feat(services): pick a global category from the service page

The service page could not say which category a service belongs to, so the
containment edges defined in settings had nothing to match against.

A Categories tab now selects one — and only selects. Creating, renaming and
deleting stay in Settings > Categories: if every page could create one,
"whole body" would exist three times with three spellings and the
includes edge would stop catching anything.

PATCH /api/v1/service-item/{uuid} carries the choice as
catalog_category_uuid. Absent field leaves the current category alone, null
clears it, and a category from another environment is refused with 422 —
the uuid arrives in the request body where TenantFilter does not reach.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
hamed
2026-08-02 13:16:53 +03:30
co-authored by Claude Opus 5
parent e08876f7b4
commit f11514950e
6 changed files with 274 additions and 0 deletions
+9
View File
@@ -20,6 +20,7 @@ import ServiceInsuranceModal from '../components/ServiceInsuranceModal';
import ServiceItemFormModal from '../components/ServiceItemFormModal';
import ServiceGroupsTab from '../components/ServiceGroupsTab';
import ServiceSegmentsTab from '../components/ServiceSegmentsTab';
import ServiceCategoryTab from '../components/ServiceCategoryTab';
interface Tariff {
uuid: string;
@@ -55,6 +56,7 @@ const TABS = [
{ id: 'insurance', label: 'بیمه‌ها' },
{ id: 'groups', label: 'گروه‌ها و آیتم‌ها' },
{ id: 'segments', label: 'بخش‌های نوبت' },
{ id: 'categories',label: 'دسته‌بندی‌ها' },
{ id: 'goods', label: 'کالاهای مرتبط' },
{ id: 'history', label: 'لاگ تغییرات' },
] as const;
@@ -543,6 +545,13 @@ function ServiceDetailPageInner() {
{tab === 'insurance' && <InsuranceTab item={item} onManage={() => setInsuranceOpen(true)} canUpdate={canUpdate} />}
{tab === 'groups' && <ServiceGroupsTab serviceUuid={item.uuid} canEdit={canUpdate} />}
{tab === 'segments' && <ServiceSegmentsTab serviceUuid={item.uuid} canEdit={canUpdate} />}
{tab === 'categories' && (
<ServiceCategoryTab
serviceUuid={item.uuid}
categoryUuid={item.catalog_category_uuid ?? null}
canEdit={canUpdate}
/>
)}
{tab === 'goods' && <GoodsTab item={item} onEdit={() => setEditOpen(true)} canUpdate={canUpdate} />}
{tab === 'history' && <HistoryTab item={item} />}