@open-mercato/core 0.5.1-develop.2949.009dcdd2d5 → 0.5.1-develop.2954.610bab2d08
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/dist/helpers/integration/salesUi.js +25 -23
- package/dist/helpers/integration/salesUi.js.map +2 -2
- package/dist/modules/api_docs/frontend/docs/api/Explorer.js +24 -24
- package/dist/modules/api_docs/frontend/docs/api/Explorer.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +15 -7
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/attachments/fields/attachment.js +4 -6
- package/dist/modules/attachments/fields/attachment.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +63 -23
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/users/create/page.js +26 -26
- package/dist/modules/auth/backend/users/create/page.js.map +2 -2
- package/dist/modules/business_rules/components/ActionRow.js +36 -25
- package/dist/modules/business_rules/components/ActionRow.js.map +2 -2
- package/dist/modules/business_rules/components/ConditionGroup.js +14 -5
- package/dist/modules/business_rules/components/ConditionGroup.js.map +2 -2
- package/dist/modules/business_rules/components/ConditionRow.js +19 -10
- package/dist/modules/business_rules/components/ConditionRow.js.map +2 -2
- package/dist/modules/business_rules/components/RuleSetMembers.js +16 -10
- package/dist/modules/business_rules/components/RuleSetMembers.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +30 -34
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +220 -223
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +20 -19
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductUomSection.js +42 -37
- package/dist/modules/catalog/components/products/ProductUomSection.js.map +2 -2
- package/dist/modules/catalog/components/products/VariantBuilder.js +22 -18
- package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +18 -26
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +4 -6
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +5 -4
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +19 -7
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +24 -21
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/components/AddressEditor.js +24 -7
- package/dist/modules/customers/components/AddressEditor.js.map +2 -2
- package/dist/modules/customers/components/AddressFormatSettings.js +35 -25
- package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityForm.js +20 -12
- package/dist/modules/customers/components/detail/ActivityForm.js.map +2 -2
- package/dist/modules/customers/components/detail/AnnualRevenueField.js +2 -2
- package/dist/modules/customers/components/detail/AnnualRevenueField.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +19 -14
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/formConfig.js +16 -12
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +3 -2
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js +18 -10
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js +3 -2
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js +3 -2
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js.map +2 -2
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +27 -28
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js +14 -6
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js +14 -6
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js +3 -2
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js +3 -2
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js +17 -8
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +40 -23
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +15 -6
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/dictionaries/components/AppearanceSelector.js +4 -4
- package/dist/modules/dictionaries/components/AppearanceSelector.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +4 -5
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +22 -14
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
- package/dist/modules/dictionaries/fields/dictionary.js +18 -13
- package/dist/modules/dictionaries/fields/dictionary.js.map +2 -2
- package/dist/modules/entities/components/EncryptionManager.js +23 -19
- package/dist/modules/entities/components/EncryptionManager.js.map +2 -2
- package/dist/modules/feature_toggles/components/formConfig.js +17 -9
- package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
- package/dist/modules/feature_toggles/components/overrideFormConfig.js +17 -9
- package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +15 -8
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +37 -22
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +22 -17
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +12 -6
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +19 -12
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/resources/components/ResourceCrudForm.js +15 -10
- package/dist/modules/resources/components/ResourceCrudForm.js.map +3 -3
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +15 -18
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/components/ProviderFieldInput.js +23 -20
- package/dist/modules/sales/components/ProviderFieldInput.js.map +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js +25 -17
- package/dist/modules/sales/components/ShippingMethodsSettings.js.map +3 -3
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +35 -42
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +87 -90
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentDialog.js +17 -6
- package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +3 -3
- package/dist/modules/sales/components/documents/LineItemDialog.js +42 -25
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +96 -87
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js +20 -11
- package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js.map +2 -2
- package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js +20 -11
- package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js +36 -22
- package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +14 -9
- package/dist/modules/staff/components/TeamMemberForm.js.map +3 -3
- package/dist/modules/workflows/backend/tasks/[id]/page.js +42 -21
- package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
- package/dist/modules/workflows/components/ActivitiesEditor.js +14 -6
- package/dist/modules/workflows/components/ActivitiesEditor.js.map +3 -3
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +25 -17
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +3 -3
- package/dist/modules/workflows/components/EdgeEditDialog.js +48 -45
- package/dist/modules/workflows/components/EdgeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialog.js +90 -90
- package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/StepsEditor.js +14 -6
- package/dist/modules/workflows/components/StepsEditor.js.map +3 -3
- package/dist/modules/workflows/components/TransitionsEditor.js +31 -26
- package/dist/modules/workflows/components/TransitionsEditor.js.map +3 -3
- package/dist/modules/workflows/components/fields/ActivityArrayEditor.js +19 -11
- package/dist/modules/workflows/components/fields/ActivityArrayEditor.js.map +3 -3
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +12 -14
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +24 -16
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +3 -3
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +12 -13
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileTaskForm.js +12 -8
- package/dist/modules/workflows/components/mobile/MobileTaskForm.js.map +2 -2
- package/dist/modules/workflows/frontend/checkout-demo/page.js +43 -46
- package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
- package/package.json +3 -3
- package/src/helpers/integration/salesUi.ts +40 -30
- package/src/modules/api_docs/frontend/docs/api/Explorer.tsx +25 -19
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +21 -11
- package/src/modules/attachments/fields/attachment.tsx +4 -6
- package/src/modules/auth/api/users/route.ts +75 -25
- package/src/modules/auth/backend/users/create/page.tsx +16 -20
- package/src/modules/business_rules/components/ActionRow.tsx +51 -32
- package/src/modules/business_rules/components/ConditionGroup.tsx +20 -9
- package/src/modules/business_rules/components/ConditionRow.tsx +24 -15
- package/src/modules/business_rules/components/RuleSetMembers.tsx +23 -13
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +47 -53
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +84 -87
- package/src/modules/catalog/components/PriceKindSettings.tsx +9 -9
- package/src/modules/catalog/components/products/ProductUomSection.tsx +85 -83
- package/src/modules/catalog/components/products/VariantBuilder.tsx +49 -33
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +12 -27
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +4 -6
- package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +5 -4
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +28 -15
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +37 -26
- package/src/modules/customers/components/AddressEditor.tsx +30 -16
- package/src/modules/customers/components/AddressFormatSettings.tsx +25 -19
- package/src/modules/customers/components/detail/ActivityForm.tsx +35 -23
- package/src/modules/customers/components/detail/AnnualRevenueField.tsx +2 -2
- package/src/modules/customers/components/detail/DealForm.tsx +33 -20
- package/src/modules/customers/components/formConfig.tsx +25 -17
- package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +3 -2
- package/src/modules/customers/widgets/dashboard/new-customers/widget.client.tsx +21 -11
- package/src/modules/customers/widgets/dashboard/new-deals/widget.client.tsx +3 -2
- package/src/modules/customers/widgets/dashboard/next-interactions/widget.client.tsx +3 -2
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +17 -22
- package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.tsx +17 -7
- package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +20 -10
- package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +3 -2
- package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +3 -2
- package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +20 -9
- package/src/modules/data_sync/backend/data-sync/page.tsx +64 -38
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +18 -7
- package/src/modules/dictionaries/components/AppearanceSelector.tsx +4 -4
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +3 -4
- package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +27 -21
- package/src/modules/dictionaries/fields/dictionary.tsx +36 -23
- package/src/modules/entities/components/EncryptionManager.tsx +49 -33
- package/src/modules/feature_toggles/components/formConfig.tsx +20 -10
- package/src/modules/feature_toggles/components/overrideFormConfig.tsx +20 -10
- package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +19 -10
- package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +49 -26
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +20 -11
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +19 -9
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +34 -21
- package/src/modules/resources/components/ResourceCrudForm.tsx +24 -15
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +12 -15
- package/src/modules/sales/components/ProviderFieldInput.tsx +26 -17
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +28 -20
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +51 -46
- package/src/modules/sales/components/documents/AddressesSection.tsx +78 -76
- package/src/modules/sales/components/documents/AdjustmentDialog.tsx +27 -15
- package/src/modules/sales/components/documents/LineItemDialog.tsx +69 -51
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +98 -87
- package/src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx +23 -12
- package/src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx +23 -12
- package/src/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.tsx +35 -19
- package/src/modules/staff/components/TeamMemberForm.tsx +23 -14
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +51 -23
- package/src/modules/workflows/components/ActivitiesEditor.tsx +20 -10
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +28 -18
- package/src/modules/workflows/components/EdgeEditDialog.tsx +51 -40
- package/src/modules/workflows/components/NodeEditDialog.tsx +81 -77
- package/src/modules/workflows/components/StepsEditor.tsx +20 -10
- package/src/modules/workflows/components/TransitionsEditor.tsx +61 -44
- package/src/modules/workflows/components/fields/ActivityArrayEditor.tsx +22 -12
- package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +9 -13
- package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +27 -17
- package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +9 -12
- package/src/modules/workflows/components/mobile/MobileTaskForm.tsx +19 -11
- package/src/modules/workflows/frontend/checkout-demo/page.tsx +71 -60
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/staff/components/TeamMemberForm.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { normalizeCustomFieldValues } from '@open-mercato/shared/lib/custom-fields/normalize'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { LookupSelect, type LookupSelectItem } from '@open-mercato/ui/backend/inputs'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { AttachmentsSection, TagsSection, type TagOption, type TagsSectionLabels } from '@open-mercato/ui/backend/detail'\nimport { E } from '#generated/entities.ids.generated'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { Plus } from 'lucide-react'\n\nconst DEFAULT_PAGE_SIZE = 100\n\nexport type TeamMemberFormValues = {\n id?: string\n teamId?: string | null\n userId?: string | null\n displayName?: string | null\n description?: string | null\n roleIds?: string[]\n tags?: string[]\n isActive?: boolean\n} & Record<string, unknown>\n\nexport type TeamMemberFormProps = {\n title: string\n submitLabel?: string\n backHref: string\n cancelHref: string\n embedded?: boolean\n initialValues: TeamMemberFormValues\n onSubmit: (values: TeamMemberFormValues) => Promise<void>\n onDelete?: () => Promise<void>\n isLoading?: boolean\n loadingMessage?: string\n tagsSection?: TeamMemberTagsSectionConfig\n}\n\ntype TeamRoleRow = {\n id: string\n name: string\n teamId: string | null\n}\n\ntype TeamRolesResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype UsersResponse = {\n items?: Array<{ id?: string; email?: string; organizationName?: string | null }>\n}\n\ntype TeamsResponse = {\n items?: Array<{ id?: string; name?: string }>\n}\n\ntype TeamMemberTagsSectionConfig = {\n title: string\n tags: TagOption[]\n onChange: (next: TagOption[]) => void\n loadOptions: (query?: string) => Promise<TagOption[]>\n createTag: (label: string) => Promise<TagOption>\n onSave: (payload: { next: TagOption[]; added: TagOption[]; removed: TagOption[] }) => Promise<void>\n labels: TagsSectionLabels\n}\n\nconst normalizeCustomFieldSubmitValue = (value: unknown): unknown => {\n const normalized = normalizeCustomFieldValues({ value })\n return normalized.value\n}\n\nexport const buildTeamMemberPayload = (\n values: TeamMemberFormValues,\n options: { id?: string } = {},\n): Record<string, unknown> => {\n const roleIds = Array.isArray(values.roleIds)\n ? values.roleIds.filter((item): item is string => typeof item === 'string')\n : []\n const tags = Array.isArray(values.tags)\n ? values.tags.filter((item): item is string => typeof item === 'string' && item.trim().length > 0)\n : null\n const customFields = collectCustomFieldValues(values, { transform: normalizeCustomFieldSubmitValue })\n return {\n ...(options.id ? { id: options.id } : {}),\n teamId: values.teamId ? String(values.teamId) : null,\n userId: values.userId ? String(values.userId) : null,\n displayName: typeof values.displayName === 'string' ? values.displayName : '',\n description: typeof values.description === 'string' && values.description.trim().length ? values.description : null,\n roleIds,\n ...(tags ? { tags } : {}),\n isActive: values.isActive ?? true,\n ...(Object.keys(customFields).length ? { customFields } : {}),\n }\n}\n\nexport function TeamMemberForm(props: TeamMemberFormProps) {\n const {\n title,\n submitLabel,\n backHref,\n cancelHref,\n embedded = false,\n initialValues,\n onSubmit,\n onDelete,\n isLoading,\n loadingMessage,\n tagsSection,\n } = props\n const translate = useT()\n const recordId = typeof initialValues?.id === 'string' ? initialValues.id : null\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const [roles, setRoles] = React.useState<TeamRoleRow[]>([])\n const [selectedTeamId, setSelectedTeamId] = React.useState<string | null>(null)\n const [userOptions, setUserOptions] = React.useState<LookupSelectItem[]>([])\n const [teamOptions, setTeamOptions] = React.useState<Array<{ value: string; label: string }>>([])\n const [roleSearch, setRoleSearch] = React.useState('')\n\n const resolvedTeamId = typeof initialValues.teamId === 'string' && initialValues.teamId.trim().length\n ? initialValues.teamId\n : null\n const resolvedUserId = typeof initialValues.userId === 'string' && initialValues.userId.trim().length\n ? initialValues.userId\n : null\n\n React.useEffect(() => {\n setSelectedTeamId(resolvedTeamId)\n }, [resolvedTeamId])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadRoles() {\n try {\n const params = new URLSearchParams({ page: '1', pageSize: String(DEFAULT_PAGE_SIZE) })\n const call = await apiCall<TeamRolesResponse>(`/api/staff/team-roles?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const nextRoles = items\n .map(mapTeamRole)\n .filter((role): role is TeamRoleRow => role !== null)\n if (!cancelled) setRoles(nextRoles)\n } catch {\n if (!cancelled) setRoles([])\n }\n }\n loadRoles()\n return () => { cancelled = true }\n }, [scopeVersion])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadTeams() {\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const call = await apiCall<TeamsResponse>(`/api/staff/teams?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const options = items\n .map((team) => {\n const id = typeof team.id === 'string' ? team.id : null\n const name = typeof team.name === 'string' ? team.name : null\n if (!id || !name) return null\n return { value: id, label: name }\n })\n .filter((entry): entry is { value: string; label: string } => entry !== null)\n if (!cancelled) setTeamOptions(options)\n } catch {\n if (!cancelled) setTeamOptions([])\n }\n }\n loadTeams()\n return () => { cancelled = true }\n }, [scopeVersion])\n\n React.useEffect(() => {\n if (!resolvedUserId) return\n const userId = resolvedUserId\n if (userOptions.some((option) => option.id === resolvedUserId)) return\n let cancelled = false\n async function loadSelectedUser() {\n try {\n const call = await apiCall<UsersResponse>(`/api/auth/users?id=${encodeURIComponent(userId)}`)\n const entry = Array.isArray(call.result?.items) ? call.result.items[0] : null\n const entryId = typeof entry?.id === 'string' ? entry.id : null\n const entryEmail = typeof entry?.email === 'string' ? entry.email : null\n if (!entryId || !entryEmail) return\n if (!cancelled) {\n setUserOptions((prev) => {\n if (prev.some((option) => option.id === entryId)) return prev\n return [{ id: entryId, title: entryEmail, subtitle: entry?.organizationName ?? null }, ...prev]\n })\n }\n } catch {\n if (!cancelled) setUserOptions((prev) => prev)\n }\n }\n loadSelectedUser()\n return () => { cancelled = true }\n }, [resolvedUserId, userOptions])\n\n const filteredRoles = React.useMemo(\n () => filterRolesByTeam(roles, selectedTeamId),\n [roles, selectedTeamId],\n )\n const roleOptions = React.useMemo(\n () => filteredRoles.map((role) => ({ value: role.id, label: role.name })),\n [filteredRoles],\n )\n const filteredRoleOptions = React.useMemo(() => {\n const query = roleSearch.trim().toLowerCase()\n if (!query) return roleOptions\n return roleOptions.filter((option) => (\n option.label.toLowerCase().includes(query) || option.value.toLowerCase().includes(query)\n ))\n }, [roleOptions, roleSearch])\n const createRoleHref = React.useMemo(() => {\n const params = new URLSearchParams()\n if (selectedTeamId) params.set('teamId', selectedTeamId)\n const query = params.toString()\n return `/backend/staff/team-roles/create${query ? `?${query}` : ''}`\n }, [selectedTeamId])\n const createTeamHref = '/backend/staff/teams/create'\n\n React.useEffect(() => {\n setRoleSearch('')\n }, [selectedTeamId])\n\n const fetchUserOptions = React.useCallback(async (query?: string): Promise<LookupSelectItem[]> => {\n const params = new URLSearchParams({ page: '1', pageSize: '50' })\n if (query && query.trim().length) params.set('search', query.trim())\n const call = await apiCall<UsersResponse>(`/api/auth/users?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const options = items\n .map((user): LookupSelectItem | null => {\n const id = typeof user?.id === 'string' ? user.id : null\n const email = typeof user?.email === 'string' ? user.email : null\n if (!id || !email) return null\n return {\n id,\n title: email,\n subtitle: user.organizationName ?? null,\n }\n })\n .filter((option): option is LookupSelectItem => option !== null)\n setUserOptions(options)\n return options\n }, [])\n\n const fields = React.useMemo<CrudField[]>(() => {\n const baseFields: CrudField[] = [\n {\n id: 'userId',\n label: translate('staff.teamMembers.form.fields.user', 'User'),\n type: 'custom',\n component: ({ value, setValue }) => (\n <LookupSelect\n value={typeof value === 'string' ? value : null}\n onChange={(next) => setValue(next)}\n options={userOptions}\n fetchOptions={fetchUserOptions}\n placeholder={translate('staff.teamMembers.form.fields.user.placeholder', 'Select a user')}\n searchPlaceholder={translate('staff.teamMembers.form.fields.user.search', 'Search users')}\n emptyLabel={translate('staff.teamMembers.form.fields.user.empty', 'No users found')}\n selectedHintLabel={(id) => translate('staff.teamMembers.form.fields.user.selected', 'Selected user: {{id}}', { id })}\n />\n ),\n },\n {\n id: 'teamId',\n label: '',\n type: 'custom',\n component: ({ value, setValue, setFormValue, values, disabled }) => {\n const currentValue = typeof value === 'string' ? value : ''\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-sm font-medium\">\n {translate('staff.teamMembers.form.fields.team', 'Team')}\n </span>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => router.push(createTeamHref)}\n disabled={disabled}\n >\n <Plus className=\"mr-2 h-4 w-4\" aria-hidden />\n {translate('staff.teamMembers.form.actions.createTeam', 'Create new team')}\n </Button>\n </div>\n <select\n className=\"w-full h-9 rounded border px-2 text-sm\"\n value={currentValue}\n onChange={(event) => {\n const nextValue = event.target.value || undefined\n const nextTeamId = event.target.value || null\n setValue(nextValue)\n setSelectedTeamId(nextTeamId)\n if (!setFormValue) return\n const roleIds = Array.isArray(values?.roleIds)\n ? values?.roleIds.filter((item): item is string => typeof item === 'string')\n : []\n const allowedRoleIds = buildAllowedRoleIdSet(roles, nextTeamId)\n const nextRoleIds = roleIds.filter((roleId) => allowedRoleIds.has(roleId))\n if (nextRoleIds.length !== roleIds.length) {\n setFormValue('roleIds', nextRoleIds)\n }\n }}\n data-crud-focus-target=\"\"\n disabled={disabled}\n >\n <option value=\"\">{translate('ui.forms.select.emptyOption', '\u2014')}</option>\n {teamOptions.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </div>\n )\n },\n },\n {\n id: 'displayName',\n label: translate('staff.teamMembers.form.fields.displayName', 'Display name'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: translate('staff.teamMembers.form.fields.description', 'Description'),\n type: 'richtext',\n editor: 'uiw',\n },\n {\n id: 'roleIds',\n label: '',\n type: 'custom',\n component: ({ value, setValue, disabled }) => {\n const selectedValues = Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : []\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-sm font-medium\">\n {translate('staff.teamMembers.form.fields.roles', 'Roles')}\n </span>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => router.push(createRoleHref)}\n disabled={disabled}\n >\n <Plus className=\"mr-2 h-4 w-4\" aria-hidden />\n {translate('staff.teamMembers.form.actions.defineRole', 'Define new role')}\n </Button>\n </div>\n <input\n className=\"w-full h-8 rounded border px-2 text-sm\"\n placeholder={translate('ui.forms.listbox.searchPlaceholder', 'Search...')}\n value={roleSearch}\n onChange={(event) => setRoleSearch(event.target.value)}\n data-crud-focus-target=\"\"\n disabled={disabled}\n />\n <div className=\"rounded border max-h-48 overflow-auto divide-y\">\n {filteredRoleOptions.map((option) => {\n const isSelected = selectedValues.includes(option.value)\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n const next = new Set(selectedValues)\n if (isSelected) {\n next.delete(option.value)\n } else {\n next.add(option.value)\n }\n setValue(Array.from(next))\n }}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-muted ${isSelected ? 'bg-muted' : ''}`}\n disabled={disabled}\n >\n <span className=\"inline-flex items-center gap-2\">\n <input type=\"checkbox\" className=\"size-4\" readOnly checked={isSelected} />\n <span>{option.label}</span>\n </span>\n </button>\n )\n })}\n {!filteredRoleOptions.length ? (\n <div className=\"px-3 py-2 text-sm text-muted-foreground\">\n {translate('ui.forms.listbox.noMatches', 'No matches')}\n </div>\n ) : null}\n </div>\n </div>\n )\n },\n },\n {\n id: 'isActive',\n label: translate('staff.teamMembers.form.fields.active', 'Active'),\n type: 'checkbox',\n },\n ]\n\n if (!tagsSection) {\n baseFields.splice(5, 0, {\n id: 'tags',\n label: translate('staff.teamMembers.form.fields.tags', 'Tags'),\n type: 'tags',\n placeholder: translate('staff.teamMembers.form.fields.tags.placeholder', 'Add tags'),\n })\n }\n\n return baseFields\n }, [\n createRoleHref,\n fetchUserOptions,\n filteredRoleOptions,\n roleSearch,\n roles,\n router,\n tagsSection,\n translate,\n teamOptions,\n userOptions,\n ])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => {\n const baseGroups: CrudFormGroup[] = [\n {\n id: 'details',\n column: 1,\n fields: ['userId', 'teamId', 'displayName', 'description', 'roleIds', 'isActive'],\n },\n {\n id: 'custom',\n title: translate('entities.customFields.title', 'Custom Attributes'),\n column: 2,\n kind: 'customFields',\n },\n ]\n\n if (tagsSection) {\n baseGroups.push({\n id: 'tags',\n column: 2,\n bare: true,\n component: () => (\n <TagsSection\n title={tagsSection.title}\n tags={tagsSection.tags}\n onChange={tagsSection.onChange}\n loadOptions={tagsSection.loadOptions}\n createTag={tagsSection.createTag}\n onSave={tagsSection.onSave}\n labels={tagsSection.labels}\n />\n ),\n })\n } else {\n baseGroups.splice(1, 0, {\n id: 'tags',\n title: translate('staff.teamMembers.form.fields.tags', 'Tags'),\n column: 2,\n fields: ['tags'],\n })\n }\n\n baseGroups.push({\n id: 'attachments',\n title: translate('attachments.library.title', 'Attachments'),\n column: 1,\n component: () => (\n <AttachmentsSection\n entityId={E.staff.staff_team_member}\n recordId={recordId}\n showHeader={false}\n />\n ),\n })\n\n return baseGroups\n }, [recordId, tagsSection, translate])\n\n return (\n <CrudForm<TeamMemberFormValues>\n embedded={embedded}\n title={title}\n backHref={backHref}\n cancelHref={cancelHref}\n versionHistory={initialValues.id\n ? { resourceKind: 'staff.teamMember', resourceId: String(initialValues.id) }\n : undefined}\n submitLabel={submitLabel}\n fields={fields}\n groups={groups}\n entityId={E.staff.staff_team_member}\n initialValues={initialValues}\n onSubmit={onSubmit}\n onDelete={onDelete}\n isLoading={isLoading}\n loadingMessage={loadingMessage}\n />\n )\n}\n\nfunction mapTeamRole(item: Record<string, unknown>): TeamRoleRow | null {\n const id = typeof item.id === 'string' ? item.id : ''\n if (!id) return null\n const name = typeof item.name === 'string' && item.name.trim().length ? item.name.trim() : id\n const teamId = typeof item.teamId === 'string'\n ? item.teamId\n : typeof item.team_id === 'string'\n ? item.team_id\n : null\n return { id, name, teamId }\n}\n\nfunction filterRolesByTeam(roles: TeamRoleRow[], teamId: string | null): TeamRoleRow[] {\n if (!teamId) return roles.filter((role) => role.teamId == null)\n return roles.filter((role) => role.teamId == null || role.teamId === teamId)\n}\n\nfunction buildAllowedRoleIdSet(roles: TeamRoleRow[], teamId: string | null): Set<string> {\n return new Set(filterRolesByTeam(roles, teamId).map((role) => role.id))\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { normalizeCustomFieldValues } from '@open-mercato/shared/lib/custom-fields/normalize'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { LookupSelect, type LookupSelectItem } from '@open-mercato/ui/backend/inputs'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { AttachmentsSection, TagsSection, type TagOption, type TagsSectionLabels } from '@open-mercato/ui/backend/detail'\nimport { E } from '#generated/entities.ids.generated'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { Plus } from 'lucide-react'\n\nconst DEFAULT_PAGE_SIZE = 100\n\nexport type TeamMemberFormValues = {\n id?: string\n teamId?: string | null\n userId?: string | null\n displayName?: string | null\n description?: string | null\n roleIds?: string[]\n tags?: string[]\n isActive?: boolean\n} & Record<string, unknown>\n\nexport type TeamMemberFormProps = {\n title: string\n submitLabel?: string\n backHref: string\n cancelHref: string\n embedded?: boolean\n initialValues: TeamMemberFormValues\n onSubmit: (values: TeamMemberFormValues) => Promise<void>\n onDelete?: () => Promise<void>\n isLoading?: boolean\n loadingMessage?: string\n tagsSection?: TeamMemberTagsSectionConfig\n}\n\ntype TeamRoleRow = {\n id: string\n name: string\n teamId: string | null\n}\n\ntype TeamRolesResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype UsersResponse = {\n items?: Array<{ id?: string; email?: string; organizationName?: string | null }>\n}\n\ntype TeamsResponse = {\n items?: Array<{ id?: string; name?: string }>\n}\n\ntype TeamMemberTagsSectionConfig = {\n title: string\n tags: TagOption[]\n onChange: (next: TagOption[]) => void\n loadOptions: (query?: string) => Promise<TagOption[]>\n createTag: (label: string) => Promise<TagOption>\n onSave: (payload: { next: TagOption[]; added: TagOption[]; removed: TagOption[] }) => Promise<void>\n labels: TagsSectionLabels\n}\n\nconst normalizeCustomFieldSubmitValue = (value: unknown): unknown => {\n const normalized = normalizeCustomFieldValues({ value })\n return normalized.value\n}\n\nexport const buildTeamMemberPayload = (\n values: TeamMemberFormValues,\n options: { id?: string } = {},\n): Record<string, unknown> => {\n const roleIds = Array.isArray(values.roleIds)\n ? values.roleIds.filter((item): item is string => typeof item === 'string')\n : []\n const tags = Array.isArray(values.tags)\n ? values.tags.filter((item): item is string => typeof item === 'string' && item.trim().length > 0)\n : null\n const customFields = collectCustomFieldValues(values, { transform: normalizeCustomFieldSubmitValue })\n return {\n ...(options.id ? { id: options.id } : {}),\n teamId: values.teamId ? String(values.teamId) : null,\n userId: values.userId ? String(values.userId) : null,\n displayName: typeof values.displayName === 'string' ? values.displayName : '',\n description: typeof values.description === 'string' && values.description.trim().length ? values.description : null,\n roleIds,\n ...(tags ? { tags } : {}),\n isActive: values.isActive ?? true,\n ...(Object.keys(customFields).length ? { customFields } : {}),\n }\n}\n\nexport function TeamMemberForm(props: TeamMemberFormProps) {\n const {\n title,\n submitLabel,\n backHref,\n cancelHref,\n embedded = false,\n initialValues,\n onSubmit,\n onDelete,\n isLoading,\n loadingMessage,\n tagsSection,\n } = props\n const translate = useT()\n const recordId = typeof initialValues?.id === 'string' ? initialValues.id : null\n const router = useRouter()\n const scopeVersion = useOrganizationScopeVersion()\n const [roles, setRoles] = React.useState<TeamRoleRow[]>([])\n const [selectedTeamId, setSelectedTeamId] = React.useState<string | null>(null)\n const [userOptions, setUserOptions] = React.useState<LookupSelectItem[]>([])\n const [teamOptions, setTeamOptions] = React.useState<Array<{ value: string; label: string }>>([])\n const [roleSearch, setRoleSearch] = React.useState('')\n\n const resolvedTeamId = typeof initialValues.teamId === 'string' && initialValues.teamId.trim().length\n ? initialValues.teamId\n : null\n const resolvedUserId = typeof initialValues.userId === 'string' && initialValues.userId.trim().length\n ? initialValues.userId\n : null\n\n React.useEffect(() => {\n setSelectedTeamId(resolvedTeamId)\n }, [resolvedTeamId])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadRoles() {\n try {\n const params = new URLSearchParams({ page: '1', pageSize: String(DEFAULT_PAGE_SIZE) })\n const call = await apiCall<TeamRolesResponse>(`/api/staff/team-roles?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const nextRoles = items\n .map(mapTeamRole)\n .filter((role): role is TeamRoleRow => role !== null)\n if (!cancelled) setRoles(nextRoles)\n } catch {\n if (!cancelled) setRoles([])\n }\n }\n loadRoles()\n return () => { cancelled = true }\n }, [scopeVersion])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadTeams() {\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const call = await apiCall<TeamsResponse>(`/api/staff/teams?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const options = items\n .map((team) => {\n const id = typeof team.id === 'string' ? team.id : null\n const name = typeof team.name === 'string' ? team.name : null\n if (!id || !name) return null\n return { value: id, label: name }\n })\n .filter((entry): entry is { value: string; label: string } => entry !== null)\n if (!cancelled) setTeamOptions(options)\n } catch {\n if (!cancelled) setTeamOptions([])\n }\n }\n loadTeams()\n return () => { cancelled = true }\n }, [scopeVersion])\n\n React.useEffect(() => {\n if (!resolvedUserId) return\n const userId = resolvedUserId\n if (userOptions.some((option) => option.id === resolvedUserId)) return\n let cancelled = false\n async function loadSelectedUser() {\n try {\n const call = await apiCall<UsersResponse>(`/api/auth/users?id=${encodeURIComponent(userId)}`)\n const entry = Array.isArray(call.result?.items) ? call.result.items[0] : null\n const entryId = typeof entry?.id === 'string' ? entry.id : null\n const entryEmail = typeof entry?.email === 'string' ? entry.email : null\n if (!entryId || !entryEmail) return\n if (!cancelled) {\n setUserOptions((prev) => {\n if (prev.some((option) => option.id === entryId)) return prev\n return [{ id: entryId, title: entryEmail, subtitle: entry?.organizationName ?? null }, ...prev]\n })\n }\n } catch {\n if (!cancelled) setUserOptions((prev) => prev)\n }\n }\n loadSelectedUser()\n return () => { cancelled = true }\n }, [resolvedUserId, userOptions])\n\n const filteredRoles = React.useMemo(\n () => filterRolesByTeam(roles, selectedTeamId),\n [roles, selectedTeamId],\n )\n const roleOptions = React.useMemo(\n () => filteredRoles.map((role) => ({ value: role.id, label: role.name })),\n [filteredRoles],\n )\n const filteredRoleOptions = React.useMemo(() => {\n const query = roleSearch.trim().toLowerCase()\n if (!query) return roleOptions\n return roleOptions.filter((option) => (\n option.label.toLowerCase().includes(query) || option.value.toLowerCase().includes(query)\n ))\n }, [roleOptions, roleSearch])\n const createRoleHref = React.useMemo(() => {\n const params = new URLSearchParams()\n if (selectedTeamId) params.set('teamId', selectedTeamId)\n const query = params.toString()\n return `/backend/staff/team-roles/create${query ? `?${query}` : ''}`\n }, [selectedTeamId])\n const createTeamHref = '/backend/staff/teams/create'\n\n React.useEffect(() => {\n setRoleSearch('')\n }, [selectedTeamId])\n\n const fetchUserOptions = React.useCallback(async (query?: string): Promise<LookupSelectItem[]> => {\n const params = new URLSearchParams({ page: '1', pageSize: '50' })\n if (query && query.trim().length) params.set('search', query.trim())\n const call = await apiCall<UsersResponse>(`/api/auth/users?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const options = items\n .map((user): LookupSelectItem | null => {\n const id = typeof user?.id === 'string' ? user.id : null\n const email = typeof user?.email === 'string' ? user.email : null\n if (!id || !email) return null\n return {\n id,\n title: email,\n subtitle: user.organizationName ?? null,\n }\n })\n .filter((option): option is LookupSelectItem => option !== null)\n setUserOptions(options)\n return options\n }, [])\n\n const fields = React.useMemo<CrudField[]>(() => {\n const baseFields: CrudField[] = [\n {\n id: 'userId',\n label: translate('staff.teamMembers.form.fields.user', 'User'),\n type: 'custom',\n component: ({ value, setValue }) => (\n <LookupSelect\n value={typeof value === 'string' ? value : null}\n onChange={(next) => setValue(next)}\n options={userOptions}\n fetchOptions={fetchUserOptions}\n placeholder={translate('staff.teamMembers.form.fields.user.placeholder', 'Select a user')}\n searchPlaceholder={translate('staff.teamMembers.form.fields.user.search', 'Search users')}\n emptyLabel={translate('staff.teamMembers.form.fields.user.empty', 'No users found')}\n selectedHintLabel={(id) => translate('staff.teamMembers.form.fields.user.selected', 'Selected user: {{id}}', { id })}\n />\n ),\n },\n {\n id: 'teamId',\n label: '',\n type: 'custom',\n component: ({ value, setValue, setFormValue, values, disabled }) => {\n const currentValue = typeof value === 'string' ? value : ''\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-sm font-medium\">\n {translate('staff.teamMembers.form.fields.team', 'Team')}\n </span>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => router.push(createTeamHref)}\n disabled={disabled}\n >\n <Plus className=\"mr-2 h-4 w-4\" aria-hidden />\n {translate('staff.teamMembers.form.actions.createTeam', 'Create new team')}\n </Button>\n </div>\n <Select\n value={currentValue || undefined}\n onValueChange={(value) => {\n const nextValue = value || undefined\n const nextTeamId = value || null\n setValue(nextValue)\n setSelectedTeamId(nextTeamId)\n if (!setFormValue) return\n const roleIds = Array.isArray(values?.roleIds)\n ? values?.roleIds.filter((item): item is string => typeof item === 'string')\n : []\n const allowedRoleIds = buildAllowedRoleIdSet(roles, nextTeamId)\n const nextRoleIds = roleIds.filter((roleId) => allowedRoleIds.has(roleId))\n if (nextRoleIds.length !== roleIds.length) {\n setFormValue('roleIds', nextRoleIds)\n }\n }}\n disabled={disabled}\n >\n <SelectTrigger data-crud-focus-target=\"\">\n <SelectValue placeholder={translate('ui.forms.select.emptyOption', '\u2014')} />\n </SelectTrigger>\n <SelectContent>\n {teamOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )\n },\n },\n {\n id: 'displayName',\n label: translate('staff.teamMembers.form.fields.displayName', 'Display name'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: translate('staff.teamMembers.form.fields.description', 'Description'),\n type: 'richtext',\n editor: 'uiw',\n },\n {\n id: 'roleIds',\n label: '',\n type: 'custom',\n component: ({ value, setValue, disabled }) => {\n const selectedValues = Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : []\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-sm font-medium\">\n {translate('staff.teamMembers.form.fields.roles', 'Roles')}\n </span>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => router.push(createRoleHref)}\n disabled={disabled}\n >\n <Plus className=\"mr-2 h-4 w-4\" aria-hidden />\n {translate('staff.teamMembers.form.actions.defineRole', 'Define new role')}\n </Button>\n </div>\n <input\n className=\"w-full h-8 rounded border px-2 text-sm\"\n placeholder={translate('ui.forms.listbox.searchPlaceholder', 'Search...')}\n value={roleSearch}\n onChange={(event) => setRoleSearch(event.target.value)}\n data-crud-focus-target=\"\"\n disabled={disabled}\n />\n <div className=\"rounded border max-h-48 overflow-auto divide-y\">\n {filteredRoleOptions.map((option) => {\n const isSelected = selectedValues.includes(option.value)\n return (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n const next = new Set(selectedValues)\n if (isSelected) {\n next.delete(option.value)\n } else {\n next.add(option.value)\n }\n setValue(Array.from(next))\n }}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-muted ${isSelected ? 'bg-muted' : ''}`}\n disabled={disabled}\n >\n <span className=\"inline-flex items-center gap-2\">\n <input type=\"checkbox\" className=\"size-4\" readOnly checked={isSelected} />\n <span>{option.label}</span>\n </span>\n </button>\n )\n })}\n {!filteredRoleOptions.length ? (\n <div className=\"px-3 py-2 text-sm text-muted-foreground\">\n {translate('ui.forms.listbox.noMatches', 'No matches')}\n </div>\n ) : null}\n </div>\n </div>\n )\n },\n },\n {\n id: 'isActive',\n label: translate('staff.teamMembers.form.fields.active', 'Active'),\n type: 'checkbox',\n },\n ]\n\n if (!tagsSection) {\n baseFields.splice(5, 0, {\n id: 'tags',\n label: translate('staff.teamMembers.form.fields.tags', 'Tags'),\n type: 'tags',\n placeholder: translate('staff.teamMembers.form.fields.tags.placeholder', 'Add tags'),\n })\n }\n\n return baseFields\n }, [\n createRoleHref,\n fetchUserOptions,\n filteredRoleOptions,\n roleSearch,\n roles,\n router,\n tagsSection,\n translate,\n teamOptions,\n userOptions,\n ])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => {\n const baseGroups: CrudFormGroup[] = [\n {\n id: 'details',\n column: 1,\n fields: ['userId', 'teamId', 'displayName', 'description', 'roleIds', 'isActive'],\n },\n {\n id: 'custom',\n title: translate('entities.customFields.title', 'Custom Attributes'),\n column: 2,\n kind: 'customFields',\n },\n ]\n\n if (tagsSection) {\n baseGroups.push({\n id: 'tags',\n column: 2,\n bare: true,\n component: () => (\n <TagsSection\n title={tagsSection.title}\n tags={tagsSection.tags}\n onChange={tagsSection.onChange}\n loadOptions={tagsSection.loadOptions}\n createTag={tagsSection.createTag}\n onSave={tagsSection.onSave}\n labels={tagsSection.labels}\n />\n ),\n })\n } else {\n baseGroups.splice(1, 0, {\n id: 'tags',\n title: translate('staff.teamMembers.form.fields.tags', 'Tags'),\n column: 2,\n fields: ['tags'],\n })\n }\n\n baseGroups.push({\n id: 'attachments',\n title: translate('attachments.library.title', 'Attachments'),\n column: 1,\n component: () => (\n <AttachmentsSection\n entityId={E.staff.staff_team_member}\n recordId={recordId}\n showHeader={false}\n />\n ),\n })\n\n return baseGroups\n }, [recordId, tagsSection, translate])\n\n return (\n <CrudForm<TeamMemberFormValues>\n embedded={embedded}\n title={title}\n backHref={backHref}\n cancelHref={cancelHref}\n versionHistory={initialValues.id\n ? { resourceKind: 'staff.teamMember', resourceId: String(initialValues.id) }\n : undefined}\n submitLabel={submitLabel}\n fields={fields}\n groups={groups}\n entityId={E.staff.staff_team_member}\n initialValues={initialValues}\n onSubmit={onSubmit}\n onDelete={onDelete}\n isLoading={isLoading}\n loadingMessage={loadingMessage}\n />\n )\n}\n\nfunction mapTeamRole(item: Record<string, unknown>): TeamRoleRow | null {\n const id = typeof item.id === 'string' ? item.id : ''\n if (!id) return null\n const name = typeof item.name === 'string' && item.name.trim().length ? item.name.trim() : id\n const teamId = typeof item.teamId === 'string'\n ? item.teamId\n : typeof item.team_id === 'string'\n ? item.team_id\n : null\n return { id, name, teamId }\n}\n\nfunction filterRolesByTeam(roles: TeamRoleRow[], teamId: string | null): TeamRoleRow[] {\n if (!teamId) return roles.filter((role) => role.teamId == null)\n return roles.filter((role) => role.teamId == null || role.teamId === teamId)\n}\n\nfunction buildAllowedRoleIdSet(roles: TeamRoleRow[], teamId: string | null): Set<string> {\n return new Set(filterRolesByTeam(roles, teamId).map((role) => role.id))\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["value"]
|
|
7
7
|
}
|
|
@@ -5,7 +5,15 @@ import Link from "next/link";
|
|
|
5
5
|
import { useRouter } from "next/navigation";
|
|
6
6
|
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
7
7
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
8
|
+
import { Input } from "@open-mercato/ui/primitives/input";
|
|
8
9
|
import { FormHeader } from "@open-mercato/ui/backend/forms";
|
|
10
|
+
import {
|
|
11
|
+
Select,
|
|
12
|
+
SelectContent,
|
|
13
|
+
SelectItem,
|
|
14
|
+
SelectTrigger,
|
|
15
|
+
SelectValue
|
|
16
|
+
} from "@open-mercato/ui/primitives/select";
|
|
9
17
|
import { Spinner } from "@open-mercato/ui/primitives/spinner";
|
|
10
18
|
import { Separator } from "@open-mercato/ui/primitives/separator";
|
|
11
19
|
import { JsonDisplay } from "@open-mercato/ui/backend/JsonDisplay";
|
|
@@ -22,6 +30,7 @@ function UserTaskDetailPage({ params }) {
|
|
|
22
30
|
const [formData, setFormData] = React.useState({});
|
|
23
31
|
const [comments, setComments] = React.useState("");
|
|
24
32
|
const [submitting, setSubmitting] = React.useState(false);
|
|
33
|
+
const [invalidField, setInvalidField] = React.useState(null);
|
|
25
34
|
const { data: task, isLoading, error } = useQuery({
|
|
26
35
|
queryKey: ["workflow-task", params.id],
|
|
27
36
|
queryFn: async () => {
|
|
@@ -39,6 +48,7 @@ function UserTaskDetailPage({ params }) {
|
|
|
39
48
|
...prev,
|
|
40
49
|
[fieldName]: value
|
|
41
50
|
}));
|
|
51
|
+
if (invalidField === fieldName) setInvalidField(null);
|
|
42
52
|
};
|
|
43
53
|
const handleSubmit = async (e) => {
|
|
44
54
|
e.preventDefault();
|
|
@@ -46,11 +56,20 @@ function UserTaskDetailPage({ params }) {
|
|
|
46
56
|
if (task.formSchema?.required) {
|
|
47
57
|
for (const requiredField of task.formSchema.required) {
|
|
48
58
|
if (!formData[requiredField] || formData[requiredField] === "") {
|
|
49
|
-
|
|
59
|
+
const fieldSchema = task.formSchema.properties?.[requiredField];
|
|
60
|
+
const fieldLabel = fieldSchema?.title ?? requiredField;
|
|
61
|
+
flash(t("workflows.tasks.detail.validation.requiredField", { field: fieldLabel }), "error");
|
|
62
|
+
setInvalidField(requiredField);
|
|
63
|
+
if (typeof document !== "undefined") {
|
|
64
|
+
const trigger = document.getElementById(requiredField);
|
|
65
|
+
trigger?.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
66
|
+
trigger?.focus();
|
|
67
|
+
}
|
|
50
68
|
return;
|
|
51
69
|
}
|
|
52
70
|
}
|
|
53
71
|
}
|
|
72
|
+
setInvalidField(null);
|
|
54
73
|
setSubmitting(true);
|
|
55
74
|
try {
|
|
56
75
|
const result = await apiCall(`/api/workflows/tasks/${params.id}/complete`, {
|
|
@@ -99,16 +118,22 @@ function UserTaskDetailPage({ params }) {
|
|
|
99
118
|
] }),
|
|
100
119
|
fieldDescription && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: fieldDescription }),
|
|
101
120
|
/* @__PURE__ */ jsxs(
|
|
102
|
-
|
|
121
|
+
Select,
|
|
103
122
|
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
onChange: (e) => handleFieldChange(fieldName, e.target.value),
|
|
107
|
-
required,
|
|
108
|
-
className: inputClasses,
|
|
123
|
+
value: fieldValue(fieldName) ? String(fieldValue(fieldName)) : void 0,
|
|
124
|
+
onValueChange: (value) => handleFieldChange(fieldName, value ?? ""),
|
|
109
125
|
children: [
|
|
110
|
-
/* @__PURE__ */ jsx(
|
|
111
|
-
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
SelectTrigger,
|
|
128
|
+
{
|
|
129
|
+
id: fieldName,
|
|
130
|
+
className: `${inputClasses} ${invalidField === fieldName ? "ring-2 ring-status-error-border border-status-error-border" : ""}`,
|
|
131
|
+
"aria-required": required,
|
|
132
|
+
"aria-invalid": invalidField === fieldName ? true : void 0,
|
|
133
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("workflows.tasks.detail.form.selectOption") })
|
|
134
|
+
}
|
|
135
|
+
),
|
|
136
|
+
/* @__PURE__ */ jsx(SelectContent, { children: enumValues.map((value) => /* @__PURE__ */ jsx(SelectItem, { value, children: value }, value)) })
|
|
112
137
|
]
|
|
113
138
|
}
|
|
114
139
|
)
|
|
@@ -124,14 +149,13 @@ function UserTaskDetailPage({ params }) {
|
|
|
124
149
|
] }),
|
|
125
150
|
fieldDescription && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: fieldDescription }),
|
|
126
151
|
/* @__PURE__ */ jsx(
|
|
127
|
-
|
|
152
|
+
Input,
|
|
128
153
|
{
|
|
129
154
|
type: "email",
|
|
130
155
|
id: fieldName,
|
|
131
156
|
value: fieldValue(fieldName),
|
|
132
157
|
onChange: (e) => handleFieldChange(fieldName, e.target.value),
|
|
133
|
-
required
|
|
134
|
-
className: inputClasses
|
|
158
|
+
required
|
|
135
159
|
}
|
|
136
160
|
)
|
|
137
161
|
] }, fieldName);
|
|
@@ -183,14 +207,13 @@ function UserTaskDetailPage({ params }) {
|
|
|
183
207
|
] }),
|
|
184
208
|
fieldDescription && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: fieldDescription }),
|
|
185
209
|
/* @__PURE__ */ jsx(
|
|
186
|
-
|
|
210
|
+
Input,
|
|
187
211
|
{
|
|
188
212
|
type: "text",
|
|
189
213
|
id: fieldName,
|
|
190
214
|
value: fieldValue(fieldName),
|
|
191
215
|
onChange: (e) => handleFieldChange(fieldName, e.target.value),
|
|
192
|
-
required
|
|
193
|
-
className: inputClasses
|
|
216
|
+
required
|
|
194
217
|
}
|
|
195
218
|
)
|
|
196
219
|
] }, fieldName);
|
|
@@ -203,15 +226,14 @@ function UserTaskDetailPage({ params }) {
|
|
|
203
226
|
] }),
|
|
204
227
|
fieldDescription && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: fieldDescription }),
|
|
205
228
|
/* @__PURE__ */ jsx(
|
|
206
|
-
|
|
229
|
+
Input,
|
|
207
230
|
{
|
|
208
231
|
type: "number",
|
|
209
232
|
id: fieldName,
|
|
210
233
|
value: fieldValue(fieldName),
|
|
211
234
|
onChange: (e) => handleFieldChange(fieldName, e.target.value ? Number(e.target.value) : ""),
|
|
212
235
|
required,
|
|
213
|
-
step: fieldType === "integer" ? 1 : "any"
|
|
214
|
-
className: inputClasses
|
|
236
|
+
step: fieldType === "integer" ? 1 : "any"
|
|
215
237
|
}
|
|
216
238
|
)
|
|
217
239
|
] }, fieldName);
|
|
@@ -243,14 +265,13 @@ function UserTaskDetailPage({ params }) {
|
|
|
243
265
|
] }),
|
|
244
266
|
fieldDescription && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: fieldDescription }),
|
|
245
267
|
/* @__PURE__ */ jsx(
|
|
246
|
-
|
|
268
|
+
Input,
|
|
247
269
|
{
|
|
248
270
|
type: "text",
|
|
249
271
|
id: fieldName,
|
|
250
272
|
value: fieldValue(fieldName),
|
|
251
273
|
onChange: (e) => handleFieldChange(fieldName, e.target.value),
|
|
252
|
-
required
|
|
253
|
-
className: inputClasses
|
|
274
|
+
required
|
|
254
275
|
}
|
|
255
276
|
)
|
|
256
277
|
] }, fieldName);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/workflows/backend/tasks/%5Bid%5D/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 { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Separator } from '@open-mercato/ui/primitives/separator'\nimport { JsonDisplay } from '@open-mercato/ui/backend/JsonDisplay'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useQuery } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { MobileTaskForm } from '../../../components/mobile/MobileTaskForm'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport type { UserTaskResponse, UserTaskStatus } from '../../../data/types'\n\nexport default function UserTaskDetailPage({ params }: { params: { id: string } }) {\n const router = useRouter()\n const t = useT()\n const isMobile = useIsMobile()\n const [formData, setFormData] = React.useState<Record<string, string | number | boolean>>({})\n const [comments, setComments] = React.useState('')\n const [submitting, setSubmitting] = React.useState(false)\n\n const { data: task, isLoading, error } = useQuery({\n queryKey: ['workflow-task', params.id],\n queryFn: async () => {\n const result = await apiCall<{ data: UserTaskResponse }>(\n `/api/workflows/tasks/${params.id}`\n )\n\n if (!result.ok) {\n throw new Error('Failed to fetch task')\n }\n\n return result.result?.data || null\n },\n })\n\n const handleFieldChange = (fieldName: string, value: any) => {\n setFormData(prev => ({\n ...prev,\n [fieldName]: value,\n }))\n }\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n\n if (!task) return\n\n // Validate required fields\n if (task.formSchema?.required) {\n for (const requiredField of task.formSchema.required) {\n if (!formData[requiredField] || formData[requiredField] === '') {\n flash(t('workflows.tasks.detail.validation.requiredField', { field: requiredField }), 'error')\n return\n }\n }\n }\n\n setSubmitting(true)\n\n try {\n const result = await apiCall(`/api/workflows/tasks/${params.id}/complete`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n formData,\n comments: comments || undefined,\n }),\n })\n\n if (result.ok) {\n flash(t('workflows.tasks.messages.completed'), 'success')\n router.push('/backend/tasks')\n } else {\n const error = result.result as any\n flash(error?.error || t('workflows.tasks.messages.completeFailed'), 'error')\n }\n } catch (err) {\n console.error('Error completing task:', err)\n flash(t('workflows.tasks.messages.completeFailed'), 'error')\n } finally {\n setSubmitting(false)\n }\n }\n\n const fieldValue = (fieldName: string): string | number => {\n const val = formData[fieldName]\n if (val == null || val === false) return ''\n if (typeof val === 'boolean') return ''\n return val\n }\n\n const renderFormField = (fieldName: string, fieldSchema: any) => {\n const fieldType = fieldSchema.type || 'string'\n const fieldTitle = fieldSchema.title || fieldName\n const fieldDescription = fieldSchema.description\n const required = task?.formSchema?.required?.includes(fieldName) || false\n const enumValues = fieldSchema.enum\n\n const inputClasses = \"w-full px-3 py-2 border border-border rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n const labelClasses = \"block text-sm font-medium text-foreground mb-1\"\n\n // Handle enum (select dropdown)\n if (enumValues && Array.isArray(enumValues)) {\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <select\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n className={inputClasses}\n >\n <option value=\"\">{t('workflows.tasks.detail.form.selectOption')}</option>\n {enumValues.map((value: any) => (\n <option key={value} value={value}>\n {value}\n </option>\n ))}\n </select>\n </div>\n )\n }\n\n // Handle different field types\n switch (fieldType) {\n case 'string':\n if (fieldSchema.format === 'email') {\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <input\n type=\"email\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n className={inputClasses}\n />\n </div>\n )\n }\n if (fieldSchema.format === 'date') {\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <input\n type=\"date\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n className={inputClasses}\n />\n </div>\n )\n }\n if (fieldSchema.maxLength && fieldSchema.maxLength > 200) {\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <textarea\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n rows={4}\n className={inputClasses}\n />\n </div>\n )\n }\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <input\n type=\"text\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n className={inputClasses}\n />\n </div>\n )\n\n case 'number':\n case 'integer':\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <input\n type=\"number\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value ? Number(e.target.value) : '')}\n required={required}\n step={fieldType === 'integer' ? 1 : 'any'}\n className={inputClasses}\n />\n </div>\n )\n\n case 'boolean':\n return (\n <div key={fieldName} className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id={fieldName}\n checked={!!formData[fieldName]}\n onChange={(e) => handleFieldChange(fieldName, e.target.checked)}\n className=\"w-4 h-4 text-primary border-border rounded focus-visible:ring-ring\"\n />\n <label htmlFor={fieldName} className=\"text-sm font-medium text-foreground\">\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n </div>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground ml-6\">{fieldDescription}</p>\n )}\n </div>\n )\n\n default:\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <input\n type=\"text\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n className={inputClasses}\n />\n </div>\n )\n }\n }\n\n const getStatusBadgeClass = (status: UserTaskStatus) => {\n switch (status) {\n case 'PENDING':\n return 'bg-status-warning-bg text-status-warning-text'\n case 'IN_PROGRESS':\n return 'bg-status-info-bg text-status-info-text'\n case 'COMPLETED':\n return 'bg-status-success-bg text-status-success-text'\n case 'CANCELLED':\n return 'bg-muted text-foreground'\n default:\n return 'bg-muted text-muted-foreground'\n }\n }\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex items-center justify-center py-12\">\n <Spinner />\n <span className=\"ml-3 text-muted-foreground\">{t('workflows.tasks.detail.loading')}</span>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n if (error || !task) {\n return (\n <Page>\n <PageBody>\n <div className=\"p-8 text-center\">\n <p className=\"text-status-error-text\">{t('workflows.tasks.detail.notFound')}</p>\n <Button onClick={() => router.push('/backend/tasks')} className=\"mt-4\">\n {t('workflows.tasks.detail.backToList')}\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n const isCompletable = task.status === 'PENDING' || task.status === 'IN_PROGRESS'\n const isOverdue = task.dueDate && new Date(task.dueDate) < new Date() && isCompletable\n\n if (isMobile) {\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-4\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/tasks\"\n backLabel={t('workflows.tasks.backToList', 'Back to tasks')}\n />\n <MobileTaskForm\n task={task}\n formData={formData}\n comments={comments}\n submitting={submitting}\n isCompletable={isCompletable}\n isOverdue={!!isOverdue}\n onFieldChange={handleFieldChange}\n onCommentsChange={setComments}\n onSubmit={handleSubmit}\n onCancel={() => router.push('/backend/tasks')}\n getStatusBadgeClass={getStatusBadgeClass}\n />\n </div>\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <div className=\"max-w-4xl mx-auto space-y-6\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/tasks\"\n backLabel={t('workflows.tasks.backToList', 'Back to tasks')}\n entityTypeLabel={t('workflows.tasks.detail.type', 'User task')}\n title={task.taskName}\n subtitle={task.description || undefined}\n statusBadge={\n <span\n className={`inline-flex items-center px-3 py-1 rounded text-sm font-medium ${getStatusBadgeClass(task.status)}`}\n >\n {t(`workflows.tasks.statuses.${task.status}`)}\n </span>\n }\n />\n\n <div className=\"space-y-3\">\n\n {isOverdue && (\n <div className=\"bg-status-error-bg border border-status-error-border rounded-lg p-3\">\n <p className=\"text-sm text-status-error-text font-medium\">\n {t('workflows.tasks.detail.overdueWarning')}\n </p>\n </div>\n )}\n </div>\n\n <Separator />\n\n {/* Task Information */}\n <div className=\"bg-muted/50 rounded-lg p-4 space-y-3\">\n <h2 className=\"text-sm font-semibold\">{t('workflows.tasks.detail.sections.taskInfo')}</h2>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.fields.createdAt')}:</span>\n <span className=\"ml-2 text-foreground\">{new Date(task.createdAt).toLocaleString()}</span>\n </div>\n {task.dueDate && (\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.fields.dueDate')}:</span>\n <span className={`ml-2 ${isOverdue ? 'text-status-error-text font-medium' : 'text-foreground'}`}>\n {new Date(task.dueDate).toLocaleString()}\n </span>\n </div>\n )}\n {task.assignedTo && (\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.detail.assignedTo')}:</span>\n <span className=\"ml-2 text-foreground\">{task.assignedTo}</span>\n </div>\n )}\n {task.claimedBy && (\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.claimedBy')}:</span>\n <span className=\"ml-2 text-foreground\">{task.claimedBy}</span>\n </div>\n )}\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.detail.workflowInstance')}:</span>\n <Link\n href={`/backend/instances/${task.workflowInstanceId}`}\n className=\"ml-2 text-primary hover:underline text-xs font-mono\"\n >\n {task.workflowInstanceId.slice(0, 8)}...\n </Link>\n </div>\n </div>\n </div>\n\n {!isCompletable && (\n <div className=\"bg-status-info-bg border border-status-info-border rounded-lg p-4\">\n <p className=\"text-sm text-status-info-text\">\n {t('workflows.tasks.detail.cannotComplete')}\n </p>\n </div>\n )}\n\n {isCompletable && (\n <>\n <Separator />\n\n {/* Dynamic Form */}\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {task.formSchema?.properties && (\n <div className=\"space-y-4\">\n <h2 className=\"text-lg font-semibold\">{t('workflows.tasks.detail.sections.form')}</h2>\n {Object.keys(task.formSchema!.properties!).map((fieldName) =>\n renderFormField(fieldName, task.formSchema!.properties![fieldName])\n )}\n </div>\n )}\n\n {!task.formSchema?.properties && (\n <div className=\"bg-status-info-bg border border-status-info-border rounded-lg p-4\">\n <p className=\"text-sm text-status-info-text\">\n {t('workflows.tasks.detail.noFormSchema')}\n </p>\n </div>\n )}\n\n <Separator />\n\n {/* Comments */}\n <div className=\"space-y-2\">\n <label htmlFor=\"comments\" className=\"block text-sm font-medium text-foreground\">\n {t('workflows.tasks.detail.comments')} ({t('workflows.tasks.detail.optional')})\n </label>\n <textarea\n id=\"comments\"\n value={comments}\n onChange={(e) => setComments(e.target.value)}\n rows={3}\n className=\"w-full px-3 py-2 border border-border rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n placeholder={t('workflows.tasks.detail.commentsPlaceholder')}\n />\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-3 pt-4 sm:flex-row sm:items-center\">\n <Button\n type=\"submit\"\n disabled={submitting}\n className=\"w-full sm:w-auto bg-primary text-primary-foreground hover:bg-primary/90\"\n >\n {submitting ? t('workflows.tasks.detail.submitting') : t('workflows.tasks.detail.completeTask')}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => router.push('/backend/tasks')}\n disabled={submitting}\n className=\"w-full sm:w-auto\"\n >\n {t('common.cancel')}\n </Button>\n </div>\n </form>\n </>\n )}\n\n {task.status === 'COMPLETED' && task.formData && (\n <>\n <Separator />\n <JsonDisplay\n data={task.formData}\n title={t('workflows.tasks.detail.sections.submittedData')}\n maxInitialDepth={2}\n />\n {task.comments && (\n <div className=\"bg-muted/50 rounded-lg p-4\">\n <p className=\"text-sm font-medium text-foreground mb-2\">{t('workflows.tasks.detail.comments')}:</p>\n <p className=\"text-sm text-muted-foreground whitespace-pre-wrap\">{task.comments}</p>\n </div>\n )}\n </>\n )}\n </div>\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
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 { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Separator } from '@open-mercato/ui/primitives/separator'\nimport { JsonDisplay } from '@open-mercato/ui/backend/JsonDisplay'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useQuery } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { MobileTaskForm } from '../../../components/mobile/MobileTaskForm'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport type { UserTaskResponse, UserTaskStatus } from '../../../data/types'\n\nexport default function UserTaskDetailPage({ params }: { params: { id: string } }) {\n const router = useRouter()\n const t = useT()\n const isMobile = useIsMobile()\n const [formData, setFormData] = React.useState<Record<string, string | number | boolean>>({})\n const [comments, setComments] = React.useState('')\n const [submitting, setSubmitting] = React.useState(false)\n // Tracks the first required field that failed validation so we can mark the\n // field with aria-invalid + a red ring (Radix Select can't carry HTML\n // `required`, so we enforce constraint validation in JS instead).\n const [invalidField, setInvalidField] = React.useState<string | null>(null)\n\n const { data: task, isLoading, error } = useQuery({\n queryKey: ['workflow-task', params.id],\n queryFn: async () => {\n const result = await apiCall<{ data: UserTaskResponse }>(\n `/api/workflows/tasks/${params.id}`\n )\n\n if (!result.ok) {\n throw new Error('Failed to fetch task')\n }\n\n return result.result?.data || null\n },\n })\n\n const handleFieldChange = (fieldName: string, value: any) => {\n setFormData(prev => ({\n ...prev,\n [fieldName]: value,\n }))\n // Clear invalid state once the user touches the offending field.\n if (invalidField === fieldName) setInvalidField(null)\n }\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n\n if (!task) return\n\n // Validate required fields. Radix Select doesn't expose HTML `required`,\n // so we enforce constraint validation here and surface it visually via\n // `invalidField` + aria-invalid on the offending field.\n if (task.formSchema?.required) {\n for (const requiredField of task.formSchema.required) {\n if (!formData[requiredField] || formData[requiredField] === '') {\n const fieldSchema = task.formSchema.properties?.[requiredField]\n const fieldLabel = fieldSchema?.title ?? requiredField\n flash(t('workflows.tasks.detail.validation.requiredField', { field: fieldLabel }), 'error')\n setInvalidField(requiredField)\n // Scroll + focus the trigger so the user sees what's missing.\n if (typeof document !== 'undefined') {\n const trigger = document.getElementById(requiredField)\n trigger?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n trigger?.focus()\n }\n return\n }\n }\n }\n setInvalidField(null)\n\n setSubmitting(true)\n\n try {\n const result = await apiCall(`/api/workflows/tasks/${params.id}/complete`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n formData,\n comments: comments || undefined,\n }),\n })\n\n if (result.ok) {\n flash(t('workflows.tasks.messages.completed'), 'success')\n router.push('/backend/tasks')\n } else {\n const error = result.result as any\n flash(error?.error || t('workflows.tasks.messages.completeFailed'), 'error')\n }\n } catch (err) {\n console.error('Error completing task:', err)\n flash(t('workflows.tasks.messages.completeFailed'), 'error')\n } finally {\n setSubmitting(false)\n }\n }\n\n const fieldValue = (fieldName: string): string | number => {\n const val = formData[fieldName]\n if (val == null || val === false) return ''\n if (typeof val === 'boolean') return ''\n return val\n }\n\n const renderFormField = (fieldName: string, fieldSchema: any) => {\n const fieldType = fieldSchema.type || 'string'\n const fieldTitle = fieldSchema.title || fieldName\n const fieldDescription = fieldSchema.description\n const required = task?.formSchema?.required?.includes(fieldName) || false\n const enumValues = fieldSchema.enum\n\n const inputClasses = \"w-full px-3 py-2 border border-border rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n const labelClasses = \"block text-sm font-medium text-foreground mb-1\"\n\n // Handle enum (select dropdown)\n if (enumValues && Array.isArray(enumValues)) {\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <Select\n value={fieldValue(fieldName) ? String(fieldValue(fieldName)) : undefined}\n onValueChange={(value) => handleFieldChange(fieldName, value ?? '')}\n >\n <SelectTrigger\n id={fieldName}\n className={`${inputClasses} ${invalidField === fieldName ? 'ring-2 ring-status-error-border border-status-error-border' : ''}`}\n aria-required={required}\n aria-invalid={invalidField === fieldName ? true : undefined}\n >\n <SelectValue placeholder={t('workflows.tasks.detail.form.selectOption')} />\n </SelectTrigger>\n <SelectContent>\n {enumValues.map((value: any) => (\n <SelectItem key={value} value={value}>\n {value}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )\n }\n\n // Handle different field types\n switch (fieldType) {\n case 'string':\n if (fieldSchema.format === 'email') {\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <Input\n type=\"email\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n />\n </div>\n )\n }\n if (fieldSchema.format === 'date') {\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <input\n type=\"date\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n className={inputClasses}\n />\n </div>\n )\n }\n if (fieldSchema.maxLength && fieldSchema.maxLength > 200) {\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <textarea\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n rows={4}\n className={inputClasses}\n />\n </div>\n )\n }\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <Input\n type=\"text\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n />\n </div>\n )\n\n case 'number':\n case 'integer':\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <Input\n type=\"number\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value ? Number(e.target.value) : '')}\n required={required}\n step={fieldType === 'integer' ? 1 : 'any'}\n />\n </div>\n )\n\n case 'boolean':\n return (\n <div key={fieldName} className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id={fieldName}\n checked={!!formData[fieldName]}\n onChange={(e) => handleFieldChange(fieldName, e.target.checked)}\n className=\"w-4 h-4 text-primary border-border rounded focus-visible:ring-ring\"\n />\n <label htmlFor={fieldName} className=\"text-sm font-medium text-foreground\">\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n </div>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground ml-6\">{fieldDescription}</p>\n )}\n </div>\n )\n\n default:\n return (\n <div key={fieldName} className=\"space-y-2\">\n <label htmlFor={fieldName} className={labelClasses}>\n {fieldTitle}\n {required && <span className=\"text-status-error-text ml-1\">*</span>}\n </label>\n {fieldDescription && (\n <p className=\"text-xs text-muted-foreground\">{fieldDescription}</p>\n )}\n <Input\n type=\"text\"\n id={fieldName}\n value={fieldValue(fieldName)}\n onChange={(e) => handleFieldChange(fieldName, e.target.value)}\n required={required}\n />\n </div>\n )\n }\n }\n\n const getStatusBadgeClass = (status: UserTaskStatus) => {\n switch (status) {\n case 'PENDING':\n return 'bg-status-warning-bg text-status-warning-text'\n case 'IN_PROGRESS':\n return 'bg-status-info-bg text-status-info-text'\n case 'COMPLETED':\n return 'bg-status-success-bg text-status-success-text'\n case 'CANCELLED':\n return 'bg-muted text-foreground'\n default:\n return 'bg-muted text-muted-foreground'\n }\n }\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex items-center justify-center py-12\">\n <Spinner />\n <span className=\"ml-3 text-muted-foreground\">{t('workflows.tasks.detail.loading')}</span>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n if (error || !task) {\n return (\n <Page>\n <PageBody>\n <div className=\"p-8 text-center\">\n <p className=\"text-status-error-text\">{t('workflows.tasks.detail.notFound')}</p>\n <Button onClick={() => router.push('/backend/tasks')} className=\"mt-4\">\n {t('workflows.tasks.detail.backToList')}\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n }\n\n const isCompletable = task.status === 'PENDING' || task.status === 'IN_PROGRESS'\n const isOverdue = task.dueDate && new Date(task.dueDate) < new Date() && isCompletable\n\n if (isMobile) {\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-4\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/tasks\"\n backLabel={t('workflows.tasks.backToList', 'Back to tasks')}\n />\n <MobileTaskForm\n task={task}\n formData={formData}\n comments={comments}\n submitting={submitting}\n isCompletable={isCompletable}\n isOverdue={!!isOverdue}\n onFieldChange={handleFieldChange}\n onCommentsChange={setComments}\n onSubmit={handleSubmit}\n onCancel={() => router.push('/backend/tasks')}\n getStatusBadgeClass={getStatusBadgeClass}\n />\n </div>\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <div className=\"max-w-4xl mx-auto space-y-6\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/tasks\"\n backLabel={t('workflows.tasks.backToList', 'Back to tasks')}\n entityTypeLabel={t('workflows.tasks.detail.type', 'User task')}\n title={task.taskName}\n subtitle={task.description || undefined}\n statusBadge={\n <span\n className={`inline-flex items-center px-3 py-1 rounded text-sm font-medium ${getStatusBadgeClass(task.status)}`}\n >\n {t(`workflows.tasks.statuses.${task.status}`)}\n </span>\n }\n />\n\n <div className=\"space-y-3\">\n\n {isOverdue && (\n <div className=\"bg-status-error-bg border border-status-error-border rounded-lg p-3\">\n <p className=\"text-sm text-status-error-text font-medium\">\n {t('workflows.tasks.detail.overdueWarning')}\n </p>\n </div>\n )}\n </div>\n\n <Separator />\n\n {/* Task Information */}\n <div className=\"bg-muted/50 rounded-lg p-4 space-y-3\">\n <h2 className=\"text-sm font-semibold\">{t('workflows.tasks.detail.sections.taskInfo')}</h2>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.fields.createdAt')}:</span>\n <span className=\"ml-2 text-foreground\">{new Date(task.createdAt).toLocaleString()}</span>\n </div>\n {task.dueDate && (\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.fields.dueDate')}:</span>\n <span className={`ml-2 ${isOverdue ? 'text-status-error-text font-medium' : 'text-foreground'}`}>\n {new Date(task.dueDate).toLocaleString()}\n </span>\n </div>\n )}\n {task.assignedTo && (\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.detail.assignedTo')}:</span>\n <span className=\"ml-2 text-foreground\">{task.assignedTo}</span>\n </div>\n )}\n {task.claimedBy && (\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.claimedBy')}:</span>\n <span className=\"ml-2 text-foreground\">{task.claimedBy}</span>\n </div>\n )}\n <div>\n <span className=\"text-muted-foreground\">{t('workflows.tasks.detail.workflowInstance')}:</span>\n <Link\n href={`/backend/instances/${task.workflowInstanceId}`}\n className=\"ml-2 text-primary hover:underline text-xs font-mono\"\n >\n {task.workflowInstanceId.slice(0, 8)}...\n </Link>\n </div>\n </div>\n </div>\n\n {!isCompletable && (\n <div className=\"bg-status-info-bg border border-status-info-border rounded-lg p-4\">\n <p className=\"text-sm text-status-info-text\">\n {t('workflows.tasks.detail.cannotComplete')}\n </p>\n </div>\n )}\n\n {isCompletable && (\n <>\n <Separator />\n\n {/* Dynamic Form */}\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {task.formSchema?.properties && (\n <div className=\"space-y-4\">\n <h2 className=\"text-lg font-semibold\">{t('workflows.tasks.detail.sections.form')}</h2>\n {Object.keys(task.formSchema!.properties!).map((fieldName) =>\n renderFormField(fieldName, task.formSchema!.properties![fieldName])\n )}\n </div>\n )}\n\n {!task.formSchema?.properties && (\n <div className=\"bg-status-info-bg border border-status-info-border rounded-lg p-4\">\n <p className=\"text-sm text-status-info-text\">\n {t('workflows.tasks.detail.noFormSchema')}\n </p>\n </div>\n )}\n\n <Separator />\n\n {/* Comments */}\n <div className=\"space-y-2\">\n <label htmlFor=\"comments\" className=\"block text-sm font-medium text-foreground\">\n {t('workflows.tasks.detail.comments')} ({t('workflows.tasks.detail.optional')})\n </label>\n <textarea\n id=\"comments\"\n value={comments}\n onChange={(e) => setComments(e.target.value)}\n rows={3}\n className=\"w-full px-3 py-2 border border-border rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n placeholder={t('workflows.tasks.detail.commentsPlaceholder')}\n />\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-3 pt-4 sm:flex-row sm:items-center\">\n <Button\n type=\"submit\"\n disabled={submitting}\n className=\"w-full sm:w-auto bg-primary text-primary-foreground hover:bg-primary/90\"\n >\n {submitting ? t('workflows.tasks.detail.submitting') : t('workflows.tasks.detail.completeTask')}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => router.push('/backend/tasks')}\n disabled={submitting}\n className=\"w-full sm:w-auto\"\n >\n {t('common.cancel')}\n </Button>\n </div>\n </form>\n </>\n )}\n\n {task.status === 'COMPLETED' && task.formData && (\n <>\n <Separator />\n <JsonDisplay\n data={task.formData}\n title={t('workflows.tasks.detail.sections.submittedData')}\n maxInitialDepth={2}\n />\n {task.comments && (\n <div className=\"bg-muted/50 rounded-lg p-4\">\n <p className=\"text-sm font-medium text-foreground mb-2\">{t('workflows.tasks.detail.comments')}:</p>\n <p className=\"text-sm text-muted-foreground whitespace-pre-wrap\">{task.comments}</p>\n </div>\n )}\n </>\n )}\n </div>\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["error"]
|
|
7
7
|
}
|
|
@@ -3,6 +3,13 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
4
4
|
import { Input } from "@open-mercato/ui/primitives/input";
|
|
5
5
|
import { Label } from "@open-mercato/ui/primitives/label";
|
|
6
|
+
import {
|
|
7
|
+
Select,
|
|
8
|
+
SelectContent,
|
|
9
|
+
SelectItem,
|
|
10
|
+
SelectTrigger,
|
|
11
|
+
SelectValue
|
|
12
|
+
} from "@open-mercato/ui/primitives/select";
|
|
6
13
|
import { Textarea } from "@open-mercato/ui/primitives/textarea";
|
|
7
14
|
import { Trash2, Plus, ChevronUp, ChevronDown } from "lucide-react";
|
|
8
15
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
@@ -152,14 +159,15 @@ function ActivitiesEditor({ value = [], onChange, error }) {
|
|
|
152
159
|
t("workflows.activities.activityType"),
|
|
153
160
|
" *"
|
|
154
161
|
] }),
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
|
|
162
|
+
/* @__PURE__ */ jsxs(
|
|
163
|
+
Select,
|
|
157
164
|
{
|
|
158
|
-
id: `activity-${index}-type`,
|
|
159
165
|
value: activity.activityType,
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
166
|
+
onValueChange: (value2) => updateActivity(index, "activityType", value2),
|
|
167
|
+
children: [
|
|
168
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id: `activity-${index}-type`, className: "mt-1", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
169
|
+
/* @__PURE__ */ jsx(SelectContent, { children: ACTIVITY_TYPES.map((type) => /* @__PURE__ */ jsx(SelectItem, { value: type.value, children: t(`workflows.activities.types.${type.value}`) }, type.value)) })
|
|
170
|
+
]
|
|
163
171
|
}
|
|
164
172
|
)
|
|
165
173
|
] }),
|