@open-mercato/core 0.6.7-develop.6758.1.697eade236 → 0.6.7-develop.6766.1.40c9011995
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/modules/api_keys/backend/api-keys/page.js +2 -1
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/api_keys/extension-points.js +16 -0
- package/dist/modules/api_keys/extension-points.js.map +7 -0
- package/dist/modules/audit_logs/components/AccessLogsTable.js +2 -1
- package/dist/modules/audit_logs/components/AccessLogsTable.js.map +2 -2
- package/dist/modules/audit_logs/components/AuditLogsActions.js +2 -1
- package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
- package/dist/modules/audit_logs/extension-points.js +14 -0
- package/dist/modules/audit_logs/extension-points.js.map +7 -0
- package/dist/modules/auth/backend/roles/page.js +2 -1
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +2 -1
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/extension-points.js +21 -0
- package/dist/modules/auth/extension-points.js.map +7 -0
- package/dist/modules/auth/frontend/login.js +2 -1
- package/dist/modules/auth/frontend/login.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/page.js +2 -1
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/events.js +13 -0
- package/dist/modules/business_rules/events.js.map +7 -0
- package/dist/modules/business_rules/extension-points.js +13 -0
- package/dist/modules/business_rules/extension-points.js.map +7 -0
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +2 -1
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +2 -1
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -1
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +3 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/events.js +1 -0
- package/dist/modules/catalog/events.js.map +2 -2
- package/dist/modules/catalog/extension-points.js +27 -0
- package/dist/modules/catalog/extension-points.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +2 -1
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +3 -2
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
- package/dist/modules/communication_channels/extension-points.js +20 -0
- package/dist/modules/communication_channels/extension-points.js.map +7 -0
- package/dist/modules/configs/backend/config/system-status/page.js +2 -1
- package/dist/modules/configs/backend/config/system-status/page.js.map +2 -2
- package/dist/modules/configs/extension-points.js +18 -0
- package/dist/modules/configs/extension-points.js.map +7 -0
- package/dist/modules/currencies/backend/currencies/page.js +2 -1
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +2 -1
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/currencies/extension-points.js +14 -0
- package/dist/modules/currencies/extension-points.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +2 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +2 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/extension-points.js +14 -0
- package/dist/modules/customer_accounts/extension-points.js.map +7 -0
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +2 -1
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +2 -1
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +5 -4
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +5 -4
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +2 -1
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js +2 -1
- package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +2 -1
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +5 -4
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/components/CustomerTodosTable.js +2 -1
- package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
- package/dist/modules/customers/extension-points.js +42 -0
- package/dist/modules/customers/extension-points.js.map +7 -0
- package/dist/modules/customers/lib/calendar/format.js +8 -4
- package/dist/modules/customers/lib/calendar/format.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +2 -1
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/extension-points.js +13 -0
- package/dist/modules/data_sync/extension-points.js.map +7 -0
- package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/directory/extension-points.js +14 -0
- package/dist/modules/directory/extension-points.js.map +7 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +5 -1
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/components/SystemEntitiesTable.js +2 -1
- package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js +2 -1
- package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
- package/dist/modules/entities/extension-points.js +21 -0
- package/dist/modules/entities/extension-points.js.map +7 -0
- package/dist/modules/integrations/backend/integrations/[id]/page.js +2 -4
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/extension-points.js +30 -0
- package/dist/modules/integrations/extension-points.js.map +7 -0
- package/dist/modules/messages/components/ComposeMessagePageClient.js +2 -1
- package/dist/modules/messages/components/ComposeMessagePageClient.js.map +2 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js +3 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +2 -1
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/extension-points.js +16 -0
- package/dist/modules/messages/extension-points.js.map +7 -0
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -2
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
- package/dist/modules/payment_gateways/extension-points.js +19 -0
- package/dist/modules/payment_gateways/extension-points.js.map +7 -0
- package/dist/modules/portal/extension-points.js +32 -0
- package/dist/modules/portal/extension-points.js.map +7 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
- package/dist/modules/query_index/components/QueryIndexesTable.js +2 -1
- package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
- package/dist/modules/query_index/events.js +20 -0
- package/dist/modules/query_index/events.js.map +7 -0
- package/dist/modules/query_index/extension-points.js +13 -0
- package/dist/modules/query_index/extension-points.js.map +7 -0
- package/dist/modules/resources/backend/resources/resource-types/page.js +2 -1
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +2 -1
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/resources/extension-points.js +14 -0
- package/dist/modules/resources/extension-points.js.map +7 -0
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +11 -3
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +2 -1
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +4 -1
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/events.js +1 -0
- package/dist/modules/sales/events.js.map +2 -2
- package/dist/modules/sales/extension-points.js +36 -0
- package/dist/modules/sales/extension-points.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js +5 -4
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +4 -3
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +3 -2
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js +3 -2
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotsListPage.js +2 -1
- package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +3 -2
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
- package/dist/modules/wms/extension-points.js +26 -0
- package/dist/modules/wms/extension-points.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/page.js +2 -1
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.js +2 -1
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +2 -1
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/events.js +1 -0
- package/dist/modules/workflows/events.js.map +2 -2
- package/dist/modules/workflows/extension-points.js +15 -0
- package/dist/modules/workflows/extension-points.js.map +7 -0
- package/package.json +7 -7
- package/src/modules/api_keys/backend/api-keys/page.tsx +2 -1
- package/src/modules/api_keys/extension-points.ts +13 -0
- package/src/modules/audit_logs/components/AccessLogsTable.tsx +2 -1
- package/src/modules/audit_logs/components/AuditLogsActions.tsx +2 -1
- package/src/modules/audit_logs/extension-points.ts +11 -0
- package/src/modules/auth/backend/roles/page.tsx +2 -1
- package/src/modules/auth/backend/users/page.tsx +2 -1
- package/src/modules/auth/extension-points.ts +18 -0
- package/src/modules/auth/frontend/login.tsx +2 -1
- package/src/modules/business_rules/backend/rules/page.tsx +2 -1
- package/src/modules/business_rules/events.ts +10 -0
- package/src/modules/business_rules/extension-points.ts +10 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +2 -1
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +2 -1
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +2 -1
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +3 -2
- package/src/modules/catalog/events.ts +1 -0
- package/src/modules/catalog/extension-points.ts +24 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +2 -1
- package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +3 -2
- package/src/modules/communication_channels/extension-points.ts +17 -0
- package/src/modules/configs/backend/config/system-status/page.tsx +2 -1
- package/src/modules/configs/extension-points.ts +15 -0
- package/src/modules/currencies/backend/currencies/page.tsx +2 -1
- package/src/modules/currencies/backend/exchange-rates/page.tsx +2 -1
- package/src/modules/currencies/extension-points.ts +11 -0
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +2 -1
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +2 -1
- package/src/modules/customer_accounts/extension-points.ts +11 -0
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +2 -1
- package/src/modules/customers/backend/customers/companies/page.tsx +2 -1
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +5 -4
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +5 -4
- package/src/modules/customers/backend/customers/deals/page.tsx +2 -1
- package/src/modules/customers/backend/customers/people/[id]/page.tsx +2 -1
- package/src/modules/customers/backend/customers/people/page.tsx +2 -1
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +5 -4
- package/src/modules/customers/components/CustomerTodosTable.tsx +2 -1
- package/src/modules/customers/extension-points.ts +40 -0
- package/src/modules/customers/lib/calendar/format.ts +10 -4
- package/src/modules/data_sync/backend/data-sync/page.tsx +2 -1
- package/src/modules/data_sync/extension-points.ts +10 -0
- package/src/modules/directory/backend/directory/organizations/page.tsx +2 -1
- package/src/modules/directory/backend/directory/tenants/page.tsx +2 -1
- package/src/modules/directory/extension-points.ts +11 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +5 -1
- package/src/modules/entities/components/SystemEntitiesTable.tsx +2 -1
- package/src/modules/entities/components/UserEntitiesTable.tsx +2 -1
- package/src/modules/entities/extension-points.ts +18 -0
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +2 -2
- package/src/modules/integrations/extension-points.ts +27 -0
- package/src/modules/messages/components/ComposeMessagePageClient.tsx +2 -1
- package/src/modules/messages/components/MessageDetailPageClient.tsx +3 -2
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +2 -1
- package/src/modules/messages/extension-points.ts +13 -0
- package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +3 -2
- package/src/modules/payment_gateways/extension-points.ts +16 -0
- package/src/modules/portal/extension-points.ts +30 -0
- package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/profile/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +4 -4
- package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +3 -3
- package/src/modules/query_index/components/QueryIndexesTable.tsx +2 -1
- package/src/modules/query_index/events.ts +17 -0
- package/src/modules/query_index/extension-points.ts +10 -0
- package/src/modules/resources/backend/resources/resource-types/page.tsx +2 -1
- package/src/modules/resources/backend/resources/resources/page.tsx +2 -1
- package/src/modules/resources/extension-points.ts +11 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +11 -3
- package/src/modules/sales/components/documents/ItemsSection.tsx +2 -1
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +6 -1
- package/src/modules/sales/events.ts +1 -0
- package/src/modules/sales/extension-points.ts +33 -0
- package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +5 -4
- package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +4 -3
- package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +3 -2
- package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +3 -2
- package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -1
- package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +3 -2
- package/src/modules/wms/extension-points.ts +23 -0
- package/src/modules/workflows/backend/definitions/page.tsx +2 -1
- package/src/modules/workflows/backend/instances/page.tsx +2 -1
- package/src/modules/workflows/backend/tasks/page.tsx +2 -1
- package/src/modules/workflows/events.ts +1 -0
- package/src/modules/workflows/extension-points.ts +12 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/workflows/backend/instances/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\ntype WorkflowInstance = {\n id: string\n definitionId: string\n workflowId: string\n version: number\n status: 'RUNNING' | 'PAUSED' | 'COMPLETED' | 'FAILED' | 'CANCELLED' | 'COMPENSATING' | 'COMPENSATED'\n currentStepId: string\n correlationKey: string | null\n startedAt: string\n completedAt: string | null\n cancelledAt: string | null\n errorMessage: string | null\n retryCount: number\n tenantId: string\n organizationId: string\n createdAt: string\n updatedAt: string\n}\n\ntype InstancesResponse = {\n data: WorkflowInstance[]\n pagination: {\n total: number\n limit: number\n offset: number\n hasMore: boolean\n }\n}\n\nexport default function WorkflowInstancesListPage() {\n const [page, setPage] = React.useState(1)\n const [pageSize] = React.useState(50)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const t = useT()\n const router = useRouter()\n const queryClient = useQueryClient()\n const { confirm: confirmDialog, ConfirmDialogElement } = useConfirmDialog()\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['workflow-instances', 'list', filterValues, page],\n queryFn: async () => {\n const params = new URLSearchParams()\n const offset = (page - 1) * pageSize\n params.set('limit', pageSize.toString())\n params.set('offset', offset.toString())\n\n if (filterValues.status) params.set('status', filterValues.status as string)\n if (filterValues.workflowId) params.set('workflowId', filterValues.workflowId as string)\n if (filterValues.correlationKey) params.set('correlationKey', filterValues.correlationKey as string)\n if (filterValues.entityType) params.set('entityType', filterValues.entityType as string)\n if (filterValues.entityId) params.set('entityId', filterValues.entityId as string)\n\n const result = await apiCall<InstancesResponse>(\n `/api/workflows/instances?${params.toString()}`\n )\n\n if (!result.ok) {\n throw new Error('Failed to fetch workflow instances')\n }\n\n const response = result.result\n if (response?.pagination) {\n setTotal(response.pagination.total || 0)\n const calculatedPages = Math.ceil((response.pagination.total || 0) / pageSize)\n setTotalPages(calculatedPages || 1)\n }\n\n return response?.data || []\n },\n })\n\n const handleCancel = async (id: string, workflowId: string) => {\n const confirmed = await confirmDialog({\n title: t('workflows.instances.confirm.cancel', { id: workflowId }),\n variant: 'destructive',\n })\n if (!confirmed) {\n return\n }\n\n const result = await apiCall(`/api/workflows/instances/${id}/cancel`, {\n method: 'POST',\n })\n\n if (result.ok) {\n flash(t('workflows.instances.messages.cancelled'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-instances'] })\n } else {\n flash(t('workflows.instances.messages.cancelFailed'), 'error')\n }\n }\n\n const handleRetry = async (id: string, workflowId: string) => {\n const ok = await confirmDialog({\n title: t('workflows.instances.confirm.retry', { id: workflowId }),\n variant: 'default',\n })\n if (!ok) {\n return\n }\n\n const result = await apiCall(`/api/workflows/instances/${id}/retry`, {\n method: 'POST',\n })\n\n if (result.ok) {\n flash(t('workflows.instances.messages.retried'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-instances'] })\n } else {\n flash(t('workflows.instances.messages.retryFailed'), 'error')\n }\n }\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = {}\n Object.entries(values).forEach(([key, value]) => {\n if (value !== undefined && value !== '') next[key] = value\n })\n setFilterValues(next)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const getStatusBadgeClass = (status: WorkflowInstance['status']) => {\n switch (status) {\n case 'RUNNING':\n return 'bg-blue-100 text-blue-800'\n case 'PAUSED':\n return 'bg-yellow-100 text-yellow-800'\n case 'COMPLETED':\n return 'bg-green-100 text-green-800'\n case 'FAILED':\n return 'bg-red-100 text-red-800'\n case 'CANCELLED':\n return 'bg-muted text-foreground'\n case 'COMPENSATING':\n return 'bg-orange-100 text-orange-800'\n case 'COMPENSATED':\n return 'bg-purple-100 text-purple-800'\n default:\n return 'bg-muted text-muted-foreground'\n }\n }\n\n const filters: FilterDef[] = [\n {\n id: 'status',\n type: 'select',\n label: t('workflows.instances.filters.status'),\n options: [\n { label: t('common.all'), value: '' },\n { label: t('workflows.instances.status.RUNNING'), value: 'RUNNING' },\n { label: t('workflows.instances.status.PAUSED'), value: 'PAUSED' },\n { label: t('workflows.instances.status.COMPLETED'), value: 'COMPLETED' },\n { label: t('workflows.instances.status.FAILED'), value: 'FAILED' },\n { label: t('workflows.instances.status.CANCELLED'), value: 'CANCELLED' },\n { label: t('workflows.instances.status.COMPENSATING'), value: 'COMPENSATING' },\n { label: t('workflows.instances.status.COMPENSATED'), value: 'COMPENSATED' },\n ],\n },\n {\n id: 'workflowId',\n type: 'text',\n label: t('workflows.instances.filters.workflowId'),\n placeholder: t('workflows.instances.filters.workflowIdPlaceholder'),\n },\n {\n id: 'correlationKey',\n type: 'text',\n label: t('workflows.instances.filters.correlationKey'),\n placeholder: t('workflows.instances.filters.correlationKeyPlaceholder'),\n },\n {\n id: 'entityType',\n type: 'text',\n label: t('workflows.instances.filters.entityType'),\n placeholder: t('workflows.instances.filters.entityTypePlaceholder'),\n },\n {\n id: 'entityId',\n type: 'text',\n label: t('workflows.instances.filters.entityId'),\n placeholder: t('workflows.instances.filters.entityIdPlaceholder'),\n },\n ]\n\n const columns: ColumnDef<WorkflowInstance>[] = [\n {\n id: 'workflowId',\n header: t('workflows.instances.fields.workflowId'),\n accessorKey: 'workflowId',\n cell: ({ row }) => (\n <Link href={`/backend/instances/${row.original.id}`} className=\"block hover:underline\">\n <div className=\"font-mono text-sm font-medium\">{row.original.workflowId}</div>\n {row.original.correlationKey && (\n <div className=\"text-xs text-muted-foreground\">\n {t('workflows.instances.fields.correlationKey')}: {row.original.correlationKey}\n </div>\n )}\n </Link>\n ),\n },\n {\n id: 'status',\n header: t('workflows.instances.fields.status'),\n accessorKey: 'status',\n cell: ({ row }) => (\n <span className={`inline-flex items-center px-2 py-1 rounded text-xs font-medium ${getStatusBadgeClass(row.original.status)}`}>\n {t(`workflows.instances.status.${row.original.status}`)}\n </span>\n ),\n },\n {\n id: 'currentStep',\n header: t('workflows.instances.fields.currentStep'),\n accessorKey: 'currentStepId',\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">{row.original.currentStepId}</span>\n ),\n },\n {\n id: 'timing',\n header: t('workflows.instances.fields.timing'),\n cell: ({ row }) => {\n const started = new Date(row.original.startedAt)\n const completed = row.original.completedAt ? new Date(row.original.completedAt) : null\n const duration = completed ? completed.getTime() - started.getTime() : Date.now() - started.getTime()\n const durationText = duration < 60000\n ? `${Math.floor(duration / 1000)}s`\n : `${Math.floor(duration / 60000)}m`\n\n return (\n <div className=\"text-sm\">\n <div className=\"text-foreground\">{started.toLocaleString()}</div>\n <div className=\"text-xs text-muted-foreground\">\n {completed ? t('workflows.instances.duration') : t('workflows.instances.elapsed')}: {durationText}\n </div>\n </div>\n )\n },\n },\n {\n id: 'retryCount',\n header: t('workflows.instances.fields.retryCount'),\n accessorKey: 'retryCount',\n cell: ({ row }) => (\n <span className={`text-sm ${row.original.retryCount > 0 ? 'text-orange-600 font-medium' : 'text-muted-foreground'}`}>\n {row.original.retryCount}\n </span>\n ),\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n const items: Array<{ id: string; label: string; href?: string; onSelect?: () => void }> = [\n {\n id: 'view',\n label: t('workflows.instances.actions.viewDetails'),\n href: `/backend/instances/${row.original.id}`,\n },\n ]\n\n if (row.original.status === 'RUNNING' || row.original.status === 'PAUSED') {\n items.push({\n id: 'cancel',\n label: t('workflows.instances.actions.cancel'),\n onSelect: () => void handleCancel(row.original.id, row.original.workflowId),\n })\n }\n\n if (row.original.status === 'FAILED') {\n items.push({\n id: 'retry',\n label: t('workflows.instances.actions.retry'),\n onSelect: () => void handleRetry(row.original.id, row.original.workflowId),\n })\n }\n\n return <RowActions items={items} />\n },\n },\n ]\n\n if (error) {\n return (\n <Page>\n <PageBody>\n <div className=\"p-8 text-center\">\n <p className=\"text-red-600\">{t('workflows.instances.messages.loadFailed')}</p>\n <Button onClick={() => queryClient.invalidateQueries({ queryKey: ['workflow-instances'] })} className=\"mt-4\">\n {t('common.retry')}\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <DataTable\n title={t('workflows.instances.list.title')}\n columns={columns}\n data={data || []}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n perspective={{\n tableId: 'workflows.instances.list',\n }}\n pagination={{ page, pageSize, total, totalPages, onPageChange: setPage }}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/workflows/extension-points'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\ntype WorkflowInstance = {\n id: string\n definitionId: string\n workflowId: string\n version: number\n status: 'RUNNING' | 'PAUSED' | 'COMPLETED' | 'FAILED' | 'CANCELLED' | 'COMPENSATING' | 'COMPENSATED'\n currentStepId: string\n correlationKey: string | null\n startedAt: string\n completedAt: string | null\n cancelledAt: string | null\n errorMessage: string | null\n retryCount: number\n tenantId: string\n organizationId: string\n createdAt: string\n updatedAt: string\n}\n\ntype InstancesResponse = {\n data: WorkflowInstance[]\n pagination: {\n total: number\n limit: number\n offset: number\n hasMore: boolean\n }\n}\n\nexport default function WorkflowInstancesListPage() {\n const [page, setPage] = React.useState(1)\n const [pageSize] = React.useState(50)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const t = useT()\n const router = useRouter()\n const queryClient = useQueryClient()\n const { confirm: confirmDialog, ConfirmDialogElement } = useConfirmDialog()\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['workflow-instances', 'list', filterValues, page],\n queryFn: async () => {\n const params = new URLSearchParams()\n const offset = (page - 1) * pageSize\n params.set('limit', pageSize.toString())\n params.set('offset', offset.toString())\n\n if (filterValues.status) params.set('status', filterValues.status as string)\n if (filterValues.workflowId) params.set('workflowId', filterValues.workflowId as string)\n if (filterValues.correlationKey) params.set('correlationKey', filterValues.correlationKey as string)\n if (filterValues.entityType) params.set('entityType', filterValues.entityType as string)\n if (filterValues.entityId) params.set('entityId', filterValues.entityId as string)\n\n const result = await apiCall<InstancesResponse>(\n `/api/workflows/instances?${params.toString()}`\n )\n\n if (!result.ok) {\n throw new Error('Failed to fetch workflow instances')\n }\n\n const response = result.result\n if (response?.pagination) {\n setTotal(response.pagination.total || 0)\n const calculatedPages = Math.ceil((response.pagination.total || 0) / pageSize)\n setTotalPages(calculatedPages || 1)\n }\n\n return response?.data || []\n },\n })\n\n const handleCancel = async (id: string, workflowId: string) => {\n const confirmed = await confirmDialog({\n title: t('workflows.instances.confirm.cancel', { id: workflowId }),\n variant: 'destructive',\n })\n if (!confirmed) {\n return\n }\n\n const result = await apiCall(`/api/workflows/instances/${id}/cancel`, {\n method: 'POST',\n })\n\n if (result.ok) {\n flash(t('workflows.instances.messages.cancelled'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-instances'] })\n } else {\n flash(t('workflows.instances.messages.cancelFailed'), 'error')\n }\n }\n\n const handleRetry = async (id: string, workflowId: string) => {\n const ok = await confirmDialog({\n title: t('workflows.instances.confirm.retry', { id: workflowId }),\n variant: 'default',\n })\n if (!ok) {\n return\n }\n\n const result = await apiCall(`/api/workflows/instances/${id}/retry`, {\n method: 'POST',\n })\n\n if (result.ok) {\n flash(t('workflows.instances.messages.retried'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-instances'] })\n } else {\n flash(t('workflows.instances.messages.retryFailed'), 'error')\n }\n }\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = {}\n Object.entries(values).forEach(([key, value]) => {\n if (value !== undefined && value !== '') next[key] = value\n })\n setFilterValues(next)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({})\n setPage(1)\n }, [])\n\n const getStatusBadgeClass = (status: WorkflowInstance['status']) => {\n switch (status) {\n case 'RUNNING':\n return 'bg-blue-100 text-blue-800'\n case 'PAUSED':\n return 'bg-yellow-100 text-yellow-800'\n case 'COMPLETED':\n return 'bg-green-100 text-green-800'\n case 'FAILED':\n return 'bg-red-100 text-red-800'\n case 'CANCELLED':\n return 'bg-muted text-foreground'\n case 'COMPENSATING':\n return 'bg-orange-100 text-orange-800'\n case 'COMPENSATED':\n return 'bg-purple-100 text-purple-800'\n default:\n return 'bg-muted text-muted-foreground'\n }\n }\n\n const filters: FilterDef[] = [\n {\n id: 'status',\n type: 'select',\n label: t('workflows.instances.filters.status'),\n options: [\n { label: t('common.all'), value: '' },\n { label: t('workflows.instances.status.RUNNING'), value: 'RUNNING' },\n { label: t('workflows.instances.status.PAUSED'), value: 'PAUSED' },\n { label: t('workflows.instances.status.COMPLETED'), value: 'COMPLETED' },\n { label: t('workflows.instances.status.FAILED'), value: 'FAILED' },\n { label: t('workflows.instances.status.CANCELLED'), value: 'CANCELLED' },\n { label: t('workflows.instances.status.COMPENSATING'), value: 'COMPENSATING' },\n { label: t('workflows.instances.status.COMPENSATED'), value: 'COMPENSATED' },\n ],\n },\n {\n id: 'workflowId',\n type: 'text',\n label: t('workflows.instances.filters.workflowId'),\n placeholder: t('workflows.instances.filters.workflowIdPlaceholder'),\n },\n {\n id: 'correlationKey',\n type: 'text',\n label: t('workflows.instances.filters.correlationKey'),\n placeholder: t('workflows.instances.filters.correlationKeyPlaceholder'),\n },\n {\n id: 'entityType',\n type: 'text',\n label: t('workflows.instances.filters.entityType'),\n placeholder: t('workflows.instances.filters.entityTypePlaceholder'),\n },\n {\n id: 'entityId',\n type: 'text',\n label: t('workflows.instances.filters.entityId'),\n placeholder: t('workflows.instances.filters.entityIdPlaceholder'),\n },\n ]\n\n const columns: ColumnDef<WorkflowInstance>[] = [\n {\n id: 'workflowId',\n header: t('workflows.instances.fields.workflowId'),\n accessorKey: 'workflowId',\n cell: ({ row }) => (\n <Link href={`/backend/instances/${row.original.id}`} className=\"block hover:underline\">\n <div className=\"font-mono text-sm font-medium\">{row.original.workflowId}</div>\n {row.original.correlationKey && (\n <div className=\"text-xs text-muted-foreground\">\n {t('workflows.instances.fields.correlationKey')}: {row.original.correlationKey}\n </div>\n )}\n </Link>\n ),\n },\n {\n id: 'status',\n header: t('workflows.instances.fields.status'),\n accessorKey: 'status',\n cell: ({ row }) => (\n <span className={`inline-flex items-center px-2 py-1 rounded text-xs font-medium ${getStatusBadgeClass(row.original.status)}`}>\n {t(`workflows.instances.status.${row.original.status}`)}\n </span>\n ),\n },\n {\n id: 'currentStep',\n header: t('workflows.instances.fields.currentStep'),\n accessorKey: 'currentStepId',\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">{row.original.currentStepId}</span>\n ),\n },\n {\n id: 'timing',\n header: t('workflows.instances.fields.timing'),\n cell: ({ row }) => {\n const started = new Date(row.original.startedAt)\n const completed = row.original.completedAt ? new Date(row.original.completedAt) : null\n const duration = completed ? completed.getTime() - started.getTime() : Date.now() - started.getTime()\n const durationText = duration < 60000\n ? `${Math.floor(duration / 1000)}s`\n : `${Math.floor(duration / 60000)}m`\n\n return (\n <div className=\"text-sm\">\n <div className=\"text-foreground\">{started.toLocaleString()}</div>\n <div className=\"text-xs text-muted-foreground\">\n {completed ? t('workflows.instances.duration') : t('workflows.instances.elapsed')}: {durationText}\n </div>\n </div>\n )\n },\n },\n {\n id: 'retryCount',\n header: t('workflows.instances.fields.retryCount'),\n accessorKey: 'retryCount',\n cell: ({ row }) => (\n <span className={`text-sm ${row.original.retryCount > 0 ? 'text-orange-600 font-medium' : 'text-muted-foreground'}`}>\n {row.original.retryCount}\n </span>\n ),\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n const items: Array<{ id: string; label: string; href?: string; onSelect?: () => void }> = [\n {\n id: 'view',\n label: t('workflows.instances.actions.viewDetails'),\n href: `/backend/instances/${row.original.id}`,\n },\n ]\n\n if (row.original.status === 'RUNNING' || row.original.status === 'PAUSED') {\n items.push({\n id: 'cancel',\n label: t('workflows.instances.actions.cancel'),\n onSelect: () => void handleCancel(row.original.id, row.original.workflowId),\n })\n }\n\n if (row.original.status === 'FAILED') {\n items.push({\n id: 'retry',\n label: t('workflows.instances.actions.retry'),\n onSelect: () => void handleRetry(row.original.id, row.original.workflowId),\n })\n }\n\n return <RowActions items={items} />\n },\n },\n ]\n\n if (error) {\n return (\n <Page>\n <PageBody>\n <div className=\"p-8 text-center\">\n <p className=\"text-red-600\">{t('workflows.instances.messages.loadFailed')}</p>\n <Button onClick={() => queryClient.invalidateQueries({ queryKey: ['workflow-instances'] })} className=\"mt-4\">\n {t('common.retry')}\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <DataTable\n title={t('workflows.instances.list.title')}\n columns={columns}\n data={data || []}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n perspective={{\n tableId: extensionPoints.hosts.instancesTable.tableId,\n }}\n pagination={{ page, pageSize, total, totalPages, onPageChange: setPage }}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { extensionPoints } from "@open-mercato/core/modules/workflows/extension-points";
|
|
4
5
|
import { useRouter } from "next/navigation";
|
|
5
6
|
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
6
7
|
import { DataTable } from "@open-mercato/ui/backend/DataTable";
|
|
@@ -244,7 +245,7 @@ function UserTasksListPage() {
|
|
|
244
245
|
onFiltersApply: handleFiltersApply,
|
|
245
246
|
onFiltersClear: handleFiltersClear,
|
|
246
247
|
perspective: {
|
|
247
|
-
tableId:
|
|
248
|
+
tableId: extensionPoints.hosts.tasksTable.tableId
|
|
248
249
|
},
|
|
249
250
|
pagination: { page, pageSize, total, totalPages, onPageChange: setPage }
|
|
250
251
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/workflows/backend/tasks/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\ntype UserTaskStatus = 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED'\n\ntype UserTask = {\n id: string\n workflowInstanceId: string\n stepInstanceId: string\n taskName: string\n description: string | null\n status: UserTaskStatus\n formSchema: any | null\n formData: any | null\n assignedTo: string | null\n assignedToRoles: string[] | null\n claimedBy: string | null\n claimedAt: string | null\n dueDate: string | null\n escalatedAt: string | null\n escalatedTo: string | null\n completedBy: string | null\n completedAt: string | null\n comments: string | null\n tenantId: string\n organizationId: string\n createdAt: string\n updatedAt: string\n}\n\ntype TasksResponse = {\n data: UserTask[]\n pagination: {\n total: number\n limit: number\n offset: number\n hasMore: boolean\n }\n}\n\nexport default function UserTasksListPage() {\n const [page, setPage] = React.useState(1)\n const [pageSize] = React.useState(50)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const t = useT()\n const router = useRouter()\n const queryClient = useQueryClient()\n const { confirm: confirmDialog, ConfirmDialogElement } = useConfirmDialog()\n const [filterValues, setFilterValues] = React.useState<FilterValues>({\n myTasks: 'true', // Default to \"My Tasks\" view\n })\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['workflow-tasks', 'list', filterValues, page],\n queryFn: async () => {\n const params = new URLSearchParams()\n const offset = (page - 1) * pageSize\n params.set('limit', pageSize.toString())\n params.set('offset', offset.toString())\n\n if (filterValues.status) params.set('status', filterValues.status as string)\n if (filterValues.overdue === 'true') params.set('overdue', 'true')\n if (filterValues.workflowInstanceId) params.set('workflowInstanceId', filterValues.workflowInstanceId as string)\n\n const result = await apiCall<TasksResponse>(\n `/api/workflows/tasks?${params.toString()}`\n )\n\n if (!result.ok) {\n throw new Error('Failed to fetch user tasks')\n }\n\n const response = result.result\n if (response?.pagination) {\n setTotal(response.pagination.total || 0)\n const calculatedPages = Math.ceil((response.pagination.total || 0) / pageSize)\n setTotalPages(calculatedPages || 1)\n }\n\n return response?.data || []\n },\n })\n\n const handleClaim = async (id: string, taskName: string) => {\n const confirmed = await confirmDialog({\n title: t('workflows.tasks.confirm.claim', { name: taskName }),\n variant: 'default',\n })\n if (!confirmed) {\n return\n }\n\n const result = await apiCall(`/api/workflows/tasks/${id}/claim`, {\n method: 'POST',\n })\n\n if (result.ok) {\n flash(t('workflows.tasks.messages.claimed'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-tasks'] })\n } else {\n flash(t('workflows.tasks.messages.claimFailed'), 'error')\n }\n }\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = {}\n Object.entries(values).forEach(([key, value]) => {\n if (value !== undefined && value !== '') next[key] = value\n })\n setFilterValues(next)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({ myTasks: 'true' })\n setPage(1)\n }, [])\n\n const getStatusBadgeClass = (status: UserTaskStatus) => {\n switch (status) {\n case 'PENDING':\n return 'bg-yellow-100 text-yellow-800'\n case 'IN_PROGRESS':\n return 'bg-blue-100 text-blue-800'\n case 'COMPLETED':\n return 'bg-green-100 text-green-800'\n case 'CANCELLED':\n return 'bg-muted text-foreground'\n default:\n return 'bg-muted text-muted-foreground'\n }\n }\n\n const isOverdue = (task: UserTask) => {\n if (!task.dueDate || task.status === 'COMPLETED' || task.status === 'CANCELLED') {\n return false\n }\n return new Date(task.dueDate) < new Date()\n }\n\n const filters: FilterDef[] = [\n {\n id: 'status',\n type: 'select',\n label: t('workflows.tasks.filters.status'),\n options: [\n { label: t('common.all'), value: '' },\n { label: t('workflows.tasks.statuses.PENDING'), value: 'PENDING' },\n { label: t('workflows.tasks.statuses.IN_PROGRESS'), value: 'IN_PROGRESS' },\n { label: t('workflows.tasks.statuses.COMPLETED'), value: 'COMPLETED' },\n { label: t('workflows.tasks.statuses.CANCELLED'), value: 'CANCELLED' },\n ],\n },\n {\n id: 'myTasks',\n type: 'select',\n label: t('workflows.tasks.filters.view'),\n options: [\n { label: t('workflows.tasks.filters.myTasks'), value: 'true' },\n { label: t('workflows.tasks.filters.allTasks'), value: '' },\n ],\n },\n {\n id: 'overdue',\n type: 'select',\n label: t('workflows.tasks.filters.overdue'),\n options: [\n { label: t('common.all'), value: '' },\n { label: t('workflows.tasks.filters.overdueOnly'), value: 'true' },\n ],\n },\n {\n id: 'workflowInstanceId',\n type: 'text',\n label: t('workflows.tasks.filters.workflowInstanceId'),\n placeholder: t('workflows.tasks.filters.workflowInstanceIdPlaceholder'),\n },\n ]\n\n const columns: ColumnDef<UserTask>[] = [\n {\n id: 'taskName',\n header: t('workflows.tasks.fields.taskName'),\n accessorKey: 'taskName',\n cell: ({ row }) => (\n <div>\n <div className=\"font-medium text-sm\">{row.original.taskName}</div>\n {row.original.description && (\n <div className=\"text-xs text-muted-foreground line-clamp-1\">\n {row.original.description}\n </div>\n )}\n {isOverdue(row.original) && (\n <div className=\"text-xs text-red-600 font-medium mt-1\">\n {t('workflows.tasks.overdue')}\n </div>\n )}\n </div>\n ),\n },\n {\n id: 'status',\n header: t('workflows.tasks.fields.status'),\n accessorKey: 'status',\n cell: ({ row }) => (\n <span className={`inline-flex items-center px-2 py-1 rounded text-xs font-medium ${getStatusBadgeClass(row.original.status)}`}>\n {t(`workflows.tasks.statuses.${row.original.status}`)}\n </span>\n ),\n },\n {\n id: 'assignment',\n header: t('workflows.tasks.fields.assignment'),\n cell: ({ row }) => {\n if (row.original.claimedBy) {\n return (\n <div className=\"text-sm\">\n <div className=\"text-foreground\">{t('workflows.tasks.claimedBy')}: {row.original.claimedBy}</div>\n </div>\n )\n }\n if (row.original.assignedTo) {\n return <div className=\"text-sm text-foreground\">{row.original.assignedTo}</div>\n }\n if (row.original.assignedToRoles && row.original.assignedToRoles.length > 0) {\n return (\n <div className=\"text-sm text-muted-foreground\">\n {t('workflows.tasks.roles')}: {row.original.assignedToRoles.join(', ')}\n </div>\n )\n }\n return <span className=\"text-sm text-muted-foreground\">-</span>\n },\n },\n {\n id: 'dueDate',\n header: t('workflows.tasks.fields.dueDate'),\n accessorKey: 'dueDate',\n cell: ({ row }) => {\n if (!row.original.dueDate) {\n return <span className=\"text-sm text-muted-foreground\">-</span>\n }\n const dueDate = new Date(row.original.dueDate)\n const overdue = isOverdue(row.original)\n return (\n <div className={`text-sm ${overdue ? 'text-red-600 font-medium' : 'text-foreground'}`}>\n {dueDate.toLocaleString()}\n </div>\n )\n },\n },\n {\n id: 'createdAt',\n header: t('workflows.tasks.fields.createdAt'),\n accessorKey: 'createdAt',\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {new Date(row.original.createdAt).toLocaleString()}\n </span>\n ),\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n const items: Array<{ id: string; label: string; href?: string; onSelect?: () => void }> = [\n {\n id: 'view',\n label: t('workflows.tasks.actions.viewDetails'),\n href: `/backend/tasks/${row.original.id}`,\n },\n ]\n\n // Allow claiming if task is PENDING and assigned to roles (not specific user)\n if (\n row.original.status === 'PENDING' &&\n !row.original.assignedTo &&\n row.original.assignedToRoles &&\n row.original.assignedToRoles.length > 0\n ) {\n items.push({\n id: 'claim',\n label: t('workflows.tasks.actions.claim'),\n onSelect: () => void handleClaim(row.original.id, row.original.taskName),\n })\n }\n\n // Allow completing if task is in progress or pending\n if (row.original.status === 'PENDING' || row.original.status === 'IN_PROGRESS') {\n items.push({\n id: 'complete',\n label: t('workflows.tasks.actions.complete'),\n href: `/backend/tasks/${row.original.id}`,\n })\n }\n\n return <RowActions items={items} />\n },\n },\n ]\n\n if (error) {\n return (\n <Page>\n <PageBody>\n <div className=\"p-8 text-center\">\n <p className=\"text-red-600\">{t('workflows.tasks.messages.loadFailed')}</p>\n <Button onClick={() => queryClient.invalidateQueries({ queryKey: ['workflow-tasks'] })} className=\"mt-4\">\n {t('common.retry')}\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <DataTable\n title={t('workflows.tasks.list.title')}\n columns={columns}\n data={data || []}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n perspective={{\n tableId: 'workflows.tasks.list',\n }}\n pagination={{ page, pageSize, total, totalPages, onPageChange: setPage }}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/workflows/extension-points'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\ntype UserTaskStatus = 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED'\n\ntype UserTask = {\n id: string\n workflowInstanceId: string\n stepInstanceId: string\n taskName: string\n description: string | null\n status: UserTaskStatus\n formSchema: any | null\n formData: any | null\n assignedTo: string | null\n assignedToRoles: string[] | null\n claimedBy: string | null\n claimedAt: string | null\n dueDate: string | null\n escalatedAt: string | null\n escalatedTo: string | null\n completedBy: string | null\n completedAt: string | null\n comments: string | null\n tenantId: string\n organizationId: string\n createdAt: string\n updatedAt: string\n}\n\ntype TasksResponse = {\n data: UserTask[]\n pagination: {\n total: number\n limit: number\n offset: number\n hasMore: boolean\n }\n}\n\nexport default function UserTasksListPage() {\n const [page, setPage] = React.useState(1)\n const [pageSize] = React.useState(50)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const t = useT()\n const router = useRouter()\n const queryClient = useQueryClient()\n const { confirm: confirmDialog, ConfirmDialogElement } = useConfirmDialog()\n const [filterValues, setFilterValues] = React.useState<FilterValues>({\n myTasks: 'true', // Default to \"My Tasks\" view\n })\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['workflow-tasks', 'list', filterValues, page],\n queryFn: async () => {\n const params = new URLSearchParams()\n const offset = (page - 1) * pageSize\n params.set('limit', pageSize.toString())\n params.set('offset', offset.toString())\n\n if (filterValues.status) params.set('status', filterValues.status as string)\n if (filterValues.overdue === 'true') params.set('overdue', 'true')\n if (filterValues.workflowInstanceId) params.set('workflowInstanceId', filterValues.workflowInstanceId as string)\n\n const result = await apiCall<TasksResponse>(\n `/api/workflows/tasks?${params.toString()}`\n )\n\n if (!result.ok) {\n throw new Error('Failed to fetch user tasks')\n }\n\n const response = result.result\n if (response?.pagination) {\n setTotal(response.pagination.total || 0)\n const calculatedPages = Math.ceil((response.pagination.total || 0) / pageSize)\n setTotalPages(calculatedPages || 1)\n }\n\n return response?.data || []\n },\n })\n\n const handleClaim = async (id: string, taskName: string) => {\n const confirmed = await confirmDialog({\n title: t('workflows.tasks.confirm.claim', { name: taskName }),\n variant: 'default',\n })\n if (!confirmed) {\n return\n }\n\n const result = await apiCall(`/api/workflows/tasks/${id}/claim`, {\n method: 'POST',\n })\n\n if (result.ok) {\n flash(t('workflows.tasks.messages.claimed'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-tasks'] })\n } else {\n flash(t('workflows.tasks.messages.claimFailed'), 'error')\n }\n }\n\n const handleFiltersApply = React.useCallback((values: FilterValues) => {\n const next: FilterValues = {}\n Object.entries(values).forEach(([key, value]) => {\n if (value !== undefined && value !== '') next[key] = value\n })\n setFilterValues(next)\n setPage(1)\n }, [])\n\n const handleFiltersClear = React.useCallback(() => {\n setFilterValues({ myTasks: 'true' })\n setPage(1)\n }, [])\n\n const getStatusBadgeClass = (status: UserTaskStatus) => {\n switch (status) {\n case 'PENDING':\n return 'bg-yellow-100 text-yellow-800'\n case 'IN_PROGRESS':\n return 'bg-blue-100 text-blue-800'\n case 'COMPLETED':\n return 'bg-green-100 text-green-800'\n case 'CANCELLED':\n return 'bg-muted text-foreground'\n default:\n return 'bg-muted text-muted-foreground'\n }\n }\n\n const isOverdue = (task: UserTask) => {\n if (!task.dueDate || task.status === 'COMPLETED' || task.status === 'CANCELLED') {\n return false\n }\n return new Date(task.dueDate) < new Date()\n }\n\n const filters: FilterDef[] = [\n {\n id: 'status',\n type: 'select',\n label: t('workflows.tasks.filters.status'),\n options: [\n { label: t('common.all'), value: '' },\n { label: t('workflows.tasks.statuses.PENDING'), value: 'PENDING' },\n { label: t('workflows.tasks.statuses.IN_PROGRESS'), value: 'IN_PROGRESS' },\n { label: t('workflows.tasks.statuses.COMPLETED'), value: 'COMPLETED' },\n { label: t('workflows.tasks.statuses.CANCELLED'), value: 'CANCELLED' },\n ],\n },\n {\n id: 'myTasks',\n type: 'select',\n label: t('workflows.tasks.filters.view'),\n options: [\n { label: t('workflows.tasks.filters.myTasks'), value: 'true' },\n { label: t('workflows.tasks.filters.allTasks'), value: '' },\n ],\n },\n {\n id: 'overdue',\n type: 'select',\n label: t('workflows.tasks.filters.overdue'),\n options: [\n { label: t('common.all'), value: '' },\n { label: t('workflows.tasks.filters.overdueOnly'), value: 'true' },\n ],\n },\n {\n id: 'workflowInstanceId',\n type: 'text',\n label: t('workflows.tasks.filters.workflowInstanceId'),\n placeholder: t('workflows.tasks.filters.workflowInstanceIdPlaceholder'),\n },\n ]\n\n const columns: ColumnDef<UserTask>[] = [\n {\n id: 'taskName',\n header: t('workflows.tasks.fields.taskName'),\n accessorKey: 'taskName',\n cell: ({ row }) => (\n <div>\n <div className=\"font-medium text-sm\">{row.original.taskName}</div>\n {row.original.description && (\n <div className=\"text-xs text-muted-foreground line-clamp-1\">\n {row.original.description}\n </div>\n )}\n {isOverdue(row.original) && (\n <div className=\"text-xs text-red-600 font-medium mt-1\">\n {t('workflows.tasks.overdue')}\n </div>\n )}\n </div>\n ),\n },\n {\n id: 'status',\n header: t('workflows.tasks.fields.status'),\n accessorKey: 'status',\n cell: ({ row }) => (\n <span className={`inline-flex items-center px-2 py-1 rounded text-xs font-medium ${getStatusBadgeClass(row.original.status)}`}>\n {t(`workflows.tasks.statuses.${row.original.status}`)}\n </span>\n ),\n },\n {\n id: 'assignment',\n header: t('workflows.tasks.fields.assignment'),\n cell: ({ row }) => {\n if (row.original.claimedBy) {\n return (\n <div className=\"text-sm\">\n <div className=\"text-foreground\">{t('workflows.tasks.claimedBy')}: {row.original.claimedBy}</div>\n </div>\n )\n }\n if (row.original.assignedTo) {\n return <div className=\"text-sm text-foreground\">{row.original.assignedTo}</div>\n }\n if (row.original.assignedToRoles && row.original.assignedToRoles.length > 0) {\n return (\n <div className=\"text-sm text-muted-foreground\">\n {t('workflows.tasks.roles')}: {row.original.assignedToRoles.join(', ')}\n </div>\n )\n }\n return <span className=\"text-sm text-muted-foreground\">-</span>\n },\n },\n {\n id: 'dueDate',\n header: t('workflows.tasks.fields.dueDate'),\n accessorKey: 'dueDate',\n cell: ({ row }) => {\n if (!row.original.dueDate) {\n return <span className=\"text-sm text-muted-foreground\">-</span>\n }\n const dueDate = new Date(row.original.dueDate)\n const overdue = isOverdue(row.original)\n return (\n <div className={`text-sm ${overdue ? 'text-red-600 font-medium' : 'text-foreground'}`}>\n {dueDate.toLocaleString()}\n </div>\n )\n },\n },\n {\n id: 'createdAt',\n header: t('workflows.tasks.fields.createdAt'),\n accessorKey: 'createdAt',\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {new Date(row.original.createdAt).toLocaleString()}\n </span>\n ),\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n const items: Array<{ id: string; label: string; href?: string; onSelect?: () => void }> = [\n {\n id: 'view',\n label: t('workflows.tasks.actions.viewDetails'),\n href: `/backend/tasks/${row.original.id}`,\n },\n ]\n\n // Allow claiming if task is PENDING and assigned to roles (not specific user)\n if (\n row.original.status === 'PENDING' &&\n !row.original.assignedTo &&\n row.original.assignedToRoles &&\n row.original.assignedToRoles.length > 0\n ) {\n items.push({\n id: 'claim',\n label: t('workflows.tasks.actions.claim'),\n onSelect: () => void handleClaim(row.original.id, row.original.taskName),\n })\n }\n\n // Allow completing if task is in progress or pending\n if (row.original.status === 'PENDING' || row.original.status === 'IN_PROGRESS') {\n items.push({\n id: 'complete',\n label: t('workflows.tasks.actions.complete'),\n href: `/backend/tasks/${row.original.id}`,\n })\n }\n\n return <RowActions items={items} />\n },\n },\n ]\n\n if (error) {\n return (\n <Page>\n <PageBody>\n <div className=\"p-8 text-center\">\n <p className=\"text-red-600\">{t('workflows.tasks.messages.loadFailed')}</p>\n <Button onClick={() => queryClient.invalidateQueries({ queryKey: ['workflow-tasks'] })} className=\"mt-4\">\n {t('common.retry')}\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <DataTable\n title={t('workflows.tasks.list.title')}\n columns={columns}\n data={data || []}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={handleFiltersApply}\n onFiltersClear={handleFiltersClear}\n perspective={{\n tableId: extensionPoints.hosts.tasksTable.tableId,\n }}\n pagination={{ page, pageSize, total, totalPages, onPageChange: setPage }}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -21,6 +21,7 @@ const events = [
|
|
|
21
21
|
{ id: "workflows.activity.started", label: "Activity Started", category: "lifecycle" },
|
|
22
22
|
{ id: "workflows.activity.completed", label: "Activity Completed", category: "lifecycle" },
|
|
23
23
|
{ id: "workflows.activity.failed", label: "Activity Failed", category: "lifecycle" },
|
|
24
|
+
{ id: "workflows.task.assigned", label: "Task Assigned", entity: "task", category: "lifecycle" },
|
|
24
25
|
// Event Triggers
|
|
25
26
|
{ id: "workflows.trigger.created", label: "Trigger Created", entity: "trigger", category: "crud" },
|
|
26
27
|
{ id: "workflows.trigger.updated", label: "Trigger Updated", entity: "trigger", category: "crud" },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/modules/workflows/events.ts"],
|
|
4
|
-
"sourcesContent": ["import { createModuleEvents } from '@open-mercato/shared/modules/events'\n\n/**\n * Workflows Module Events\n *\n * Declares all events that can be emitted by the workflows module.\n */\nconst events = [\n // Workflow Definitions\n { id: 'workflows.definition.created', label: 'Workflow Definition Created', entity: 'definition', category: 'crud' },\n { id: 'workflows.definition.updated', label: 'Workflow Definition Updated', entity: 'definition', category: 'crud' },\n { id: 'workflows.definition.deleted', label: 'Workflow Definition Deleted', entity: 'definition', category: 'crud' },\n { id: 'workflows.definition.customized', label: 'Workflow Definition Customized', entity: 'definition', category: 'lifecycle' },\n { id: 'workflows.definition.reset_to_code', label: 'Workflow Definition Reset to Code', entity: 'definition', category: 'lifecycle' },\n\n // Workflow Instances\n { id: 'workflows.instance.created', label: 'Workflow Instance Created', entity: 'instance', category: 'crud' },\n { id: 'workflows.instance.updated', label: 'Workflow Instance Updated', entity: 'instance', category: 'crud' },\n { id: 'workflows.instance.deleted', label: 'Workflow Instance Deleted', entity: 'instance', category: 'crud' },\n\n // Workflow Lifecycle Events\n { id: 'workflows.instance.started', label: 'Workflow Started', category: 'lifecycle' },\n { id: 'workflows.instance.completed', label: 'Workflow Completed', category: 'lifecycle' },\n { id: 'workflows.instance.failed', label: 'Workflow Failed', category: 'lifecycle' },\n { id: 'workflows.instance.cancelled', label: 'Workflow Cancelled', category: 'lifecycle' },\n { id: 'workflows.instance.paused', label: 'Workflow Paused', category: 'lifecycle' },\n { id: 'workflows.instance.resumed', label: 'Workflow Resumed', category: 'lifecycle' },\n\n // Activity Events\n { id: 'workflows.activity.started', label: 'Activity Started', category: 'lifecycle' },\n { id: 'workflows.activity.completed', label: 'Activity Completed', category: 'lifecycle' },\n { id: 'workflows.activity.failed', label: 'Activity Failed', category: 'lifecycle' },\n\n // Event Triggers\n { id: 'workflows.trigger.created', label: 'Trigger Created', entity: 'trigger', category: 'crud' },\n { id: 'workflows.trigger.updated', label: 'Trigger Updated', entity: 'trigger', category: 'crud' },\n { id: 'workflows.trigger.deleted', label: 'Trigger Deleted', entity: 'trigger', category: 'crud' },\n\n // Parallel Fork / Join (branch lifecycle)\n { id: 'workflows.branch.opened', label: 'Parallel Branch Opened', entity: 'branch', category: 'lifecycle' },\n { id: 'workflows.branch.completed', label: 'Parallel Branch Completed', entity: 'branch', category: 'lifecycle' },\n { id: 'workflows.branch.cancelled', label: 'Parallel Branch Cancelled', entity: 'branch', category: 'lifecycle' },\n { id: 'workflows.branch.failed', label: 'Parallel Branch Failed', entity: 'branch', category: 'lifecycle' },\n { id: 'workflows.join.completed', label: 'Parallel Join Completed', entity: 'branch', category: 'lifecycle' },\n] as const\n\nexport const eventsConfig = createModuleEvents({\n moduleId: 'workflows',\n events,\n})\n\n/** Type-safe event emitter for workflows module */\nexport const emitWorkflowsEvent = eventsConfig.emit\n\n/** Event IDs that can be emitted by the workflows module */\nexport type WorkflowsEventId = typeof events[number]['id']\n\nexport default eventsConfig\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,0BAA0B;AAOnC,MAAM,SAAS;AAAA;AAAA,EAEb,EAAE,IAAI,gCAAgC,OAAO,+BAA+B,QAAQ,cAAc,UAAU,OAAO;AAAA,EACnH,EAAE,IAAI,gCAAgC,OAAO,+BAA+B,QAAQ,cAAc,UAAU,OAAO;AAAA,EACnH,EAAE,IAAI,gCAAgC,OAAO,+BAA+B,QAAQ,cAAc,UAAU,OAAO;AAAA,EACnH,EAAE,IAAI,mCAAmC,OAAO,kCAAkC,QAAQ,cAAc,UAAU,YAAY;AAAA,EAC9H,EAAE,IAAI,sCAAsC,OAAO,qCAAqC,QAAQ,cAAc,UAAU,YAAY;AAAA;AAAA,EAGpI,EAAE,IAAI,8BAA8B,OAAO,6BAA6B,QAAQ,YAAY,UAAU,OAAO;AAAA,EAC7G,EAAE,IAAI,8BAA8B,OAAO,6BAA6B,QAAQ,YAAY,UAAU,OAAO;AAAA,EAC7G,EAAE,IAAI,8BAA8B,OAAO,6BAA6B,QAAQ,YAAY,UAAU,OAAO;AAAA;AAAA,EAG7G,EAAE,IAAI,8BAA8B,OAAO,oBAAoB,UAAU,YAAY;AAAA,EACrF,EAAE,IAAI,gCAAgC,OAAO,sBAAsB,UAAU,YAAY;AAAA,EACzF,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,UAAU,YAAY;AAAA,EACnF,EAAE,IAAI,gCAAgC,OAAO,sBAAsB,UAAU,YAAY;AAAA,EACzF,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,UAAU,YAAY;AAAA,EACnF,EAAE,IAAI,8BAA8B,OAAO,oBAAoB,UAAU,YAAY;AAAA;AAAA,EAGrF,EAAE,IAAI,8BAA8B,OAAO,oBAAoB,UAAU,YAAY;AAAA,EACrF,EAAE,IAAI,gCAAgC,OAAO,sBAAsB,UAAU,YAAY;AAAA,EACzF,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,UAAU,YAAY;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { createModuleEvents } from '@open-mercato/shared/modules/events'\n\n/**\n * Workflows Module Events\n *\n * Declares all events that can be emitted by the workflows module.\n */\nconst events = [\n // Workflow Definitions\n { id: 'workflows.definition.created', label: 'Workflow Definition Created', entity: 'definition', category: 'crud' },\n { id: 'workflows.definition.updated', label: 'Workflow Definition Updated', entity: 'definition', category: 'crud' },\n { id: 'workflows.definition.deleted', label: 'Workflow Definition Deleted', entity: 'definition', category: 'crud' },\n { id: 'workflows.definition.customized', label: 'Workflow Definition Customized', entity: 'definition', category: 'lifecycle' },\n { id: 'workflows.definition.reset_to_code', label: 'Workflow Definition Reset to Code', entity: 'definition', category: 'lifecycle' },\n\n // Workflow Instances\n { id: 'workflows.instance.created', label: 'Workflow Instance Created', entity: 'instance', category: 'crud' },\n { id: 'workflows.instance.updated', label: 'Workflow Instance Updated', entity: 'instance', category: 'crud' },\n { id: 'workflows.instance.deleted', label: 'Workflow Instance Deleted', entity: 'instance', category: 'crud' },\n\n // Workflow Lifecycle Events\n { id: 'workflows.instance.started', label: 'Workflow Started', category: 'lifecycle' },\n { id: 'workflows.instance.completed', label: 'Workflow Completed', category: 'lifecycle' },\n { id: 'workflows.instance.failed', label: 'Workflow Failed', category: 'lifecycle' },\n { id: 'workflows.instance.cancelled', label: 'Workflow Cancelled', category: 'lifecycle' },\n { id: 'workflows.instance.paused', label: 'Workflow Paused', category: 'lifecycle' },\n { id: 'workflows.instance.resumed', label: 'Workflow Resumed', category: 'lifecycle' },\n\n // Activity Events\n { id: 'workflows.activity.started', label: 'Activity Started', category: 'lifecycle' },\n { id: 'workflows.activity.completed', label: 'Activity Completed', category: 'lifecycle' },\n { id: 'workflows.activity.failed', label: 'Activity Failed', category: 'lifecycle' },\n { id: 'workflows.task.assigned', label: 'Task Assigned', entity: 'task', category: 'lifecycle' },\n\n // Event Triggers\n { id: 'workflows.trigger.created', label: 'Trigger Created', entity: 'trigger', category: 'crud' },\n { id: 'workflows.trigger.updated', label: 'Trigger Updated', entity: 'trigger', category: 'crud' },\n { id: 'workflows.trigger.deleted', label: 'Trigger Deleted', entity: 'trigger', category: 'crud' },\n\n // Parallel Fork / Join (branch lifecycle)\n { id: 'workflows.branch.opened', label: 'Parallel Branch Opened', entity: 'branch', category: 'lifecycle' },\n { id: 'workflows.branch.completed', label: 'Parallel Branch Completed', entity: 'branch', category: 'lifecycle' },\n { id: 'workflows.branch.cancelled', label: 'Parallel Branch Cancelled', entity: 'branch', category: 'lifecycle' },\n { id: 'workflows.branch.failed', label: 'Parallel Branch Failed', entity: 'branch', category: 'lifecycle' },\n { id: 'workflows.join.completed', label: 'Parallel Join Completed', entity: 'branch', category: 'lifecycle' },\n] as const\n\nexport const eventsConfig = createModuleEvents({\n moduleId: 'workflows',\n events,\n})\n\n/** Type-safe event emitter for workflows module */\nexport const emitWorkflowsEvent = eventsConfig.emit\n\n/** Event IDs that can be emitted by the workflows module */\nexport type WorkflowsEventId = typeof events[number]['id']\n\nexport default eventsConfig\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,0BAA0B;AAOnC,MAAM,SAAS;AAAA;AAAA,EAEb,EAAE,IAAI,gCAAgC,OAAO,+BAA+B,QAAQ,cAAc,UAAU,OAAO;AAAA,EACnH,EAAE,IAAI,gCAAgC,OAAO,+BAA+B,QAAQ,cAAc,UAAU,OAAO;AAAA,EACnH,EAAE,IAAI,gCAAgC,OAAO,+BAA+B,QAAQ,cAAc,UAAU,OAAO;AAAA,EACnH,EAAE,IAAI,mCAAmC,OAAO,kCAAkC,QAAQ,cAAc,UAAU,YAAY;AAAA,EAC9H,EAAE,IAAI,sCAAsC,OAAO,qCAAqC,QAAQ,cAAc,UAAU,YAAY;AAAA;AAAA,EAGpI,EAAE,IAAI,8BAA8B,OAAO,6BAA6B,QAAQ,YAAY,UAAU,OAAO;AAAA,EAC7G,EAAE,IAAI,8BAA8B,OAAO,6BAA6B,QAAQ,YAAY,UAAU,OAAO;AAAA,EAC7G,EAAE,IAAI,8BAA8B,OAAO,6BAA6B,QAAQ,YAAY,UAAU,OAAO;AAAA;AAAA,EAG7G,EAAE,IAAI,8BAA8B,OAAO,oBAAoB,UAAU,YAAY;AAAA,EACrF,EAAE,IAAI,gCAAgC,OAAO,sBAAsB,UAAU,YAAY;AAAA,EACzF,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,UAAU,YAAY;AAAA,EACnF,EAAE,IAAI,gCAAgC,OAAO,sBAAsB,UAAU,YAAY;AAAA,EACzF,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,UAAU,YAAY;AAAA,EACnF,EAAE,IAAI,8BAA8B,OAAO,oBAAoB,UAAU,YAAY;AAAA;AAAA,EAGrF,EAAE,IAAI,8BAA8B,OAAO,oBAAoB,UAAU,YAAY;AAAA,EACrF,EAAE,IAAI,gCAAgC,OAAO,sBAAsB,UAAU,YAAY;AAAA,EACzF,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,UAAU,YAAY;AAAA,EACnF,EAAE,IAAI,2BAA2B,OAAO,iBAAiB,QAAQ,QAAQ,UAAU,YAAY;AAAA;AAAA,EAG/F,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,QAAQ,WAAW,UAAU,OAAO;AAAA,EACjG,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,QAAQ,WAAW,UAAU,OAAO;AAAA,EACjG,EAAE,IAAI,6BAA6B,OAAO,mBAAmB,QAAQ,WAAW,UAAU,OAAO;AAAA;AAAA,EAGjG,EAAE,IAAI,2BAA2B,OAAO,0BAA0B,QAAQ,UAAU,UAAU,YAAY;AAAA,EAC1G,EAAE,IAAI,8BAA8B,OAAO,6BAA6B,QAAQ,UAAU,UAAU,YAAY;AAAA,EAChH,EAAE,IAAI,8BAA8B,OAAO,6BAA6B,QAAQ,UAAU,UAAU,YAAY;AAAA,EAChH,EAAE,IAAI,2BAA2B,OAAO,0BAA0B,QAAQ,UAAU,UAAU,YAAY;AAAA,EAC1G,EAAE,IAAI,4BAA4B,OAAO,2BAA2B,QAAQ,UAAU,UAAU,YAAY;AAC9G;AAEO,MAAM,eAAe,mBAAmB;AAAA,EAC7C,UAAU;AAAA,EACV;AACF,CAAC;AAGM,MAAM,qBAAqB,aAAa;AAK/C,IAAO,iBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { dataTableExtensionHost, defineModuleExtensionPoints } from "@open-mercato/shared/modules/widgets/extension-points";
|
|
2
|
+
const extensionPoints = defineModuleExtensionPoints({
|
|
3
|
+
moduleId: "workflows",
|
|
4
|
+
hosts: {
|
|
5
|
+
definitionsTable: dataTableExtensionHost({ tableId: "workflows.definitions.list", source: "backend/definitions/page.tsx" }),
|
|
6
|
+
instancesTable: dataTableExtensionHost({ tableId: "workflows.instances.list", source: "backend/instances/page.tsx" }),
|
|
7
|
+
tasksTable: dataTableExtensionHost({ tableId: "workflows.tasks.list", source: "backend/tasks/page.tsx" })
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
var extension_points_default = extensionPoints;
|
|
11
|
+
export {
|
|
12
|
+
extension_points_default as default,
|
|
13
|
+
extensionPoints
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=extension-points.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/workflows/extension-points.ts"],
|
|
4
|
+
"sourcesContent": ["import { dataTableExtensionHost, defineModuleExtensionPoints } from '@open-mercato/shared/modules/widgets/extension-points'\n\nexport const extensionPoints = defineModuleExtensionPoints({\n moduleId: 'workflows',\n hosts: {\n definitionsTable: dataTableExtensionHost({ tableId: 'workflows.definitions.list', source: 'backend/definitions/page.tsx' }),\n instancesTable: dataTableExtensionHost({ tableId: 'workflows.instances.list', source: 'backend/instances/page.tsx' }),\n tasksTable: dataTableExtensionHost({ tableId: 'workflows.tasks.list', source: 'backend/tasks/page.tsx' }),\n },\n})\n\nexport default extensionPoints\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,wBAAwB,mCAAmC;AAE7D,MAAM,kBAAkB,4BAA4B;AAAA,EACzD,UAAU;AAAA,EACV,OAAO;AAAA,IACL,kBAAkB,uBAAuB,EAAE,SAAS,8BAA8B,QAAQ,+BAA+B,CAAC;AAAA,IAC1H,gBAAgB,uBAAuB,EAAE,SAAS,4BAA4B,QAAQ,6BAA6B,CAAC;AAAA,IACpH,YAAY,uBAAuB,EAAE,SAAS,wBAAwB,QAAQ,yBAAyB,CAAC;AAAA,EAC1G;AACF,CAAC;AAED,IAAO,2BAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.6.7-develop.
|
|
3
|
+
"version": "0.6.7-develop.6766.1.40c9011995",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -254,16 +254,16 @@
|
|
|
254
254
|
"zod": "^4.4.3"
|
|
255
255
|
},
|
|
256
256
|
"peerDependencies": {
|
|
257
|
-
"@open-mercato/ai-assistant": "0.6.7-develop.
|
|
258
|
-
"@open-mercato/shared": "0.6.7-develop.
|
|
259
|
-
"@open-mercato/ui": "0.6.7-develop.
|
|
257
|
+
"@open-mercato/ai-assistant": "0.6.7-develop.6766.1.40c9011995",
|
|
258
|
+
"@open-mercato/shared": "0.6.7-develop.6766.1.40c9011995",
|
|
259
|
+
"@open-mercato/ui": "0.6.7-develop.6766.1.40c9011995",
|
|
260
260
|
"react": "^19.0.0",
|
|
261
261
|
"react-dom": "^19.0.0"
|
|
262
262
|
},
|
|
263
263
|
"devDependencies": {
|
|
264
|
-
"@open-mercato/ai-assistant": "0.6.7-develop.
|
|
265
|
-
"@open-mercato/shared": "0.6.7-develop.
|
|
266
|
-
"@open-mercato/ui": "0.6.7-develop.
|
|
264
|
+
"@open-mercato/ai-assistant": "0.6.7-develop.6766.1.40c9011995",
|
|
265
|
+
"@open-mercato/shared": "0.6.7-develop.6766.1.40c9011995",
|
|
266
|
+
"@open-mercato/ui": "0.6.7-develop.6766.1.40c9011995",
|
|
267
267
|
"@testing-library/dom": "^10.4.1",
|
|
268
268
|
"@testing-library/jest-dom": "^6.9.1",
|
|
269
269
|
"@testing-library/react": "^16.3.1",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import * as React from 'react'
|
|
3
|
+
import { extensionPoints } from '@open-mercato/core/modules/api_keys/extension-points'
|
|
3
4
|
import Link from 'next/link'
|
|
4
5
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
5
6
|
import { DataTable } from '@open-mercato/ui/backend/DataTable'
|
|
@@ -184,7 +185,7 @@ export default function ApiKeysListPage() {
|
|
|
184
185
|
data={rows}
|
|
185
186
|
searchValue={search}
|
|
186
187
|
onSearchChange={(value) => { setSearch(value); setPage(1) }}
|
|
187
|
-
perspective={{ tableId:
|
|
188
|
+
perspective={{ tableId: extensionPoints.hosts.apiKeysTable.tableId }}
|
|
188
189
|
rowActions={(row) => (
|
|
189
190
|
<RowActions items={[
|
|
190
191
|
{ id: 'delete', label: t('common.delete'), destructive: true, onSelect: () => { void handleDelete(row) } },
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { dataTableExtensionHost, defineModuleExtensionPoints } from '@open-mercato/shared/modules/widgets/extension-points'
|
|
2
|
+
|
|
3
|
+
export const extensionPoints = defineModuleExtensionPoints({
|
|
4
|
+
moduleId: 'api_keys',
|
|
5
|
+
hosts: {
|
|
6
|
+
apiKeysTable: dataTableExtensionHost({
|
|
7
|
+
tableId: 'api_keys.list',
|
|
8
|
+
source: 'backend/api-keys/page.tsx',
|
|
9
|
+
}),
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
export default extensionPoints
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
|
+
import { extensionPoints } from '@open-mercato/core/modules/audit_logs/extension-points'
|
|
4
5
|
import type { ColumnDef } from '@tanstack/react-table'
|
|
5
6
|
import { DataTable, type PaginationProps } from '@open-mercato/ui/backend/DataTable'
|
|
6
7
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
@@ -74,7 +75,7 @@ export function AccessLogsTable({ items, isLoading, actions, pagination }: { ite
|
|
|
74
75
|
title={t('audit_logs.access.title')}
|
|
75
76
|
data={accessItems}
|
|
76
77
|
columns={columns}
|
|
77
|
-
perspective={{ tableId:
|
|
78
|
+
perspective={{ tableId: extensionPoints.hosts.accessLogsTable.tableId }}
|
|
78
79
|
isLoading={Boolean(isLoading)}
|
|
79
80
|
actions={actions}
|
|
80
81
|
pagination={pagination}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
|
+
import { extensionPoints } from '@open-mercato/core/modules/audit_logs/extension-points'
|
|
4
5
|
import type { ColumnDef } from '@tanstack/react-table'
|
|
5
6
|
import { DataTable, type PaginationProps } from '@open-mercato/ui/backend/DataTable'
|
|
6
7
|
import { Button } from '@open-mercato/ui/primitives/button'
|
|
@@ -245,7 +246,7 @@ export function AuditLogsActions({
|
|
|
245
246
|
data={actionItems}
|
|
246
247
|
columns={columns}
|
|
247
248
|
actions={combinedActions}
|
|
248
|
-
perspective={{ tableId:
|
|
249
|
+
perspective={{ tableId: extensionPoints.hosts.actionsTable.tableId }}
|
|
249
250
|
isLoading={Boolean(isLoading) || Boolean(undoingToken) || Boolean(redoingId)}
|
|
250
251
|
onRowClick={(item) => setSelected(item)}
|
|
251
252
|
pagination={pagination}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { dataTableExtensionHost, defineModuleExtensionPoints } from '@open-mercato/shared/modules/widgets/extension-points'
|
|
2
|
+
|
|
3
|
+
export const extensionPoints = defineModuleExtensionPoints({
|
|
4
|
+
moduleId: 'audit_logs',
|
|
5
|
+
hosts: {
|
|
6
|
+
accessLogsTable: dataTableExtensionHost({ tableId: 'audit_logs.access.list', source: 'components/AccessLogsTable.tsx' }),
|
|
7
|
+
actionsTable: dataTableExtensionHost({ tableId: 'audit_logs.actions.list', source: 'components/AuditLogsActions.tsx' }),
|
|
8
|
+
},
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
export default extensionPoints
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import * as React from 'react'
|
|
3
|
+
import { extensionPoints } from '@open-mercato/core/modules/auth/extension-points'
|
|
3
4
|
import Link from 'next/link'
|
|
4
5
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
5
6
|
import { DataTable } from '@open-mercato/ui/backend/DataTable'
|
|
@@ -146,7 +147,7 @@ export default function RolesListPage() {
|
|
|
146
147
|
sortable
|
|
147
148
|
sorting={sorting}
|
|
148
149
|
onSortingChange={setSorting}
|
|
149
|
-
perspective={{ tableId:
|
|
150
|
+
perspective={{ tableId: extensionPoints.hosts.rolesTable.tableId }}
|
|
150
151
|
emptyState={(
|
|
151
152
|
<ListEmptyState
|
|
152
153
|
entityName={t('auth.roles.list.title', 'Roles')}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import * as React from 'react'
|
|
3
|
+
import { extensionPoints } from '@open-mercato/core/modules/auth/extension-points'
|
|
3
4
|
import Link from 'next/link'
|
|
4
5
|
import { useSearchParams } from 'next/navigation'
|
|
5
6
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
@@ -428,7 +429,7 @@ export default function UsersListPage() {
|
|
|
428
429
|
sortable
|
|
429
430
|
sorting={sorting}
|
|
430
431
|
onSortingChange={setSorting}
|
|
431
|
-
perspective={{ tableId:
|
|
432
|
+
perspective={{ tableId: extensionPoints.hosts.usersTable.tableId }}
|
|
432
433
|
emptyState={(
|
|
433
434
|
<ListEmptyState
|
|
434
435
|
entityName={t('auth.users.list.title', 'Users')}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { dataTableExtensionHost, defineModuleExtensionPoints, injectionExtensionHost } from '@open-mercato/shared/modules/widgets/extension-points'
|
|
2
|
+
|
|
3
|
+
export const extensionPoints = defineModuleExtensionPoints({
|
|
4
|
+
moduleId: 'auth',
|
|
5
|
+
hosts: {
|
|
6
|
+
loginForm: injectionExtensionHost({
|
|
7
|
+
family: 'generic',
|
|
8
|
+
spotId: 'auth.login:form',
|
|
9
|
+
supported: ['render-widget'],
|
|
10
|
+
contextContract: 'auth.login-form.v1',
|
|
11
|
+
source: 'frontend/login.tsx',
|
|
12
|
+
}),
|
|
13
|
+
usersTable: dataTableExtensionHost({ tableId: 'auth.users.list', source: 'backend/users/page.tsx' }),
|
|
14
|
+
rolesTable: dataTableExtensionHost({ tableId: 'auth.roles.list', source: 'backend/roles/page.tsx' }),
|
|
15
|
+
},
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
export default extensionPoints
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
3
|
+
import { extensionPoints } from '@open-mercato/core/modules/auth/extension-points'
|
|
3
4
|
import type { ReactNode } from 'react'
|
|
4
5
|
import Image from 'next/image'
|
|
5
6
|
import Link from 'next/link'
|
|
@@ -426,7 +427,7 @@ export default function LoginPage() {
|
|
|
426
427
|
/>
|
|
427
428
|
</div>
|
|
428
429
|
<InjectionSpot<LoginFormWidgetContext>
|
|
429
|
-
spotId=
|
|
430
|
+
spotId={extensionPoints.hosts.loginForm.spotId}
|
|
430
431
|
context={loginFormContext}
|
|
431
432
|
/>
|
|
432
433
|
{authOverride?.hidePassword ? null : (
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
|
+
import { extensionPoints } from '@open-mercato/core/modules/business_rules/extension-points'
|
|
4
5
|
import Link from 'next/link'
|
|
5
6
|
import { useRouter } from 'next/navigation'
|
|
6
7
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
@@ -342,7 +343,7 @@ export default function RulesListPage() {
|
|
|
342
343
|
onFiltersApply={handleFiltersApply}
|
|
343
344
|
onFiltersClear={handleFiltersClear}
|
|
344
345
|
perspective={{
|
|
345
|
-
tableId:
|
|
346
|
+
tableId: extensionPoints.hosts.rulesTable.tableId,
|
|
346
347
|
}}
|
|
347
348
|
emptyState={(
|
|
348
349
|
<ListEmptyState
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createModuleEvents } from '@open-mercato/shared/modules/events'
|
|
2
|
+
|
|
3
|
+
const events = [
|
|
4
|
+
{ id: 'business_rules.rule.execution_failed', label: 'Rule Execution Failed', entity: 'rule', category: 'lifecycle' },
|
|
5
|
+
] as const
|
|
6
|
+
|
|
7
|
+
export const eventsConfig = createModuleEvents({ moduleId: 'business_rules', events })
|
|
8
|
+
export const emitBusinessRulesEvent = eventsConfig.emit
|
|
9
|
+
export type BusinessRulesEventId = typeof events[number]['id']
|
|
10
|
+
export default eventsConfig
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { dataTableExtensionHost, defineModuleExtensionPoints } from '@open-mercato/shared/modules/widgets/extension-points'
|
|
2
|
+
|
|
3
|
+
export const extensionPoints = defineModuleExtensionPoints({
|
|
4
|
+
moduleId: 'business_rules',
|
|
5
|
+
hosts: {
|
|
6
|
+
rulesTable: dataTableExtensionHost({ tableId: 'business-rules.rules.list', source: 'backend/rules/page.tsx' }),
|
|
7
|
+
},
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
export default extensionPoints
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { extensionPoints } from "@open-mercato/core/modules/catalog/extension-points";
|
|
4
5
|
import Link from "next/link";
|
|
5
6
|
import { usePathname } from "next/navigation";
|
|
6
7
|
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
@@ -1525,7 +1526,7 @@ export default function EditCatalogProductPage({
|
|
|
1525
1526
|
) : undefined}
|
|
1526
1527
|
fields={[]}
|
|
1527
1528
|
groups={groups}
|
|
1528
|
-
injectionSpotId=
|
|
1529
|
+
injectionSpotId={extensionPoints.hosts.productForm.spotId}
|
|
1529
1530
|
entityId={E.catalog.catalog_product}
|
|
1530
1531
|
customFieldsetBindings={{
|
|
1531
1532
|
[E.catalog.catalog_product]: { valueKey: "customFieldsetCode" },
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { extensionPoints } from "@open-mercato/core/modules/catalog/extension-points";
|
|
4
5
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
5
6
|
import type { ZodType } from "zod";
|
|
6
7
|
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
@@ -381,7 +382,7 @@ export default function CreateCatalogProductPage() {
|
|
|
381
382
|
backHref="/backend/catalog/products"
|
|
382
383
|
fields={[]}
|
|
383
384
|
groups={groups}
|
|
384
|
-
injectionSpotId=
|
|
385
|
+
injectionSpotId={extensionPoints.hosts.productForm.spotId}
|
|
385
386
|
initialValues={
|
|
386
387
|
initialValuesRef.current ?? createInitialProductFormValues()
|
|
387
388
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
|
+
import { extensionPoints } from '@open-mercato/core/modules/catalog/extension-points'
|
|
4
5
|
import Link from 'next/link'
|
|
5
6
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
6
7
|
import type { ColumnDef } from '@tanstack/react-table'
|
|
@@ -232,7 +233,7 @@ export default function CategoriesDataTable() {
|
|
|
232
233
|
setPage(1)
|
|
233
234
|
}}
|
|
234
235
|
sortable={false}
|
|
235
|
-
perspective={{ tableId:
|
|
236
|
+
perspective={{ tableId: extensionPoints.hosts.categoriesTable.tableId }}
|
|
236
237
|
rowActions={(row) => (
|
|
237
238
|
canManage ? (
|
|
238
239
|
<RowActions
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
|
+
import { extensionPoints } from '@open-mercato/core/modules/catalog/extension-points'
|
|
4
5
|
import Link from 'next/link'
|
|
5
6
|
import type { ColumnDef, SortingState } from '@tanstack/react-table'
|
|
6
7
|
import { DataTable, type DataTableExportFormat } from '@open-mercato/ui/backend/DataTable'
|
|
@@ -696,7 +697,7 @@ export default function ProductsDataTable({
|
|
|
696
697
|
onCustomFieldFilterFieldsetChange={handleCustomFieldsetFilterChange}
|
|
697
698
|
sorting={sorting}
|
|
698
699
|
onSortingChange={setSorting}
|
|
699
|
-
injectionSpotId=
|
|
700
|
+
injectionSpotId={extensionPoints.hosts.productsTable.baseSpotId}
|
|
700
701
|
injectionContext={{
|
|
701
702
|
search,
|
|
702
703
|
filters: filterValues,
|
|
@@ -721,7 +722,7 @@ export default function ProductsDataTable({
|
|
|
721
722
|
}}
|
|
722
723
|
exporter={exportConfig}
|
|
723
724
|
isLoading={isLoading}
|
|
724
|
-
perspective={{ tableId:
|
|
725
|
+
perspective={{ tableId: extensionPoints.hosts.productsTable.tableId }}
|
|
725
726
|
stickyActionsColumn
|
|
726
727
|
rowActions={(row) => (
|
|
727
728
|
<RowActions
|
|
@@ -13,6 +13,7 @@ const events = [
|
|
|
13
13
|
{ id: 'catalog.product.created', label: 'Product Created', entity: 'product', category: 'crud', clientBroadcast: true },
|
|
14
14
|
{ id: 'catalog.product.updated', label: 'Product Updated', entity: 'product', category: 'crud', clientBroadcast: true },
|
|
15
15
|
{ id: 'catalog.product.deleted', label: 'Product Deleted', entity: 'product', category: 'crud', clientBroadcast: true },
|
|
16
|
+
{ id: 'catalog.product.stock_low', label: 'Product Stock Low', entity: 'product', category: 'lifecycle' },
|
|
16
17
|
{ id: 'catalog.product_unit_conversion.created', label: 'Product Unit Conversion Created', entity: 'product_unit_conversion', category: 'crud' },
|
|
17
18
|
{ id: 'catalog.product_unit_conversion.updated', label: 'Product Unit Conversion Updated', entity: 'product_unit_conversion', category: 'crud' },
|
|
18
19
|
{ id: 'catalog.product_unit_conversion.deleted', label: 'Product Unit Conversion Deleted', entity: 'product_unit_conversion', category: 'crud' },
|