@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
|
@@ -4,13 +4,12 @@ import { useState, useEffect } from "react";
|
|
|
4
4
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
5
5
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
6
6
|
import { Badge } from "@open-mercato/ui/primitives/badge";
|
|
7
|
-
import { Label } from "@open-mercato/ui/primitives/label";
|
|
8
7
|
import { Plus, Trash2, AlertCircle } from "lucide-react";
|
|
9
8
|
import { BusinessRulesSelector } from "../BusinessRulesSelector.js";
|
|
10
9
|
import { apiFetch } from "@open-mercato/ui/backend/utils/api";
|
|
11
10
|
import { EmptyState } from "@open-mercato/ui/backend/EmptyState";
|
|
12
11
|
import { Spinner } from "@open-mercato/ui/primitives/spinner";
|
|
13
|
-
import {
|
|
12
|
+
import { SwitchField } from "@open-mercato/ui/primitives/switch-field";
|
|
14
13
|
import { ConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
|
|
15
14
|
function normalizeCondition(raw) {
|
|
16
15
|
if (typeof raw === "string") {
|
|
@@ -154,18 +153,17 @@ function BusinessRuleConditionsEditor({
|
|
|
154
153
|
/* @__PURE__ */ jsx("code", { className: "bg-muted px-1 rounded font-mono", children: condition.ruleId })
|
|
155
154
|
] })
|
|
156
155
|
] }) }),
|
|
157
|
-
/* @__PURE__ */
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
{
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
] })
|
|
156
|
+
/* @__PURE__ */ jsx(
|
|
157
|
+
SwitchField,
|
|
158
|
+
{
|
|
159
|
+
id: `${id}-${index}-required`,
|
|
160
|
+
label: t("workflows.fieldEditors.businessRuleConditions.requiredLabel"),
|
|
161
|
+
flip: true,
|
|
162
|
+
checked: normalized.required,
|
|
163
|
+
onCheckedChange: () => toggleRequired(index),
|
|
164
|
+
disabled
|
|
165
|
+
}
|
|
166
|
+
)
|
|
169
167
|
] }),
|
|
170
168
|
/* @__PURE__ */ jsx(
|
|
171
169
|
ConfirmDialog,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport { useState, useEffect } from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Plus, Trash2, AlertCircle } from 'lucide-react'\nimport type { CrudCustomFieldRenderProps } from '@open-mercato/ui/backend/CrudForm'\nimport { BusinessRulesSelector, type BusinessRule } from '../BusinessRulesSelector'\nimport { apiFetch } from '@open-mercato/ui/backend/utils/api'\nimport { EmptyState } from '@open-mercato/ui/backend/EmptyState'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport { ConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\n/**\n * Condition definition structure (supports legacy string format and new object format)\n */\nexport type TransitionCondition = string | { ruleId: string; required: boolean }\n\ninterface BusinessRuleConditionsEditorProps extends CrudCustomFieldRenderProps {\n value: TransitionCondition[]\n filterEntityType?: string\n filterRuleType?: string\n}\n\ninterface ConditionWithDetails {\n ruleId: string\n required: boolean\n ruleName?: string\n ruleType?: string\n loading?: boolean\n error?: boolean\n}\n\n/**\n * Normalize legacy string format to object format\n */\nfunction normalizeCondition(raw: TransitionCondition): { ruleId: string; required: boolean } {\n if (typeof raw === 'string') {\n return { ruleId: raw, required: true }\n }\n return raw\n}\n\n/**\n * BusinessRuleConditionsEditor - Custom field component for managing pre/post business rule conditions\n *\n * Integrates with BusinessRulesSelector modal to add/remove conditions.\n * Fetches and displays rule names for selected rule IDs.\n * Supports both legacy string format and new object format with required flag.\n *\n * Used by EdgeEditDialog (pre-conditions and post-conditions)\n */\nexport function BusinessRuleConditionsEditor({\n id,\n value = [],\n setValue,\n disabled,\n filterEntityType,\n filterRuleType,\n}: BusinessRuleConditionsEditorProps) {\n const t = useT()\n const [isModalOpen, setIsModalOpen] = useState(false)\n const [conditionsWithDetails, setConditionsWithDetails] = useState<ConditionWithDetails[]>([])\n\n const conditions = Array.isArray(value) ? value : []\n\n // Fetch rule details when conditions change\n useEffect(() => {\n const normalized = conditions.map(normalizeCondition)\n const withDetails: ConditionWithDetails[] = normalized.map((c) => ({\n ...c,\n loading: true,\n }))\n setConditionsWithDetails(withDetails)\n\n // Fetch details for each rule\n normalized.forEach((condition, index) => {\n fetchRuleDetails(condition.ruleId, index)\n })\n }, [JSON.stringify(conditions.map(normalizeCondition))])\n\n const fetchRuleDetails = async (ruleId: string, index: number) => {\n try {\n const params = new URLSearchParams({ ruleId, pageSize: '1' })\n const response = await apiFetch(`/api/business_rules/rules?${params.toString()}`)\n\n if (response.ok) {\n const data = await response.json()\n const rule = data.items?.[0] as BusinessRule | undefined\n\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: rule?.ruleName || ruleId,\n ruleType: rule?.ruleType,\n loading: false,\n error: !rule,\n }\n }\n return updated\n })\n } else {\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: ruleId,\n loading: false,\n error: true,\n }\n }\n return updated\n })\n }\n } catch (err) {\n console.error(`Failed to fetch rule details for ${ruleId}:`, err)\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: ruleId,\n loading: false,\n error: true,\n }\n }\n return updated\n })\n }\n }\n\n const addCondition = (ruleId: string, _rule: BusinessRule) => {\n const newCondition: TransitionCondition = { ruleId, required: true }\n setValue([...conditions, newCondition])\n setIsModalOpen(false)\n }\n\n const removeCondition = (index: number) => {\n const newConditions = conditions.filter((_, i) => i !== index)\n setValue(newConditions)\n }\n\n const toggleRequired = (index: number) => {\n const normalized = normalizeCondition(conditions[index])\n const updated = [...conditions]\n updated[index] = {\n ruleId: normalized.ruleId,\n required: !normalized.required,\n }\n setValue(updated)\n }\n\n const getExcludedRuleIds = (): string[] => {\n return conditions.map((c) => normalizeCondition(c).ruleId)\n }\n\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-end\">\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => setIsModalOpen(true)}\n disabled={disabled}\n >\n <Plus className=\"size-3 mr-1\" />\n {t('workflows.fieldEditors.businessRuleConditions.addRule')}\n </Button>\n </div>\n\n {conditions.length === 0 ? (\n <EmptyState\n title={t('workflows.fieldEditors.businessRuleConditions.emptyTitle')}\n description={t('workflows.fieldEditors.businessRuleConditions.emptyDescription')}\n action={{ label: t('workflows.fieldEditors.businessRuleConditions.addRule'), onClick: () => setIsModalOpen(true), disabled }}\n />\n ) : (\n <div className=\"space-y-2\">\n {conditionsWithDetails.map((condition, index) => {\n const normalized = normalizeCondition(conditions[index])\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-white p-4\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex-1 min-w-0 space-y-2\">\n {/* Rule Name/ID */}\n <div className=\"flex items-center gap-2\">\n {condition.loading ? (\n <>\n <Spinner size=\"sm\" />\n <span className=\"text-sm text-muted-foreground\">{t('workflows.common.loadingDetails')}</span>\n </>\n ) : condition.error ? (\n <>\n <AlertCircle className=\"size-4 text-amber-600\" />\n <div>\n <span className=\"text-sm font-semibold text-foreground\">{condition.ruleId}</span>\n <p className=\"text-xs text-amber-600\">{t('workflows.common.ruleNotFound')}</p>\n </div>\n </>\n ) : (\n <div>\n <span className=\"text-sm font-semibold text-foreground\">{condition.ruleName}</span>\n {condition.ruleType && (\n <Badge variant=\"secondary\" className=\"text-xs ml-2\">\n {condition.ruleType}\n </Badge>\n )}\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n ID: <code className=\"bg-muted px-1 rounded font-mono\">{condition.ruleId}</code>\n </p>\n </div>\n )}\n </div>\n\n {/* Required Toggle */}\n <div className=\"flex items-center gap-2\">\n <Switch\n id={`${id}-${index}-required`}\n checked={normalized.required}\n onCheckedChange={() => toggleRequired(index)}\n disabled={disabled}\n />\n <Label htmlFor={`${id}-${index}-required`} className=\"text-xs font-medium cursor-pointer\">\n {t('workflows.fieldEditors.businessRuleConditions.requiredLabel')}\n </Label>\n </div>\n </div>\n\n {/* Delete Button */}\n <ConfirmDialog\n trigger={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={disabled}\n className=\"ml-2 flex-shrink-0\"\n >\n <Trash2 className=\"size-4 text-red-600\" />\n </Button>\n }\n title={t('workflows.fieldEditors.businessRuleConditions.removeCondition')}\n text={t('workflows.fieldEditors.businessRuleConditions.confirmRemove')}\n variant=\"destructive\"\n onConfirm={() => removeCondition(index)}\n />\n </div>\n </div>\n )\n })}\n </div>\n )}\n\n {/* Business Rules Selector Modal */}\n <BusinessRulesSelector\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n onSelect={addCondition}\n excludeRuleIds={getExcludedRuleIds()}\n title={t('workflows.fieldEditors.businessRuleConditions.selectBusinessRule')}\n description={t('workflows.fieldEditors.businessRuleConditions.selectBusinessRuleDescription')}\n filterEntityType={filterEntityType}\n filterRuleType={filterRuleType}\n onlyEnabled={true}\n />\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport { useState, useEffect } from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Plus, Trash2, AlertCircle } from 'lucide-react'\nimport type { CrudCustomFieldRenderProps } from '@open-mercato/ui/backend/CrudForm'\nimport { BusinessRulesSelector, type BusinessRule } from '../BusinessRulesSelector'\nimport { apiFetch } from '@open-mercato/ui/backend/utils/api'\nimport { EmptyState } from '@open-mercato/ui/backend/EmptyState'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { SwitchField } from '@open-mercato/ui/primitives/switch-field'\nimport { ConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\n/**\n * Condition definition structure (supports legacy string format and new object format)\n */\nexport type TransitionCondition = string | { ruleId: string; required: boolean }\n\ninterface BusinessRuleConditionsEditorProps extends CrudCustomFieldRenderProps {\n value: TransitionCondition[]\n filterEntityType?: string\n filterRuleType?: string\n}\n\ninterface ConditionWithDetails {\n ruleId: string\n required: boolean\n ruleName?: string\n ruleType?: string\n loading?: boolean\n error?: boolean\n}\n\n/**\n * Normalize legacy string format to object format\n */\nfunction normalizeCondition(raw: TransitionCondition): { ruleId: string; required: boolean } {\n if (typeof raw === 'string') {\n return { ruleId: raw, required: true }\n }\n return raw\n}\n\n/**\n * BusinessRuleConditionsEditor - Custom field component for managing pre/post business rule conditions\n *\n * Integrates with BusinessRulesSelector modal to add/remove conditions.\n * Fetches and displays rule names for selected rule IDs.\n * Supports both legacy string format and new object format with required flag.\n *\n * Used by EdgeEditDialog (pre-conditions and post-conditions)\n */\nexport function BusinessRuleConditionsEditor({\n id,\n value = [],\n setValue,\n disabled,\n filterEntityType,\n filterRuleType,\n}: BusinessRuleConditionsEditorProps) {\n const t = useT()\n const [isModalOpen, setIsModalOpen] = useState(false)\n const [conditionsWithDetails, setConditionsWithDetails] = useState<ConditionWithDetails[]>([])\n\n const conditions = Array.isArray(value) ? value : []\n\n // Fetch rule details when conditions change\n useEffect(() => {\n const normalized = conditions.map(normalizeCondition)\n const withDetails: ConditionWithDetails[] = normalized.map((c) => ({\n ...c,\n loading: true,\n }))\n setConditionsWithDetails(withDetails)\n\n // Fetch details for each rule\n normalized.forEach((condition, index) => {\n fetchRuleDetails(condition.ruleId, index)\n })\n }, [JSON.stringify(conditions.map(normalizeCondition))])\n\n const fetchRuleDetails = async (ruleId: string, index: number) => {\n try {\n const params = new URLSearchParams({ ruleId, pageSize: '1' })\n const response = await apiFetch(`/api/business_rules/rules?${params.toString()}`)\n\n if (response.ok) {\n const data = await response.json()\n const rule = data.items?.[0] as BusinessRule | undefined\n\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: rule?.ruleName || ruleId,\n ruleType: rule?.ruleType,\n loading: false,\n error: !rule,\n }\n }\n return updated\n })\n } else {\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: ruleId,\n loading: false,\n error: true,\n }\n }\n return updated\n })\n }\n } catch (err) {\n console.error(`Failed to fetch rule details for ${ruleId}:`, err)\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: ruleId,\n loading: false,\n error: true,\n }\n }\n return updated\n })\n }\n }\n\n const addCondition = (ruleId: string, _rule: BusinessRule) => {\n const newCondition: TransitionCondition = { ruleId, required: true }\n setValue([...conditions, newCondition])\n setIsModalOpen(false)\n }\n\n const removeCondition = (index: number) => {\n const newConditions = conditions.filter((_, i) => i !== index)\n setValue(newConditions)\n }\n\n const toggleRequired = (index: number) => {\n const normalized = normalizeCondition(conditions[index])\n const updated = [...conditions]\n updated[index] = {\n ruleId: normalized.ruleId,\n required: !normalized.required,\n }\n setValue(updated)\n }\n\n const getExcludedRuleIds = (): string[] => {\n return conditions.map((c) => normalizeCondition(c).ruleId)\n }\n\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-end\">\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => setIsModalOpen(true)}\n disabled={disabled}\n >\n <Plus className=\"size-3 mr-1\" />\n {t('workflows.fieldEditors.businessRuleConditions.addRule')}\n </Button>\n </div>\n\n {conditions.length === 0 ? (\n <EmptyState\n title={t('workflows.fieldEditors.businessRuleConditions.emptyTitle')}\n description={t('workflows.fieldEditors.businessRuleConditions.emptyDescription')}\n action={{ label: t('workflows.fieldEditors.businessRuleConditions.addRule'), onClick: () => setIsModalOpen(true), disabled }}\n />\n ) : (\n <div className=\"space-y-2\">\n {conditionsWithDetails.map((condition, index) => {\n const normalized = normalizeCondition(conditions[index])\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-white p-4\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex-1 min-w-0 space-y-2\">\n {/* Rule Name/ID */}\n <div className=\"flex items-center gap-2\">\n {condition.loading ? (\n <>\n <Spinner size=\"sm\" />\n <span className=\"text-sm text-muted-foreground\">{t('workflows.common.loadingDetails')}</span>\n </>\n ) : condition.error ? (\n <>\n <AlertCircle className=\"size-4 text-amber-600\" />\n <div>\n <span className=\"text-sm font-semibold text-foreground\">{condition.ruleId}</span>\n <p className=\"text-xs text-amber-600\">{t('workflows.common.ruleNotFound')}</p>\n </div>\n </>\n ) : (\n <div>\n <span className=\"text-sm font-semibold text-foreground\">{condition.ruleName}</span>\n {condition.ruleType && (\n <Badge variant=\"secondary\" className=\"text-xs ml-2\">\n {condition.ruleType}\n </Badge>\n )}\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n ID: <code className=\"bg-muted px-1 rounded font-mono\">{condition.ruleId}</code>\n </p>\n </div>\n )}\n </div>\n\n {/* Required Toggle */}\n <SwitchField\n id={`${id}-${index}-required`}\n label={t('workflows.fieldEditors.businessRuleConditions.requiredLabel')}\n flip\n checked={normalized.required}\n onCheckedChange={() => toggleRequired(index)}\n disabled={disabled}\n />\n </div>\n\n {/* Delete Button */}\n <ConfirmDialog\n trigger={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={disabled}\n className=\"ml-2 flex-shrink-0\"\n >\n <Trash2 className=\"size-4 text-red-600\" />\n </Button>\n }\n title={t('workflows.fieldEditors.businessRuleConditions.removeCondition')}\n text={t('workflows.fieldEditors.businessRuleConditions.confirmRemove')}\n variant=\"destructive\"\n onConfirm={() => removeCondition(index)}\n />\n </div>\n </div>\n )\n })}\n </div>\n )}\n\n {/* Business Rules Selector Modal */}\n <BusinessRulesSelector\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n onSelect={addCondition}\n excludeRuleIds={getExcludedRuleIds()}\n title={t('workflows.fieldEditors.businessRuleConditions.selectBusinessRule')}\n description={t('workflows.fieldEditors.businessRuleConditions.selectBusinessRuleDescription')}\n filterEntityType={filterEntityType}\n filterRuleType={filterRuleType}\n onlyEnabled={true}\n />\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,6 +7,13 @@ import { Button } from "@open-mercato/ui/primitives/button";
|
|
|
7
7
|
import { Badge } from "@open-mercato/ui/primitives/badge";
|
|
8
8
|
import { Input } from "@open-mercato/ui/primitives/input";
|
|
9
9
|
import { Label } from "@open-mercato/ui/primitives/label";
|
|
10
|
+
import {
|
|
11
|
+
Select,
|
|
12
|
+
SelectContent,
|
|
13
|
+
SelectItem,
|
|
14
|
+
SelectTrigger,
|
|
15
|
+
SelectValue
|
|
16
|
+
} from "@open-mercato/ui/primitives/select";
|
|
10
17
|
import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
|
|
11
18
|
import { ChevronDown, Plus, Trash2, Info } from "lucide-react";
|
|
12
19
|
function FormFieldArrayEditor({
|
|
@@ -169,26 +176,27 @@ function FormFieldArrayEditor({
|
|
|
169
176
|
" *"
|
|
170
177
|
] }),
|
|
171
178
|
/* @__PURE__ */ jsxs(
|
|
172
|
-
|
|
179
|
+
Select,
|
|
173
180
|
{
|
|
174
|
-
id: `${id}-${index}-type`,
|
|
175
181
|
value: field.type,
|
|
176
|
-
|
|
177
|
-
className: "flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-xs shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
182
|
+
onValueChange: (value2) => updateFormField(index, "type", value2),
|
|
178
183
|
disabled,
|
|
179
184
|
children: [
|
|
180
|
-
/* @__PURE__ */ jsx(
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
185
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id: `${id}-${index}-type`, children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
186
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
187
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "text", children: t("workflows.form.fieldTypes.text") }),
|
|
188
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "number", children: t("workflows.form.fieldTypes.number") }),
|
|
189
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "email", children: t("workflows.form.fieldTypes.email") }),
|
|
190
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "tel", children: t("workflows.form.fieldTypes.tel") }),
|
|
191
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "url", children: t("workflows.form.fieldTypes.url") }),
|
|
192
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "textarea", children: t("workflows.form.fieldTypes.textarea") }),
|
|
193
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "select", children: t("workflows.form.fieldTypes.select") }),
|
|
194
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "radio", children: t("workflows.form.fieldTypes.radio") }),
|
|
195
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "checkbox", children: t("workflows.form.fieldTypes.checkbox") }),
|
|
196
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "date", children: t("workflows.form.fieldTypes.date") }),
|
|
197
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "time", children: t("workflows.form.fieldTypes.time") }),
|
|
198
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "datetime-local", children: t("workflows.form.fieldTypes.datetime-local") })
|
|
199
|
+
] })
|
|
192
200
|
]
|
|
193
201
|
}
|
|
194
202
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/workflows/components/fields/FormFieldArrayEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport { useState } from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { ChevronDown, Plus, Trash2, Info } from 'lucide-react'\nimport type { CrudCustomFieldRenderProps } from '@open-mercato/ui/backend/CrudForm'\n\n/**\n * Form field definition structure\n */\nexport interface FormField {\n name: string\n type: string\n label: string\n required: boolean\n placeholder?: string\n options?: string[]\n defaultValue?: string\n}\n\ninterface FormFieldArrayEditorProps extends CrudCustomFieldRenderProps {\n value: FormField[]\n isJsonSchemaFormat?: boolean\n}\n\n/**\n * FormFieldArrayEditor - Custom field component for managing UserTask form fields\n *\n * Provides an interface to add, edit, and remove form field definitions for user tasks.\n * Supports 12 field types with conditional options for select/radio types.\n *\n * Displays a warning banner if the form was converted from JSON Schema format.\n *\n * Used by NodeEditDialog (UserTask type only)\n */\nexport function FormFieldArrayEditor({\n id,\n value = [],\n error,\n setValue,\n disabled,\n isJsonSchemaFormat = false,\n}: FormFieldArrayEditorProps) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [expandedIndices, setExpandedIndices] = useState<Set<number>>(new Set())\n\n const formFields = Array.isArray(value) ? value : []\n\n const toggleExpanded = (index: number) => {\n const newExpanded = new Set(expandedIndices)\n if (newExpanded.has(index)) {\n newExpanded.delete(index)\n } else {\n newExpanded.add(index)\n }\n setExpandedIndices(newExpanded)\n }\n\n const addFormField = () => {\n const newField: FormField = {\n name: `field_${Date.now()}`,\n type: 'text',\n label: t('workflows.form.newField'),\n required: false,\n placeholder: '',\n }\n const newFields = [...formFields, newField]\n setValue(newFields)\n\n // Auto-expand the newly added field\n const newExpanded = new Set(expandedIndices)\n newExpanded.add(formFields.length)\n setExpandedIndices(newExpanded)\n }\n\n const removeFormField = async (index: number) => {\n const confirmed = await confirm({\n title: t('workflows.fieldEditors.formFields.removeField'),\n text: t('workflows.fieldEditors.formFields.confirmRemove'),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n const newFields = formFields.filter((_, i) => i !== index)\n setValue(newFields)\n\n // Remove from expanded set\n const newExpanded = new Set(expandedIndices)\n newExpanded.delete(index)\n setExpandedIndices(newExpanded)\n }\n\n const updateFormField = (index: number, fieldKey: keyof FormField, fieldValue: any) => {\n const updated = [...formFields]\n updated[index] = { ...updated[index], [fieldKey]: fieldValue }\n setValue(updated)\n }\n\n return (\n <div className=\"space-y-3\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <Label className=\"text-sm font-semibold\">{t('workflows.fieldEditors.formFields.title')} ({formFields.length})</Label>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {t('workflows.fieldEditors.formFields.description')}\n </p>\n {error && <p className=\"text-xs text-red-600 mt-1\">{error}</p>}\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={addFormField}\n disabled={disabled}\n className=\"w-full sm:w-auto\"\n >\n <Plus className=\"size-3 mr-1\" />\n {t('workflows.fieldEditors.formFields.addField')}\n </Button>\n </div>\n\n {/* JSON Schema Format Notice */}\n {isJsonSchemaFormat && (\n <Alert variant=\"default\" className=\"border-blue-200 bg-blue-50\">\n <Info className=\"size-4\" />\n <AlertDescription className=\"text-xs\">\n {t('workflows.fieldEditors.formFields.jsonSchemaNotice')}\n </AlertDescription>\n </Alert>\n )}\n\n {formFields.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-muted-foreground bg-muted rounded-lg border\">\n {t('workflows.fieldEditors.formFields.emptyState')}\n </div>\n ) : (\n <div className=\"space-y-2\">\n {formFields.map((field, index) => {\n const isExpanded = expandedIndices.has(index)\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-gray-50\">\n {/* Collapsed Header */}\n <button\n type=\"button\"\n onClick={() => toggleExpanded(index)}\n disabled={disabled}\n className=\"w-full px-4 py-3 text-left flex items-center justify-between hover:bg-gray-100 transition-colors rounded-t-lg disabled:opacity-50\"\n >\n <div className=\"flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-900\">\n {field.label || field.name}\n </span>\n <Badge variant=\"secondary\" className=\"text-xs\">\n {field.type}\n </Badge>\n {field.required && (\n <Badge variant=\"destructive\" className=\"text-xs text-white\">\n {t('workflows.form.required')}\n </Badge>\n )}\n </div>\n <p className=\"text-xs text-gray-600 mt-1\">\n Field name: <code className=\"bg-white px-1 rounded\">{field.name}</code>\n </p>\n </div>\n <ChevronDown\n className={`w-5 h-5 text-gray-400 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n />\n </button>\n\n {/* Expanded Content */}\n {isExpanded && (\n <div className=\"px-4 pb-4 space-y-3 border-t border-gray-200 bg-white\">\n {/* Field Name */}\n <div className=\"pt-3\">\n <Label htmlFor={`${id}-${index}-name`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.fieldName')} *\n </Label>\n <Input\n id={`${id}-${index}-name`}\n type=\"text\"\n value={field.name}\n onChange={(e) => updateFormField(index, 'name', e.target.value)}\n placeholder={t('workflows.fieldEditors.formFields.fieldNamePlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n <p className=\"text-xs text-muted-foreground mt-0.5\">{t('workflows.fieldEditors.formFields.fieldNameHint')}</p>\n </div>\n\n {/* Field Label */}\n <div>\n <Label htmlFor={`${id}-${index}-label`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.fieldLabel')} *\n </Label>\n <Input\n id={`${id}-${index}-label`}\n type=\"text\"\n value={field.label}\n onChange={(e) => updateFormField(index, 'label', e.target.value)}\n placeholder={t('workflows.fieldEditors.formFields.fieldLabelPlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n <p className=\"text-xs text-muted-foreground mt-0.5\">{t('workflows.fieldEditors.formFields.fieldLabelHint')}</p>\n </div>\n\n {/* Field Type */}\n <div>\n <Label htmlFor={`${id}-${index}-type`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.fieldType')} *\n </Label>\n <select\n id={`${id}-${index}-type`}\n value={field.type}\n onChange={(e) => updateFormField(index, 'type', e.target.value)}\n className=\"flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-xs shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n disabled={disabled}\n >\n <option value=\"text\">{t('workflows.form.fieldTypes.text')}</option>\n <option value=\"number\">{t('workflows.form.fieldTypes.number')}</option>\n <option value=\"email\">{t('workflows.form.fieldTypes.email')}</option>\n <option value=\"tel\">{t('workflows.form.fieldTypes.tel')}</option>\n <option value=\"url\">{t('workflows.form.fieldTypes.url')}</option>\n <option value=\"textarea\">{t('workflows.form.fieldTypes.textarea')}</option>\n <option value=\"select\">{t('workflows.form.fieldTypes.select')}</option>\n <option value=\"radio\">{t('workflows.form.fieldTypes.radio')}</option>\n <option value=\"checkbox\">{t('workflows.form.fieldTypes.checkbox')}</option>\n <option value=\"date\">{t('workflows.form.fieldTypes.date')}</option>\n <option value=\"time\">{t('workflows.form.fieldTypes.time')}</option>\n <option value=\"datetime-local\">{t('workflows.form.fieldTypes.datetime-local')}</option>\n </select>\n </div>\n\n {/* Placeholder */}\n <div>\n <Label htmlFor={`${id}-${index}-placeholder`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.placeholder')}\n </Label>\n <Input\n id={`${id}-${index}-placeholder`}\n type=\"text\"\n value={field.placeholder || ''}\n onChange={(e) => updateFormField(index, 'placeholder', e.target.value)}\n placeholder={t('workflows.fieldEditors.formFields.placeholderPlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n </div>\n\n {/* Default Value */}\n <div>\n <Label htmlFor={`${id}-${index}-defaultValue`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.defaultValue')}\n </Label>\n <Input\n id={`${id}-${index}-defaultValue`}\n type=\"text\"\n value={field.defaultValue || ''}\n onChange={(e) => updateFormField(index, 'defaultValue', e.target.value)}\n placeholder={t('workflows.fieldEditors.formFields.defaultValuePlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n </div>\n\n {/* Options (for select/radio) */}\n {(field.type === 'select' || field.type === 'radio') && (\n <div>\n <Label htmlFor={`${id}-${index}-options`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.options')}\n </Label>\n <Input\n id={`${id}-${index}-options`}\n type=\"text\"\n value={field.options?.join(', ') || ''}\n onChange={(e) =>\n updateFormField(\n index,\n 'options',\n e.target.value\n .split(',')\n .map((o) => o.trim())\n .filter(Boolean)\n )\n }\n placeholder={t('workflows.fieldEditors.formFields.optionsPlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n <p className=\"text-xs text-muted-foreground mt-0.5\">{t('workflows.fieldEditors.formFields.optionsHint')}</p>\n </div>\n )}\n\n {/* Required Checkbox */}\n <div>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id={`${id}-${index}-required`}\n checked={field.required}\n onChange={(e) => updateFormField(index, 'required', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600 focus-visible:ring-ring\"\n disabled={disabled}\n />\n <Label htmlFor={`${id}-${index}-required`} className=\"text-xs font-medium cursor-pointer\">\n {t('workflows.fieldEditors.formFields.requiredField')}\n </Label>\n </div>\n </div>\n\n {/* Delete Button */}\n <div className=\"border-t border-gray-200 pt-3\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => removeFormField(index)}\n disabled={disabled}\n >\n <Trash2 className=\"size-4 mr-1\" />\n {t('workflows.fieldEditors.formFields.removeField')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n })}\n </div>\n )}\n {ConfirmDialogElement}\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport { useState } from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { ChevronDown, Plus, Trash2, Info } from 'lucide-react'\nimport type { CrudCustomFieldRenderProps } from '@open-mercato/ui/backend/CrudForm'\n\n/**\n * Form field definition structure\n */\nexport interface FormField {\n name: string\n type: string\n label: string\n required: boolean\n placeholder?: string\n options?: string[]\n defaultValue?: string\n}\n\ninterface FormFieldArrayEditorProps extends CrudCustomFieldRenderProps {\n value: FormField[]\n isJsonSchemaFormat?: boolean\n}\n\n/**\n * FormFieldArrayEditor - Custom field component for managing UserTask form fields\n *\n * Provides an interface to add, edit, and remove form field definitions for user tasks.\n * Supports 12 field types with conditional options for select/radio types.\n *\n * Displays a warning banner if the form was converted from JSON Schema format.\n *\n * Used by NodeEditDialog (UserTask type only)\n */\nexport function FormFieldArrayEditor({\n id,\n value = [],\n error,\n setValue,\n disabled,\n isJsonSchemaFormat = false,\n}: FormFieldArrayEditorProps) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [expandedIndices, setExpandedIndices] = useState<Set<number>>(new Set())\n\n const formFields = Array.isArray(value) ? value : []\n\n const toggleExpanded = (index: number) => {\n const newExpanded = new Set(expandedIndices)\n if (newExpanded.has(index)) {\n newExpanded.delete(index)\n } else {\n newExpanded.add(index)\n }\n setExpandedIndices(newExpanded)\n }\n\n const addFormField = () => {\n const newField: FormField = {\n name: `field_${Date.now()}`,\n type: 'text',\n label: t('workflows.form.newField'),\n required: false,\n placeholder: '',\n }\n const newFields = [...formFields, newField]\n setValue(newFields)\n\n // Auto-expand the newly added field\n const newExpanded = new Set(expandedIndices)\n newExpanded.add(formFields.length)\n setExpandedIndices(newExpanded)\n }\n\n const removeFormField = async (index: number) => {\n const confirmed = await confirm({\n title: t('workflows.fieldEditors.formFields.removeField'),\n text: t('workflows.fieldEditors.formFields.confirmRemove'),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n const newFields = formFields.filter((_, i) => i !== index)\n setValue(newFields)\n\n // Remove from expanded set\n const newExpanded = new Set(expandedIndices)\n newExpanded.delete(index)\n setExpandedIndices(newExpanded)\n }\n\n const updateFormField = (index: number, fieldKey: keyof FormField, fieldValue: any) => {\n const updated = [...formFields]\n updated[index] = { ...updated[index], [fieldKey]: fieldValue }\n setValue(updated)\n }\n\n return (\n <div className=\"space-y-3\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <Label className=\"text-sm font-semibold\">{t('workflows.fieldEditors.formFields.title')} ({formFields.length})</Label>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {t('workflows.fieldEditors.formFields.description')}\n </p>\n {error && <p className=\"text-xs text-red-600 mt-1\">{error}</p>}\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={addFormField}\n disabled={disabled}\n className=\"w-full sm:w-auto\"\n >\n <Plus className=\"size-3 mr-1\" />\n {t('workflows.fieldEditors.formFields.addField')}\n </Button>\n </div>\n\n {/* JSON Schema Format Notice */}\n {isJsonSchemaFormat && (\n <Alert variant=\"default\" className=\"border-blue-200 bg-blue-50\">\n <Info className=\"size-4\" />\n <AlertDescription className=\"text-xs\">\n {t('workflows.fieldEditors.formFields.jsonSchemaNotice')}\n </AlertDescription>\n </Alert>\n )}\n\n {formFields.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-muted-foreground bg-muted rounded-lg border\">\n {t('workflows.fieldEditors.formFields.emptyState')}\n </div>\n ) : (\n <div className=\"space-y-2\">\n {formFields.map((field, index) => {\n const isExpanded = expandedIndices.has(index)\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-gray-50\">\n {/* Collapsed Header */}\n <button\n type=\"button\"\n onClick={() => toggleExpanded(index)}\n disabled={disabled}\n className=\"w-full px-4 py-3 text-left flex items-center justify-between hover:bg-gray-100 transition-colors rounded-t-lg disabled:opacity-50\"\n >\n <div className=\"flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-900\">\n {field.label || field.name}\n </span>\n <Badge variant=\"secondary\" className=\"text-xs\">\n {field.type}\n </Badge>\n {field.required && (\n <Badge variant=\"destructive\" className=\"text-xs text-white\">\n {t('workflows.form.required')}\n </Badge>\n )}\n </div>\n <p className=\"text-xs text-gray-600 mt-1\">\n Field name: <code className=\"bg-white px-1 rounded\">{field.name}</code>\n </p>\n </div>\n <ChevronDown\n className={`w-5 h-5 text-gray-400 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n />\n </button>\n\n {/* Expanded Content */}\n {isExpanded && (\n <div className=\"px-4 pb-4 space-y-3 border-t border-gray-200 bg-white\">\n {/* Field Name */}\n <div className=\"pt-3\">\n <Label htmlFor={`${id}-${index}-name`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.fieldName')} *\n </Label>\n <Input\n id={`${id}-${index}-name`}\n type=\"text\"\n value={field.name}\n onChange={(e) => updateFormField(index, 'name', e.target.value)}\n placeholder={t('workflows.fieldEditors.formFields.fieldNamePlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n <p className=\"text-xs text-muted-foreground mt-0.5\">{t('workflows.fieldEditors.formFields.fieldNameHint')}</p>\n </div>\n\n {/* Field Label */}\n <div>\n <Label htmlFor={`${id}-${index}-label`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.fieldLabel')} *\n </Label>\n <Input\n id={`${id}-${index}-label`}\n type=\"text\"\n value={field.label}\n onChange={(e) => updateFormField(index, 'label', e.target.value)}\n placeholder={t('workflows.fieldEditors.formFields.fieldLabelPlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n <p className=\"text-xs text-muted-foreground mt-0.5\">{t('workflows.fieldEditors.formFields.fieldLabelHint')}</p>\n </div>\n\n {/* Field Type */}\n <div>\n <Label htmlFor={`${id}-${index}-type`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.fieldType')} *\n </Label>\n <Select\n value={field.type}\n onValueChange={(value) => updateFormField(index, 'type', value)}\n disabled={disabled}\n >\n <SelectTrigger id={`${id}-${index}-type`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"text\">{t('workflows.form.fieldTypes.text')}</SelectItem>\n <SelectItem value=\"number\">{t('workflows.form.fieldTypes.number')}</SelectItem>\n <SelectItem value=\"email\">{t('workflows.form.fieldTypes.email')}</SelectItem>\n <SelectItem value=\"tel\">{t('workflows.form.fieldTypes.tel')}</SelectItem>\n <SelectItem value=\"url\">{t('workflows.form.fieldTypes.url')}</SelectItem>\n <SelectItem value=\"textarea\">{t('workflows.form.fieldTypes.textarea')}</SelectItem>\n <SelectItem value=\"select\">{t('workflows.form.fieldTypes.select')}</SelectItem>\n <SelectItem value=\"radio\">{t('workflows.form.fieldTypes.radio')}</SelectItem>\n <SelectItem value=\"checkbox\">{t('workflows.form.fieldTypes.checkbox')}</SelectItem>\n <SelectItem value=\"date\">{t('workflows.form.fieldTypes.date')}</SelectItem>\n <SelectItem value=\"time\">{t('workflows.form.fieldTypes.time')}</SelectItem>\n <SelectItem value=\"datetime-local\">{t('workflows.form.fieldTypes.datetime-local')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n {/* Placeholder */}\n <div>\n <Label htmlFor={`${id}-${index}-placeholder`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.placeholder')}\n </Label>\n <Input\n id={`${id}-${index}-placeholder`}\n type=\"text\"\n value={field.placeholder || ''}\n onChange={(e) => updateFormField(index, 'placeholder', e.target.value)}\n placeholder={t('workflows.fieldEditors.formFields.placeholderPlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n </div>\n\n {/* Default Value */}\n <div>\n <Label htmlFor={`${id}-${index}-defaultValue`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.defaultValue')}\n </Label>\n <Input\n id={`${id}-${index}-defaultValue`}\n type=\"text\"\n value={field.defaultValue || ''}\n onChange={(e) => updateFormField(index, 'defaultValue', e.target.value)}\n placeholder={t('workflows.fieldEditors.formFields.defaultValuePlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n </div>\n\n {/* Options (for select/radio) */}\n {(field.type === 'select' || field.type === 'radio') && (\n <div>\n <Label htmlFor={`${id}-${index}-options`} className=\"text-xs font-medium mb-1\">\n {t('workflows.fieldEditors.formFields.options')}\n </Label>\n <Input\n id={`${id}-${index}-options`}\n type=\"text\"\n value={field.options?.join(', ') || ''}\n onChange={(e) =>\n updateFormField(\n index,\n 'options',\n e.target.value\n .split(',')\n .map((o) => o.trim())\n .filter(Boolean)\n )\n }\n placeholder={t('workflows.fieldEditors.formFields.optionsPlaceholder')}\n className=\"text-xs\"\n disabled={disabled}\n />\n <p className=\"text-xs text-muted-foreground mt-0.5\">{t('workflows.fieldEditors.formFields.optionsHint')}</p>\n </div>\n )}\n\n {/* Required Checkbox */}\n <div>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id={`${id}-${index}-required`}\n checked={field.required}\n onChange={(e) => updateFormField(index, 'required', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300 text-blue-600 focus-visible:ring-ring\"\n disabled={disabled}\n />\n <Label htmlFor={`${id}-${index}-required`} className=\"text-xs font-medium cursor-pointer\">\n {t('workflows.fieldEditors.formFields.requiredField')}\n </Label>\n </div>\n </div>\n\n {/* Delete Button */}\n <div className=\"border-t border-gray-200 pt-3\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => removeFormField(index)}\n disabled={disabled}\n >\n <Trash2 className=\"size-4 mr-1\" />\n {t('workflows.fieldEditors.formFields.removeField')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n })}\n </div>\n )}\n {ConfirmDialogElement}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AAoHU,SACA,KADA;AAlHV,SAAS,gBAAgB;AACzB,SAAS,YAAY;AACrB,SAAS,wBAAwB;AACjC,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,OAAO,wBAAwB;AACxC,SAAS,aAAa,MAAM,QAAQ,YAAY;AA+BzC,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA,QAAQ,CAAC;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AACvB,GAA8B;AAC5B,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,SAAS,qBAAqB,IAAI,iBAAiB;AAC3D,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAsB,oBAAI,IAAI,CAAC;AAE7E,QAAM,aAAa,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AAEnD,QAAM,iBAAiB,CAAC,UAAkB;AACxC,UAAM,cAAc,IAAI,IAAI,eAAe;AAC3C,QAAI,YAAY,IAAI,KAAK,GAAG;AAC1B,kBAAY,OAAO,KAAK;AAAA,IAC1B,OAAO;AACL,kBAAY,IAAI,KAAK;AAAA,IACvB;AACA,uBAAmB,WAAW;AAAA,EAChC;AAEA,QAAM,eAAe,MAAM;AACzB,UAAM,WAAsB;AAAA,MAC1B,MAAM,SAAS,KAAK,IAAI,CAAC;AAAA,MACzB,MAAM;AAAA,MACN,OAAO,EAAE,yBAAyB;AAAA,MAClC,UAAU;AAAA,MACV,aAAa;AAAA,IACf;AACA,UAAM,YAAY,CAAC,GAAG,YAAY,QAAQ;AAC1C,aAAS,SAAS;AAGlB,UAAM,cAAc,IAAI,IAAI,eAAe;AAC3C,gBAAY,IAAI,WAAW,MAAM;AACjC,uBAAmB,WAAW;AAAA,EAChC;AAEA,QAAM,kBAAkB,OAAO,UAAkB;AAC/C,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,OAAO,EAAE,+CAA+C;AAAA,MACxD,MAAM,EAAE,iDAAiD;AAAA,MACzD,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,UAAW;AAEhB,UAAM,YAAY,WAAW,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK;AACzD,aAAS,SAAS;AAGlB,UAAM,cAAc,IAAI,IAAI,eAAe;AAC3C,gBAAY,OAAO,KAAK;AACxB,uBAAmB,WAAW;AAAA,EAChC;AAEA,QAAM,kBAAkB,CAAC,OAAe,UAA2B,eAAoB;AACrF,UAAM,UAAU,CAAC,GAAG,UAAU;AAC9B,YAAQ,KAAK,IAAI,EAAE,GAAG,QAAQ,KAAK,GAAG,CAAC,QAAQ,GAAG,WAAW;AAC7D,aAAS,OAAO;AAAA,EAClB;AAEA,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SAAI,WAAU,sEACb;AAAA,2BAAC,SACC;AAAA,6BAAC,SAAM,WAAU,yBAAyB;AAAA,YAAE,yCAAyC;AAAA,UAAE;AAAA,UAAG,WAAW;AAAA,UAAO;AAAA,WAAC;AAAA,QAC7G,oBAAC,OAAE,WAAU,wCACV,YAAE,+CAA+C,GACpD;AAAA,QACC,SAAS,oBAAC,OAAE,WAAU,6BAA6B,iBAAM;AAAA,SAC5D;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,MAAK;AAAA,UACL,SAAS;AAAA,UACT;AAAA,UACA,WAAU;AAAA,UAEV;AAAA,gCAAC,QAAK,WAAU,eAAc;AAAA,YAC7B,EAAE,4CAA4C;AAAA;AAAA;AAAA,MACjD;AAAA,OACF;AAAA,IAGC,sBACC,qBAAC,SAAM,SAAQ,WAAU,WAAU,8BACjC;AAAA,0BAAC,QAAK,WAAU,UAAS;AAAA,MACzB,oBAAC,oBAAiB,WAAU,WACzB,YAAE,oDAAoD,GACzD;AAAA,OACF;AAAA,IAGD,WAAW,WAAW,IACrB,oBAAC,SAAI,WAAU,4EACZ,YAAE,8CAA8C,GACnD,IAEA,oBAAC,SAAI,WAAU,aACZ,qBAAW,IAAI,CAAC,OAAO,UAAU;AAChC,YAAM,aAAa,gBAAgB,IAAI,KAAK;AAC5C,aACE,qBAAC,SAAgB,WAAU,gDAEzB;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,eAAe,KAAK;AAAA,YACnC;AAAA,YACA,WAAU;AAAA,YAEV;AAAA,mCAAC,SAAI,WAAU,UACb;AAAA,qCAAC,SAAI,WAAU,qCACb;AAAA,sCAAC,UAAK,WAAU,uCACb,gBAAM,SAAS,MAAM,MACxB;AAAA,kBACA,oBAAC,SAAM,SAAQ,aAAY,WAAU,WAClC,gBAAM,MACT;AAAA,kBACC,MAAM,YACL,oBAAC,SAAM,SAAQ,eAAc,WAAU,sBACpC,YAAE,yBAAyB,GAC9B;AAAA,mBAEJ;AAAA,gBACA,qBAAC,OAAE,WAAU,8BAA6B;AAAA;AAAA,kBAC5B,oBAAC,UAAK,WAAU,yBAAyB,gBAAM,MAAK;AAAA,mBAClE;AAAA,iBACF;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW,8CAA8C,aAAa,eAAe,EAAE;AAAA;AAAA,cACzF;AAAA;AAAA;AAAA,QACF;AAAA,QAGC,cACC,qBAAC,SAAI,WAAU,yDAEb;AAAA,+BAAC,SAAI,WAAU,QACb;AAAA,iCAAC,SAAM,SAAS,GAAG,EAAE,IAAI,KAAK,SAAS,WAAU,4BAC9C;AAAA,gBAAE,6CAA6C;AAAA,cAAE;AAAA,eACpD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,IAAI,GAAG,EAAE,IAAI,KAAK;AAAA,gBAClB,MAAK;AAAA,gBACL,OAAO,MAAM;AAAA,gBACb,UAAU,CAAC,MAAM,gBAAgB,OAAO,QAAQ,EAAE,OAAO,KAAK;AAAA,gBAC9D,aAAa,EAAE,wDAAwD;AAAA,gBACvE,WAAU;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,YACA,oBAAC,OAAE,WAAU,wCAAwC,YAAE,iDAAiD,GAAE;AAAA,aAC5G;AAAA,UAGA,qBAAC,SACC;AAAA,iCAAC,SAAM,SAAS,GAAG,EAAE,IAAI,KAAK,UAAU,WAAU,4BAC/C;AAAA,gBAAE,8CAA8C;AAAA,cAAE;AAAA,eACrD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,IAAI,GAAG,EAAE,IAAI,KAAK;AAAA,gBAClB,MAAK;AAAA,gBACL,OAAO,MAAM;AAAA,gBACb,UAAU,CAAC,MAAM,gBAAgB,OAAO,SAAS,EAAE,OAAO,KAAK;AAAA,gBAC/D,aAAa,EAAE,yDAAyD;AAAA,gBACxE,WAAU;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,YACA,oBAAC,OAAE,WAAU,wCAAwC,YAAE,kDAAkD,GAAE;AAAA,aAC7G;AAAA,UAGA,qBAAC,SACC;AAAA,iCAAC,SAAM,SAAS,GAAG,EAAE,IAAI,KAAK,SAAS,WAAU,4BAC9C;AAAA,gBAAE,6CAA6C;AAAA,cAAE;AAAA,eACpD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,MAAM;AAAA,gBACb,eAAe,CAACA,WAAU,gBAAgB,OAAO,QAAQA,MAAK;AAAA,gBAC9D;AAAA,gBAEA;AAAA,sCAAC,iBAAc,IAAI,GAAG,EAAE,IAAI,KAAK,SAC/B,8BAAC,eAAY,GACf;AAAA,kBACA,qBAAC,iBACC;AAAA,wCAAC,cAAW,OAAM,QAAQ,YAAE,gCAAgC,GAAE;AAAA,oBAC9D,oBAAC,cAAW,OAAM,UAAU,YAAE,kCAAkC,GAAE;AAAA,oBAClE,oBAAC,cAAW,OAAM,SAAS,YAAE,iCAAiC,GAAE;AAAA,oBAChE,oBAAC,cAAW,OAAM,OAAO,YAAE,+BAA+B,GAAE;AAAA,oBAC5D,oBAAC,cAAW,OAAM,OAAO,YAAE,+BAA+B,GAAE;AAAA,oBAC5D,oBAAC,cAAW,OAAM,YAAY,YAAE,oCAAoC,GAAE;AAAA,oBACtE,oBAAC,cAAW,OAAM,UAAU,YAAE,kCAAkC,GAAE;AAAA,oBAClE,oBAAC,cAAW,OAAM,SAAS,YAAE,iCAAiC,GAAE;AAAA,oBAChE,oBAAC,cAAW,OAAM,YAAY,YAAE,oCAAoC,GAAE;AAAA,oBACtE,oBAAC,cAAW,OAAM,QAAQ,YAAE,gCAAgC,GAAE;AAAA,oBAC9D,oBAAC,cAAW,OAAM,QAAQ,YAAE,gCAAgC,GAAE;AAAA,oBAC9D,oBAAC,cAAW,OAAM,kBAAkB,YAAE,0CAA0C,GAAE;AAAA,qBACpF;AAAA;AAAA;AAAA,YACF;AAAA,aACF;AAAA,UAGA,qBAAC,SACC;AAAA,gCAAC,SAAM,SAAS,GAAG,EAAE,IAAI,KAAK,gBAAgB,WAAU,4BACrD,YAAE,+CAA+C,GACpD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,IAAI,GAAG,EAAE,IAAI,KAAK;AAAA,gBAClB,MAAK;AAAA,gBACL,OAAO,MAAM,eAAe;AAAA,gBAC5B,UAAU,CAAC,MAAM,gBAAgB,OAAO,eAAe,EAAE,OAAO,KAAK;AAAA,gBACrE,aAAa,EAAE,0DAA0D;AAAA,gBACzE,WAAU;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,aACF;AAAA,UAGA,qBAAC,SACC;AAAA,gCAAC,SAAM,SAAS,GAAG,EAAE,IAAI,KAAK,iBAAiB,WAAU,4BACtD,YAAE,gDAAgD,GACrD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,IAAI,GAAG,EAAE,IAAI,KAAK;AAAA,gBAClB,MAAK;AAAA,gBACL,OAAO,MAAM,gBAAgB;AAAA,gBAC7B,UAAU,CAAC,MAAM,gBAAgB,OAAO,gBAAgB,EAAE,OAAO,KAAK;AAAA,gBACtE,aAAa,EAAE,2DAA2D;AAAA,gBAC1E,WAAU;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,aACF;AAAA,WAGE,MAAM,SAAS,YAAY,MAAM,SAAS,YAC1C,qBAAC,SACC;AAAA,gCAAC,SAAM,SAAS,GAAG,EAAE,IAAI,KAAK,YAAY,WAAU,4BACjD,YAAE,2CAA2C,GAChD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,IAAI,GAAG,EAAE,IAAI,KAAK;AAAA,gBAClB,MAAK;AAAA,gBACL,OAAO,MAAM,SAAS,KAAK,IAAI,KAAK;AAAA,gBACpC,UAAU,CAAC,MACT;AAAA,kBACE;AAAA,kBACA;AAAA,kBACA,EAAE,OAAO,MACN,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AAAA,gBACnB;AAAA,gBAEF,aAAa,EAAE,sDAAsD;AAAA,gBACrE,WAAU;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,YACA,oBAAC,OAAE,WAAU,wCAAwC,YAAE,+CAA+C,GAAE;AAAA,aAC1G;AAAA,UAIF,oBAAC,SACC,+BAAC,SAAI,WAAU,2BACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,IAAI,GAAG,EAAE,IAAI,KAAK;AAAA,gBAClB,SAAS,MAAM;AAAA,gBACf,UAAU,CAAC,MAAM,gBAAgB,OAAO,YAAY,EAAE,OAAO,OAAO;AAAA,gBACpE,WAAU;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,YACA,oBAAC,SAAM,SAAS,GAAG,EAAE,IAAI,KAAK,aAAa,WAAU,sCAClD,YAAE,iDAAiD,GACtD;AAAA,aACF,GACF;AAAA,UAGA,oBAAC,SAAI,WAAU,iCACb;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM,gBAAgB,KAAK;AAAA,cACpC;AAAA,cAEA;AAAA,oCAAC,UAAO,WAAU,eAAc;AAAA,gBAC/B,EAAE,+CAA+C;AAAA;AAAA;AAAA,UACpD,GACF;AAAA,WACF;AAAA,WA5LM,KA8LV;AAAA,IAEJ,CAAC,GACH;AAAA,IAED;AAAA,KACH;AAEJ;",
|
|
6
|
+
"names": ["value"]
|
|
7
7
|
}
|
|
@@ -11,7 +11,7 @@ import { BusinessRulesSelector } from "../BusinessRulesSelector.js";
|
|
|
11
11
|
import { apiFetch } from "@open-mercato/ui/backend/utils/api";
|
|
12
12
|
import { EmptyState } from "@open-mercato/ui/backend/EmptyState";
|
|
13
13
|
import { Spinner } from "@open-mercato/ui/primitives/spinner";
|
|
14
|
-
import {
|
|
14
|
+
import { SwitchField } from "@open-mercato/ui/primitives/switch-field";
|
|
15
15
|
import { ConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
|
|
16
16
|
function LocalizedMessageTextarea({
|
|
17
17
|
value,
|
|
@@ -257,18 +257,17 @@ function StartPreConditionsEditor({
|
|
|
257
257
|
)
|
|
258
258
|
] })
|
|
259
259
|
] }),
|
|
260
|
-
/* @__PURE__ */
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
{
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
] }),
|
|
260
|
+
/* @__PURE__ */ jsx(
|
|
261
|
+
SwitchField,
|
|
262
|
+
{
|
|
263
|
+
id: `precondition-${index}-required`,
|
|
264
|
+
label: t("workflows.fieldEditors.preConditions.requiredLabel"),
|
|
265
|
+
flip: true,
|
|
266
|
+
checked: conditions[index]?.required ?? true,
|
|
267
|
+
onCheckedChange: (checked) => updateCondition(index, { required: checked }),
|
|
268
|
+
disabled
|
|
269
|
+
}
|
|
270
|
+
),
|
|
272
271
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
273
272
|
/* @__PURE__ */ jsx(Label, { htmlFor: `precondition-${index}-messages`, className: "text-xs", children: t("workflows.fieldEditors.preConditions.validationMessages") }),
|
|
274
273
|
/* @__PURE__ */ jsx(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/workflows/components/fields/StartPreConditionsEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { Plus, Trash2, AlertCircle, ChevronUp, ChevronDown } from 'lucide-react'\nimport { BusinessRulesSelector, type BusinessRule } from '../BusinessRulesSelector'\nimport { apiFetch } from '@open-mercato/ui/backend/utils/api'\nimport { EmptyState } from '@open-mercato/ui/backend/EmptyState'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport { ConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\n/**\n * StartPreCondition interface matching the schema in validators.ts\n */\nexport interface StartPreCondition {\n ruleId: string\n required: boolean\n validationMessage?: Record<string, string> // e.g., { en: 'Message', pl: 'Wiadomo\u015B\u0107' }\n}\n\ninterface StartPreConditionsEditorProps {\n value?: StartPreCondition[] | unknown\n setValue?: ((value: unknown) => void) | ((value: StartPreCondition[]) => void)\n disabled?: boolean\n}\n\ninterface ConditionWithDetails extends StartPreCondition {\n ruleName?: string\n ruleType?: string\n loading?: boolean\n error?: boolean\n}\n\n/**\n * LocalizedMessageTextarea - Textarea with local state that only updates parent on blur\n */\nfunction LocalizedMessageTextarea({\n value,\n onChange,\n disabled,\n id,\n placeholder,\n hint,\n}: {\n value: Record<string, string> | undefined\n onChange: (messages: Record<string, string>) => void\n disabled?: boolean\n id: string\n placeholder: string\n hint: string\n}) {\n const getValidationMessagesString = (messages: Record<string, string> | undefined): string => {\n if (!messages) return ''\n return Object.entries(messages)\n .filter(([_, msg]) => msg)\n .map(([locale, msg]) => `${locale}: ${msg}`)\n .join('\\n')\n }\n\n const parseValidationMessagesString = (str: string): Record<string, string> => {\n const result: Record<string, string> = {}\n str.split('\\n').forEach(line => {\n const match = line.match(/^(\\w+):\\s*(.*)$/)\n if (match) {\n result[match[1]] = match[2]\n }\n })\n return result\n }\n\n const [localValue, setLocalValue] = useState(() => getValidationMessagesString(value))\n\n // Update local value when external value changes\n useEffect(() => {\n setLocalValue(getValidationMessagesString(value))\n }, [value])\n\n const handleBlur = useCallback(() => {\n onChange(parseValidationMessagesString(localValue))\n }, [localValue, onChange])\n\n return (\n <>\n <Textarea\n id={id}\n value={localValue}\n onChange={(e) => setLocalValue(e.target.value)}\n onBlur={handleBlur}\n placeholder={placeholder}\n rows={2}\n className=\"mt-1 font-mono text-xs\"\n disabled={disabled}\n />\n <p className=\"text-xs text-muted-foreground mt-1\">\n {hint}\n </p>\n </>\n )\n}\n\n/**\n * StartPreConditionsEditor - Editor for START step pre-conditions\n *\n * Uses BusinessRulesSelector modal for selecting business rules (searchable).\n * Supports localized validation messages for each pre-condition.\n * Matches the style of TransitionsEditor and BusinessRuleConditionsEditor.\n */\nexport function StartPreConditionsEditor({\n value,\n setValue,\n disabled = false,\n}: StartPreConditionsEditorProps) {\n const t = useT()\n const [isModalOpen, setIsModalOpen] = useState(false)\n const [conditionsWithDetails, setConditionsWithDetails] = useState<ConditionWithDetails[]>([])\n\n // Safely cast value to StartPreCondition array\n const conditions: StartPreCondition[] = Array.isArray(value) ? value : []\n\n // Helper to call setValue with proper typing\n const updateValue = (newValue: StartPreCondition[]) => {\n if (setValue) {\n setValue(newValue)\n }\n }\n\n // Fetch rule details when conditions change\n useEffect(() => {\n const withDetails: ConditionWithDetails[] = conditions.map((c) => ({\n ...c,\n loading: true,\n }))\n setConditionsWithDetails(withDetails)\n\n // Fetch details for each rule\n conditions.forEach((condition, index) => {\n fetchRuleDetails(condition.ruleId, index)\n })\n }, [JSON.stringify(conditions.map(c => c.ruleId))])\n\n const fetchRuleDetails = async (ruleId: string, index: number) => {\n try {\n const params = new URLSearchParams({ ruleId, pageSize: '1' })\n const response = await apiFetch(`/api/business_rules/rules?${params.toString()}`)\n\n if (response.ok) {\n const data = await response.json()\n const rule = data.items?.[0] as BusinessRule | undefined\n\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: rule?.ruleName || ruleId,\n ruleType: rule?.ruleType,\n loading: false,\n error: !rule,\n }\n }\n return updated\n })\n } else {\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: ruleId,\n loading: false,\n error: true,\n }\n }\n return updated\n })\n }\n } catch (err) {\n console.error(`Failed to fetch rule details for ${ruleId}:`, err)\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: ruleId,\n loading: false,\n error: true,\n }\n }\n return updated\n })\n }\n }\n\n const addCondition = (ruleId: string, _rule: BusinessRule) => {\n const newCondition: StartPreCondition = {\n ruleId,\n required: true,\n validationMessage: { en: '' },\n }\n updateValue([...conditions, newCondition])\n setIsModalOpen(false)\n }\n\n const updateCondition = (index: number, updates: Partial<StartPreCondition>) => {\n const updated = [...conditions]\n updated[index] = { ...updated[index], ...updates }\n updateValue(updated)\n }\n\n const removeCondition = (index: number) => {\n updateValue(conditions.filter((_, i) => i !== index))\n }\n\n const moveCondition = (index: number, direction: 'up' | 'down') => {\n const newIndex = direction === 'up' ? index - 1 : index + 1\n if (newIndex < 0 || newIndex >= conditions.length) return\n\n const updated = [...conditions]\n const temp = updated[index]\n updated[index] = updated[newIndex]\n updated[newIndex] = temp\n updateValue(updated)\n }\n\n const getExcludedRuleIds = (): string[] => {\n return conditions.map((c) => c.ruleId)\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <p className=\"text-sm text-muted-foreground\">\n {t('workflows.fieldEditors.preConditions.description')}\n </p>\n </div>\n <Button\n type=\"button\"\n onClick={() => setIsModalOpen(true)}\n variant=\"outline\"\n size=\"sm\"\n disabled={disabled}\n className=\"w-full sm:w-auto\"\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n {t('workflows.fieldEditors.preConditions.addRule')}\n </Button>\n </div>\n\n {conditions.length === 0 && (\n <EmptyState\n title={t('workflows.fieldEditors.preConditions.emptyTitle')}\n description={t('workflows.fieldEditors.preConditions.emptyDescription')}\n action={{ label: t('workflows.fieldEditors.preConditions.addRule'), onClick: () => setIsModalOpen(true), disabled }}\n />\n )}\n\n <div className=\"space-y-3\">\n {conditionsWithDetails.map((condition, index) => (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-white p-4\">\n <div className=\"space-y-3\">\n {/* Header row with rule info and actions */}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex-1 min-w-0\">\n {/* Rule Name/ID */}\n {condition.loading ? (\n <div className=\"flex items-center gap-2\">\n <Spinner size=\"sm\" />\n <span className=\"text-sm text-muted-foreground\">{t('workflows.common.loadingDetails')}</span>\n </div>\n ) : condition.error ? (\n <div className=\"flex items-center gap-2\">\n <AlertCircle className=\"size-4 text-amber-600\" />\n <div>\n <span className=\"text-sm font-semibold text-foreground\">{condition.ruleId}</span>\n <p className=\"text-xs text-amber-600\">{t('workflows.common.ruleNotFound')}</p>\n </div>\n </div>\n ) : (\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-foreground\">{condition.ruleName}</span>\n {condition.ruleType && (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {condition.ruleType}\n </Badge>\n )}\n </div>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n ID: <code className=\"bg-muted px-1 rounded font-mono\">{condition.ruleId}</code>\n </p>\n </div>\n )}\n </div>\n\n {/* Action buttons */}\n <div className=\"flex items-center gap-1 self-end sm:self-auto\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => moveCondition(index, 'up')}\n disabled={index === 0 || disabled}\n title={t('workflows.common.moveUp')}\n >\n <ChevronUp className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => moveCondition(index, 'down')}\n disabled={index === conditions.length - 1 || disabled}\n title={t('workflows.common.moveDown')}\n >\n <ChevronDown className=\"h-4 w-4\" />\n </Button>\n <ConfirmDialog\n trigger={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n title={t('workflows.common.delete')}\n disabled={disabled}\n >\n <Trash2 className=\"h-4 w-4 text-red-600\" />\n </Button>\n }\n title={t('workflows.fieldEditors.preConditions.removePreCondition')}\n text={t('workflows.fieldEditors.preConditions.confirmRemove')}\n variant=\"destructive\"\n onConfirm={() => removeCondition(index)}\n />\n </div>\n </div>\n\n {/* Required toggle */}\n <div className=\"flex items-center gap-2\">\n <Switch\n id={`precondition-${index}-required`}\n checked={conditions[index]?.required ?? true}\n onCheckedChange={(checked) => updateCondition(index, { required: checked })}\n disabled={disabled}\n />\n <Label htmlFor={`precondition-${index}-required`} className=\"text-xs font-medium cursor-pointer\">\n {t('workflows.fieldEditors.preConditions.requiredLabel')}\n </Label>\n </div>\n\n {/* Validation Messages */}\n <div>\n <Label htmlFor={`precondition-${index}-messages`} className=\"text-xs\">\n {t('workflows.fieldEditors.preConditions.validationMessages')}\n </Label>\n <LocalizedMessageTextarea\n id={`precondition-${index}-messages`}\n value={conditions[index]?.validationMessage}\n onChange={(messages) => updateCondition(index, { validationMessage: messages })}\n disabled={disabled}\n placeholder={t('workflows.fieldEditors.preConditions.validationMessagesPlaceholder')}\n hint={t('workflows.fieldEditors.preConditions.validationMessagesHint')}\n />\n </div>\n </div>\n </div>\n ))}\n </div>\n\n {/* Business Rules Selector Modal */}\n <BusinessRulesSelector\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n onSelect={addCondition}\n excludeRuleIds={getExcludedRuleIds()}\n title={t('workflows.fieldEditors.preConditions.selectBusinessRule')}\n description={t('workflows.fieldEditors.preConditions.selectBusinessRuleDescription')}\n filterRuleType=\"GUARD\"\n onlyEnabled={true}\n />\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": ";AAuFI,mBACE,KADF;AArFJ,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,YAAY;AACrB,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,gBAAgB;AACzB,SAAS,MAAM,QAAQ,aAAa,WAAW,mBAAmB;AAClE,SAAS,6BAAgD;AACzD,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { Plus, Trash2, AlertCircle, ChevronUp, ChevronDown } from 'lucide-react'\nimport { BusinessRulesSelector, type BusinessRule } from '../BusinessRulesSelector'\nimport { apiFetch } from '@open-mercato/ui/backend/utils/api'\nimport { EmptyState } from '@open-mercato/ui/backend/EmptyState'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { SwitchField } from '@open-mercato/ui/primitives/switch-field'\nimport { ConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\n/**\n * StartPreCondition interface matching the schema in validators.ts\n */\nexport interface StartPreCondition {\n ruleId: string\n required: boolean\n validationMessage?: Record<string, string> // e.g., { en: 'Message', pl: 'Wiadomo\u015B\u0107' }\n}\n\ninterface StartPreConditionsEditorProps {\n value?: StartPreCondition[] | unknown\n setValue?: ((value: unknown) => void) | ((value: StartPreCondition[]) => void)\n disabled?: boolean\n}\n\ninterface ConditionWithDetails extends StartPreCondition {\n ruleName?: string\n ruleType?: string\n loading?: boolean\n error?: boolean\n}\n\n/**\n * LocalizedMessageTextarea - Textarea with local state that only updates parent on blur\n */\nfunction LocalizedMessageTextarea({\n value,\n onChange,\n disabled,\n id,\n placeholder,\n hint,\n}: {\n value: Record<string, string> | undefined\n onChange: (messages: Record<string, string>) => void\n disabled?: boolean\n id: string\n placeholder: string\n hint: string\n}) {\n const getValidationMessagesString = (messages: Record<string, string> | undefined): string => {\n if (!messages) return ''\n return Object.entries(messages)\n .filter(([_, msg]) => msg)\n .map(([locale, msg]) => `${locale}: ${msg}`)\n .join('\\n')\n }\n\n const parseValidationMessagesString = (str: string): Record<string, string> => {\n const result: Record<string, string> = {}\n str.split('\\n').forEach(line => {\n const match = line.match(/^(\\w+):\\s*(.*)$/)\n if (match) {\n result[match[1]] = match[2]\n }\n })\n return result\n }\n\n const [localValue, setLocalValue] = useState(() => getValidationMessagesString(value))\n\n // Update local value when external value changes\n useEffect(() => {\n setLocalValue(getValidationMessagesString(value))\n }, [value])\n\n const handleBlur = useCallback(() => {\n onChange(parseValidationMessagesString(localValue))\n }, [localValue, onChange])\n\n return (\n <>\n <Textarea\n id={id}\n value={localValue}\n onChange={(e) => setLocalValue(e.target.value)}\n onBlur={handleBlur}\n placeholder={placeholder}\n rows={2}\n className=\"mt-1 font-mono text-xs\"\n disabled={disabled}\n />\n <p className=\"text-xs text-muted-foreground mt-1\">\n {hint}\n </p>\n </>\n )\n}\n\n/**\n * StartPreConditionsEditor - Editor for START step pre-conditions\n *\n * Uses BusinessRulesSelector modal for selecting business rules (searchable).\n * Supports localized validation messages for each pre-condition.\n * Matches the style of TransitionsEditor and BusinessRuleConditionsEditor.\n */\nexport function StartPreConditionsEditor({\n value,\n setValue,\n disabled = false,\n}: StartPreConditionsEditorProps) {\n const t = useT()\n const [isModalOpen, setIsModalOpen] = useState(false)\n const [conditionsWithDetails, setConditionsWithDetails] = useState<ConditionWithDetails[]>([])\n\n // Safely cast value to StartPreCondition array\n const conditions: StartPreCondition[] = Array.isArray(value) ? value : []\n\n // Helper to call setValue with proper typing\n const updateValue = (newValue: StartPreCondition[]) => {\n if (setValue) {\n setValue(newValue)\n }\n }\n\n // Fetch rule details when conditions change\n useEffect(() => {\n const withDetails: ConditionWithDetails[] = conditions.map((c) => ({\n ...c,\n loading: true,\n }))\n setConditionsWithDetails(withDetails)\n\n // Fetch details for each rule\n conditions.forEach((condition, index) => {\n fetchRuleDetails(condition.ruleId, index)\n })\n }, [JSON.stringify(conditions.map(c => c.ruleId))])\n\n const fetchRuleDetails = async (ruleId: string, index: number) => {\n try {\n const params = new URLSearchParams({ ruleId, pageSize: '1' })\n const response = await apiFetch(`/api/business_rules/rules?${params.toString()}`)\n\n if (response.ok) {\n const data = await response.json()\n const rule = data.items?.[0] as BusinessRule | undefined\n\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: rule?.ruleName || ruleId,\n ruleType: rule?.ruleType,\n loading: false,\n error: !rule,\n }\n }\n return updated\n })\n } else {\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: ruleId,\n loading: false,\n error: true,\n }\n }\n return updated\n })\n }\n } catch (err) {\n console.error(`Failed to fetch rule details for ${ruleId}:`, err)\n setConditionsWithDetails((prev) => {\n const updated = [...prev]\n if (updated[index]) {\n updated[index] = {\n ...updated[index],\n ruleName: ruleId,\n loading: false,\n error: true,\n }\n }\n return updated\n })\n }\n }\n\n const addCondition = (ruleId: string, _rule: BusinessRule) => {\n const newCondition: StartPreCondition = {\n ruleId,\n required: true,\n validationMessage: { en: '' },\n }\n updateValue([...conditions, newCondition])\n setIsModalOpen(false)\n }\n\n const updateCondition = (index: number, updates: Partial<StartPreCondition>) => {\n const updated = [...conditions]\n updated[index] = { ...updated[index], ...updates }\n updateValue(updated)\n }\n\n const removeCondition = (index: number) => {\n updateValue(conditions.filter((_, i) => i !== index))\n }\n\n const moveCondition = (index: number, direction: 'up' | 'down') => {\n const newIndex = direction === 'up' ? index - 1 : index + 1\n if (newIndex < 0 || newIndex >= conditions.length) return\n\n const updated = [...conditions]\n const temp = updated[index]\n updated[index] = updated[newIndex]\n updated[newIndex] = temp\n updateValue(updated)\n }\n\n const getExcludedRuleIds = (): string[] => {\n return conditions.map((c) => c.ruleId)\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <p className=\"text-sm text-muted-foreground\">\n {t('workflows.fieldEditors.preConditions.description')}\n </p>\n </div>\n <Button\n type=\"button\"\n onClick={() => setIsModalOpen(true)}\n variant=\"outline\"\n size=\"sm\"\n disabled={disabled}\n className=\"w-full sm:w-auto\"\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n {t('workflows.fieldEditors.preConditions.addRule')}\n </Button>\n </div>\n\n {conditions.length === 0 && (\n <EmptyState\n title={t('workflows.fieldEditors.preConditions.emptyTitle')}\n description={t('workflows.fieldEditors.preConditions.emptyDescription')}\n action={{ label: t('workflows.fieldEditors.preConditions.addRule'), onClick: () => setIsModalOpen(true), disabled }}\n />\n )}\n\n <div className=\"space-y-3\">\n {conditionsWithDetails.map((condition, index) => (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-white p-4\">\n <div className=\"space-y-3\">\n {/* Header row with rule info and actions */}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex-1 min-w-0\">\n {/* Rule Name/ID */}\n {condition.loading ? (\n <div className=\"flex items-center gap-2\">\n <Spinner size=\"sm\" />\n <span className=\"text-sm text-muted-foreground\">{t('workflows.common.loadingDetails')}</span>\n </div>\n ) : condition.error ? (\n <div className=\"flex items-center gap-2\">\n <AlertCircle className=\"size-4 text-amber-600\" />\n <div>\n <span className=\"text-sm font-semibold text-foreground\">{condition.ruleId}</span>\n <p className=\"text-xs text-amber-600\">{t('workflows.common.ruleNotFound')}</p>\n </div>\n </div>\n ) : (\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-foreground\">{condition.ruleName}</span>\n {condition.ruleType && (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {condition.ruleType}\n </Badge>\n )}\n </div>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n ID: <code className=\"bg-muted px-1 rounded font-mono\">{condition.ruleId}</code>\n </p>\n </div>\n )}\n </div>\n\n {/* Action buttons */}\n <div className=\"flex items-center gap-1 self-end sm:self-auto\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => moveCondition(index, 'up')}\n disabled={index === 0 || disabled}\n title={t('workflows.common.moveUp')}\n >\n <ChevronUp className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => moveCondition(index, 'down')}\n disabled={index === conditions.length - 1 || disabled}\n title={t('workflows.common.moveDown')}\n >\n <ChevronDown className=\"h-4 w-4\" />\n </Button>\n <ConfirmDialog\n trigger={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n title={t('workflows.common.delete')}\n disabled={disabled}\n >\n <Trash2 className=\"h-4 w-4 text-red-600\" />\n </Button>\n }\n title={t('workflows.fieldEditors.preConditions.removePreCondition')}\n text={t('workflows.fieldEditors.preConditions.confirmRemove')}\n variant=\"destructive\"\n onConfirm={() => removeCondition(index)}\n />\n </div>\n </div>\n\n {/* Required toggle */}\n <SwitchField\n id={`precondition-${index}-required`}\n label={t('workflows.fieldEditors.preConditions.requiredLabel')}\n flip\n checked={conditions[index]?.required ?? true}\n onCheckedChange={(checked) => updateCondition(index, { required: checked })}\n disabled={disabled}\n />\n\n {/* Validation Messages */}\n <div>\n <Label htmlFor={`precondition-${index}-messages`} className=\"text-xs\">\n {t('workflows.fieldEditors.preConditions.validationMessages')}\n </Label>\n <LocalizedMessageTextarea\n id={`precondition-${index}-messages`}\n value={conditions[index]?.validationMessage}\n onChange={(messages) => updateCondition(index, { validationMessage: messages })}\n disabled={disabled}\n placeholder={t('workflows.fieldEditors.preConditions.validationMessagesPlaceholder')}\n hint={t('workflows.fieldEditors.preConditions.validationMessagesHint')}\n />\n </div>\n </div>\n </div>\n ))}\n </div>\n\n {/* Business Rules Selector Modal */}\n <BusinessRulesSelector\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n onSelect={addCondition}\n excludeRuleIds={getExcludedRuleIds()}\n title={t('workflows.fieldEditors.preConditions.selectBusinessRule')}\n description={t('workflows.fieldEditors.preConditions.selectBusinessRuleDescription')}\n filterRuleType=\"GUARD\"\n onlyEnabled={true}\n />\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -6,6 +6,13 @@ import { Input } from "@open-mercato/ui/primitives/input";
|
|
|
6
6
|
import { Textarea } from "@open-mercato/ui/primitives/textarea";
|
|
7
7
|
import { Checkbox } from "@open-mercato/ui/primitives/checkbox";
|
|
8
8
|
import { Label } from "@open-mercato/ui/primitives/label";
|
|
9
|
+
import {
|
|
10
|
+
Select,
|
|
11
|
+
SelectContent,
|
|
12
|
+
SelectItem,
|
|
13
|
+
SelectTrigger,
|
|
14
|
+
SelectValue
|
|
15
|
+
} from "@open-mercato/ui/primitives/select";
|
|
9
16
|
import { Separator } from "@open-mercato/ui/primitives/separator";
|
|
10
17
|
import { JsonDisplay } from "@open-mercato/ui/backend/JsonDisplay";
|
|
11
18
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
@@ -43,16 +50,13 @@ function MobileTaskForm({
|
|
|
43
50
|
] }),
|
|
44
51
|
fieldDescription && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: fieldDescription }),
|
|
45
52
|
/* @__PURE__ */ jsxs(
|
|
46
|
-
|
|
53
|
+
Select,
|
|
47
54
|
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
onChange: (e) => onFieldChange(fieldName, e.target.value),
|
|
51
|
-
required,
|
|
52
|
-
className: "w-full h-11 px-3 py-2 border border-border rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring text-base",
|
|
55
|
+
value: fieldValue(fieldName) ? String(fieldValue(fieldName)) : void 0,
|
|
56
|
+
onValueChange: (value) => onFieldChange(fieldName, value ?? ""),
|
|
53
57
|
children: [
|
|
54
|
-
/* @__PURE__ */ jsx(
|
|
55
|
-
enumValues.map((value) => /* @__PURE__ */ jsx(
|
|
58
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id: fieldName, size: "lg", "aria-required": required, children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("workflows.tasks.detail.form.selectOption") }) }),
|
|
59
|
+
/* @__PURE__ */ jsx(SelectContent, { children: enumValues.map((value) => /* @__PURE__ */ jsx(SelectItem, { value, children: value }, value)) })
|
|
56
60
|
]
|
|
57
61
|
}
|
|
58
62
|
)
|