@open-mercato/core 0.5.1-develop.2953.6647bb2c43 → 0.5.1-develop.2964.d5ac4a6ebb
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/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/backend/users/create/page.tsx +16 -20
- package/src/modules/business_rules/components/ActionRow.tsx +51 -32
- package/src/modules/business_rules/components/ConditionGroup.tsx +20 -9
- package/src/modules/business_rules/components/ConditionRow.tsx +24 -15
- package/src/modules/business_rules/components/RuleSetMembers.tsx +23 -13
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +47 -53
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +84 -87
- package/src/modules/catalog/components/PriceKindSettings.tsx +9 -9
- package/src/modules/catalog/components/products/ProductUomSection.tsx +85 -83
- package/src/modules/catalog/components/products/VariantBuilder.tsx +49 -33
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +12 -27
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +4 -6
- package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +5 -4
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +28 -15
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +37 -26
- package/src/modules/customers/components/AddressEditor.tsx +30 -16
- package/src/modules/customers/components/AddressFormatSettings.tsx +25 -19
- package/src/modules/customers/components/detail/ActivityForm.tsx +35 -23
- package/src/modules/customers/components/detail/AnnualRevenueField.tsx +2 -2
- package/src/modules/customers/components/detail/DealForm.tsx +33 -20
- package/src/modules/customers/components/formConfig.tsx +25 -17
- package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +3 -2
- package/src/modules/customers/widgets/dashboard/new-customers/widget.client.tsx +21 -11
- package/src/modules/customers/widgets/dashboard/new-deals/widget.client.tsx +3 -2
- package/src/modules/customers/widgets/dashboard/next-interactions/widget.client.tsx +3 -2
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +17 -22
- package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.tsx +17 -7
- package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +20 -10
- package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +3 -2
- package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +3 -2
- package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +20 -9
- package/src/modules/data_sync/backend/data-sync/page.tsx +64 -38
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +18 -7
- package/src/modules/dictionaries/components/AppearanceSelector.tsx +4 -4
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +3 -4
- package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +27 -21
- package/src/modules/dictionaries/fields/dictionary.tsx +36 -23
- package/src/modules/entities/components/EncryptionManager.tsx +49 -33
- package/src/modules/feature_toggles/components/formConfig.tsx +20 -10
- package/src/modules/feature_toggles/components/overrideFormConfig.tsx +20 -10
- package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +19 -10
- package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +49 -26
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +20 -11
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +19 -9
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +34 -21
- package/src/modules/resources/components/ResourceCrudForm.tsx +24 -15
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +12 -15
- package/src/modules/sales/components/ProviderFieldInput.tsx +26 -17
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +28 -20
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +51 -46
- package/src/modules/sales/components/documents/AddressesSection.tsx +78 -76
- package/src/modules/sales/components/documents/AdjustmentDialog.tsx +27 -15
- package/src/modules/sales/components/documents/LineItemDialog.tsx +69 -51
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +98 -87
- package/src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx +23 -12
- package/src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx +23 -12
- package/src/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.tsx +35 -19
- package/src/modules/staff/components/TeamMemberForm.tsx +23 -14
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +51 -23
- package/src/modules/workflows/components/ActivitiesEditor.tsx +20 -10
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +28 -18
- package/src/modules/workflows/components/EdgeEditDialog.tsx +51 -40
- package/src/modules/workflows/components/NodeEditDialog.tsx +81 -77
- package/src/modules/workflows/components/StepsEditor.tsx +20 -10
- package/src/modules/workflows/components/TransitionsEditor.tsx +61 -44
- package/src/modules/workflows/components/fields/ActivityArrayEditor.tsx +22 -12
- package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +9 -13
- package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +27 -17
- package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +9 -12
- package/src/modules/workflows/components/mobile/MobileTaskForm.tsx +19 -11
- package/src/modules/workflows/frontend/checkout-demo/page.tsx +71 -60
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { X, ChevronUp, ChevronDown } from "lucide-react";
|
|
4
|
+
import { Input } from "@open-mercato/ui/primitives/input";
|
|
5
|
+
import {
|
|
6
|
+
Select,
|
|
7
|
+
SelectContent,
|
|
8
|
+
SelectItem,
|
|
9
|
+
SelectTrigger,
|
|
10
|
+
SelectValue
|
|
11
|
+
} from "@open-mercato/ui/primitives/select";
|
|
4
12
|
import { getActionTypeOptions, getRequiredConfigFields, getOptionalConfigFields } from "./utils/actionValidation.js";
|
|
5
13
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
6
14
|
function ActionRow({
|
|
@@ -45,13 +53,13 @@ function ActionRow({
|
|
|
45
53
|
required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: t("business_rules.components.actionRow.actionType.required") })
|
|
46
54
|
] }),
|
|
47
55
|
/* @__PURE__ */ jsx(
|
|
48
|
-
|
|
56
|
+
Input,
|
|
49
57
|
{
|
|
50
58
|
type: "text",
|
|
51
59
|
value,
|
|
52
60
|
onChange: (e) => handleConfigChange(field, e.target.value.split(",").map((s) => s.trim())),
|
|
53
61
|
placeholder: t("business_rules.components.actionRow.config.recipients.placeholder"),
|
|
54
|
-
className: "col-span-3
|
|
62
|
+
className: "col-span-3"
|
|
55
63
|
}
|
|
56
64
|
),
|
|
57
65
|
/* @__PURE__ */ jsx("div", { className: "col-span-4 col-start-2", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("business_rules.components.actionRow.config.recipients.help") }) })
|
|
@@ -61,16 +69,18 @@ function ActionRow({
|
|
|
61
69
|
return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-4 gap-2 items-center", children: [
|
|
62
70
|
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground col-span-1", children: t("business_rules.components.actionRow.config.level") }),
|
|
63
71
|
/* @__PURE__ */ jsxs(
|
|
64
|
-
|
|
72
|
+
Select,
|
|
65
73
|
{
|
|
66
74
|
value: value || "info",
|
|
67
|
-
|
|
68
|
-
className: "col-span-3 px-2 py-1.5 text-sm border border-border rounded bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
75
|
+
onValueChange: (next) => handleConfigChange(field, next),
|
|
69
76
|
children: [
|
|
70
|
-
/* @__PURE__ */ jsx(
|
|
71
|
-
/* @__PURE__ */
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "col-span-3", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
78
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
79
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "info", children: t("business_rules.components.actionRow.config.level.info") }),
|
|
80
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "warn", children: t("business_rules.components.actionRow.config.level.warn") }),
|
|
81
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "error", children: t("business_rules.components.actionRow.config.level.error") }),
|
|
82
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "debug", children: t("business_rules.components.actionRow.config.level.debug") })
|
|
83
|
+
] })
|
|
74
84
|
]
|
|
75
85
|
}
|
|
76
86
|
)
|
|
@@ -80,17 +90,19 @@ function ActionRow({
|
|
|
80
90
|
return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-4 gap-2 items-center", children: [
|
|
81
91
|
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground col-span-1", children: t("business_rules.components.actionRow.config.method") }),
|
|
82
92
|
/* @__PURE__ */ jsxs(
|
|
83
|
-
|
|
93
|
+
Select,
|
|
84
94
|
{
|
|
85
95
|
value: value || "POST",
|
|
86
|
-
|
|
87
|
-
className: "col-span-3 px-2 py-1.5 text-sm border border-border rounded bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
96
|
+
onValueChange: (next) => handleConfigChange(field, next),
|
|
88
97
|
children: [
|
|
89
|
-
/* @__PURE__ */ jsx(
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
98
|
+
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "col-span-3", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
99
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
100
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "GET", children: "GET" }),
|
|
101
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "POST", children: "POST" }),
|
|
102
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "PUT", children: "PUT" }),
|
|
103
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "PATCH", children: "PATCH" }),
|
|
104
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "DELETE", children: "DELETE" })
|
|
105
|
+
] })
|
|
94
106
|
]
|
|
95
107
|
}
|
|
96
108
|
)
|
|
@@ -123,13 +135,13 @@ function ActionRow({
|
|
|
123
135
|
required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: t("business_rules.components.actionRow.actionType.required") })
|
|
124
136
|
] }),
|
|
125
137
|
/* @__PURE__ */ jsx(
|
|
126
|
-
|
|
138
|
+
Input,
|
|
127
139
|
{
|
|
128
140
|
type: "text",
|
|
129
141
|
value,
|
|
130
142
|
onChange: (e) => handleConfigChange(field, e.target.value),
|
|
131
143
|
placeholder: t("business_rules.components.actionRow.config.field.placeholder", { field }),
|
|
132
|
-
className: "col-span-3
|
|
144
|
+
className: "col-span-3"
|
|
133
145
|
}
|
|
134
146
|
)
|
|
135
147
|
] }, field);
|
|
@@ -143,14 +155,13 @@ function ActionRow({
|
|
|
143
155
|
/* @__PURE__ */ jsx("span", { className: "text-red-500", children: t("business_rules.components.actionRow.actionType.required") })
|
|
144
156
|
] }),
|
|
145
157
|
/* @__PURE__ */ jsxs(
|
|
146
|
-
|
|
158
|
+
Select,
|
|
147
159
|
{
|
|
148
|
-
value: action.type ||
|
|
149
|
-
|
|
150
|
-
className: "col-span-3 px-2 py-1.5 text-sm border border-border rounded bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring font-medium",
|
|
160
|
+
value: action.type || void 0,
|
|
161
|
+
onValueChange: (value) => handleTypeChange({ target: { value } }),
|
|
151
162
|
children: [
|
|
152
|
-
/* @__PURE__ */ jsx(
|
|
153
|
-
actionTypes.map((type) => /* @__PURE__ */ jsx(
|
|
163
|
+
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "col-span-3 font-medium", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("business_rules.components.actionRow.actionType.placeholder") }) }),
|
|
164
|
+
/* @__PURE__ */ jsx(SelectContent, { children: actionTypes.map((type) => /* @__PURE__ */ jsx(SelectItem, { value: type.value, children: type.label }, type.value)) })
|
|
154
165
|
]
|
|
155
166
|
}
|
|
156
167
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/business_rules/components/ActionRow.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { X, ChevronUp, ChevronDown } from 'lucide-react'\nimport type { Action } from './utils/actionValidation'\nimport { getActionTypeOptions, getRequiredConfigFields, getOptionalConfigFields } from './utils/actionValidation'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ActionRowProps = {\n action: Action\n index: number\n onChange: (index: number, action: Action) => void\n onDelete: (index: number) => void\n onMoveUp?: (index: number) => void\n onMoveDown?: (index: number) => void\n canMoveUp?: boolean\n canMoveDown?: boolean\n error?: string\n}\n\nexport function ActionRow({\n action,\n index,\n onChange,\n onDelete,\n onMoveUp,\n onMoveDown,\n canMoveUp,\n canMoveDown,\n error,\n}: ActionRowProps) {\n const t = useT()\n const actionTypes = getActionTypeOptions(t)\n const requiredFields = getRequiredConfigFields(action.type)\n const optionalFields = getOptionalConfigFields(action.type)\n\n const handleTypeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n onChange(index, {\n ...action,\n type: e.target.value,\n config: {}, // Reset config when type changes\n })\n }\n\n const handleConfigChange = (field: string, value: any) => {\n onChange(index, {\n ...action,\n config: {\n ...(action.config || {}),\n [field]: value,\n },\n })\n }\n\n const renderConfigField = (field: string, required: boolean) => {\n const value = action.config?.[field] || ''\n\n // Special handling for different field types\n if (field === 'recipients' && action.type === 'NOTIFY') {\n return (\n <div key={field} className=\"grid grid-cols-4 gap-2 items-start\">\n <label className=\"text-xs font-medium text-foreground col-span-1\">\n {t('business_rules.components.actionRow.config.recipients')} {required && <span className=\"text-red-500\">{t('business_rules.components.actionRow.actionType.required')}</span>}\n </label>\n <
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { X, ChevronUp, ChevronDown } from 'lucide-react'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport type { Action } from './utils/actionValidation'\nimport { getActionTypeOptions, getRequiredConfigFields, getOptionalConfigFields } from './utils/actionValidation'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ActionRowProps = {\n action: Action\n index: number\n onChange: (index: number, action: Action) => void\n onDelete: (index: number) => void\n onMoveUp?: (index: number) => void\n onMoveDown?: (index: number) => void\n canMoveUp?: boolean\n canMoveDown?: boolean\n error?: string\n}\n\nexport function ActionRow({\n action,\n index,\n onChange,\n onDelete,\n onMoveUp,\n onMoveDown,\n canMoveUp,\n canMoveDown,\n error,\n}: ActionRowProps) {\n const t = useT()\n const actionTypes = getActionTypeOptions(t)\n const requiredFields = getRequiredConfigFields(action.type)\n const optionalFields = getOptionalConfigFields(action.type)\n\n const handleTypeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n onChange(index, {\n ...action,\n type: e.target.value,\n config: {}, // Reset config when type changes\n })\n }\n\n const handleConfigChange = (field: string, value: any) => {\n onChange(index, {\n ...action,\n config: {\n ...(action.config || {}),\n [field]: value,\n },\n })\n }\n\n const renderConfigField = (field: string, required: boolean) => {\n const value = action.config?.[field] || ''\n\n // Special handling for different field types\n if (field === 'recipients' && action.type === 'NOTIFY') {\n return (\n <div key={field} className=\"grid grid-cols-4 gap-2 items-start\">\n <label className=\"text-xs font-medium text-foreground col-span-1\">\n {t('business_rules.components.actionRow.config.recipients')} {required && <span className=\"text-red-500\">{t('business_rules.components.actionRow.actionType.required')}</span>}\n </label>\n <Input\n type=\"text\"\n value={value}\n onChange={(e) => handleConfigChange(field, e.target.value.split(',').map((s) => s.trim()))}\n placeholder={t('business_rules.components.actionRow.config.recipients.placeholder')}\n className=\"col-span-3\"\n />\n <div className=\"col-span-4 col-start-2\">\n <p className=\"text-xs text-muted-foreground\">{t('business_rules.components.actionRow.config.recipients.help')}</p>\n </div>\n </div>\n )\n }\n\n if (field === 'level' && action.type === 'LOG') {\n return (\n <div key={field} className=\"grid grid-cols-4 gap-2 items-center\">\n <label className=\"text-xs font-medium text-foreground col-span-1\">{t('business_rules.components.actionRow.config.level')}</label>\n <Select\n value={value || 'info'}\n onValueChange={(next) => handleConfigChange(field, next)}\n >\n <SelectTrigger size=\"sm\" className=\"col-span-3\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"info\">{t('business_rules.components.actionRow.config.level.info')}</SelectItem>\n <SelectItem value=\"warn\">{t('business_rules.components.actionRow.config.level.warn')}</SelectItem>\n <SelectItem value=\"error\">{t('business_rules.components.actionRow.config.level.error')}</SelectItem>\n <SelectItem value=\"debug\">{t('business_rules.components.actionRow.config.level.debug')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n )\n }\n\n if (field === 'method' && action.type === 'CALL_WEBHOOK') {\n return (\n <div key={field} className=\"grid grid-cols-4 gap-2 items-center\">\n <label className=\"text-xs font-medium text-foreground col-span-1\">{t('business_rules.components.actionRow.config.method')}</label>\n <Select\n value={value || 'POST'}\n onValueChange={(next) => handleConfigChange(field, next)}\n >\n <SelectTrigger size=\"sm\" className=\"col-span-3\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"GET\">GET</SelectItem>\n <SelectItem value=\"POST\">POST</SelectItem>\n <SelectItem value=\"PUT\">PUT</SelectItem>\n <SelectItem value=\"PATCH\">PATCH</SelectItem>\n <SelectItem value=\"DELETE\">DELETE</SelectItem>\n </SelectContent>\n </Select>\n </div>\n )\n }\n\n if (field === 'message') {\n return (\n <div key={field} className=\"grid grid-cols-4 gap-2 items-start\">\n <label className=\"text-xs font-medium text-foreground col-span-1\">\n {t('business_rules.components.actionRow.config.message')} {required && <span className=\"text-red-500\">{t('business_rules.components.actionRow.actionType.required')}</span>}\n </label>\n <textarea\n value={value}\n onChange={(e) => handleConfigChange(field, e.target.value)}\n placeholder={t('business_rules.components.actionRow.config.message.placeholder')}\n rows={2}\n className=\"col-span-3 px-2 py-1.5 text-sm border border-border rounded bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n <div className=\"col-span-4 col-start-2\">\n <p className=\"text-xs text-muted-foreground\">{t('business_rules.components.actionRow.config.message.help')}</p>\n </div>\n </div>\n )\n }\n\n // Default text input\n return (\n <div key={field} className=\"grid grid-cols-4 gap-2 items-center\">\n <label className=\"text-xs font-medium text-foreground col-span-1\">\n {field} {required && <span className=\"text-red-500\">{t('business_rules.components.actionRow.actionType.required')}</span>}\n </label>\n <Input\n type=\"text\"\n value={value}\n onChange={(e) => handleConfigChange(field, e.target.value)}\n placeholder={t('business_rules.components.actionRow.config.field.placeholder', { field })}\n className=\"col-span-3\"\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex items-start gap-2 p-3 bg-muted rounded border border-border\">\n <div className=\"flex-1 space-y-2\">\n {/* Action Type */}\n <div className=\"grid grid-cols-4 gap-2 items-center\">\n <label className=\"text-xs font-medium text-foreground col-span-1\">\n {t('business_rules.components.actionRow.actionType')} <span className=\"text-red-500\">{t('business_rules.components.actionRow.actionType.required')}</span>\n </label>\n <Select\n value={action.type || undefined}\n onValueChange={(value) => handleTypeChange({ target: { value } } as React.ChangeEvent<HTMLSelectElement>)}\n >\n <SelectTrigger size=\"sm\" className=\"col-span-3 font-medium\">\n <SelectValue placeholder={t('business_rules.components.actionRow.actionType.placeholder')} />\n </SelectTrigger>\n <SelectContent>\n {actionTypes.map((type) => (\n <SelectItem key={type.value} value={type.value}>\n {type.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {/* Config Fields */}\n {action.type && (\n <>\n {requiredFields.map((field) => renderConfigField(field, true))}\n {optionalFields.map((field) => renderConfigField(field, false))}\n </>\n )}\n\n {/* Error Display */}\n {error && (\n <div className=\"mt-2\">\n <p className=\"text-xs text-red-600\">{error}</p>\n </div>\n )}\n </div>\n\n {/* Control Buttons */}\n <div className=\"flex flex-col gap-1\">\n {onMoveUp && (\n <button\n type=\"button\"\n onClick={() => onMoveUp(index)}\n disabled={!canMoveUp}\n className=\"p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n title={t('business_rules.components.actionRow.moveUp')}\n >\n <ChevronUp className=\"w-4 h-4\" />\n </button>\n )}\n {onMoveDown && (\n <button\n type=\"button\"\n onClick={() => onMoveDown(index)}\n disabled={!canMoveDown}\n className=\"p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n title={t('business_rules.components.actionRow.moveDown')}\n >\n <ChevronDown className=\"w-4 h-4\" />\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => onDelete(index)}\n className=\"p-1 text-muted-foreground hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors\"\n title={t('business_rules.components.actionRow.delete')}\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Plus, X } from "lucide-react";
|
|
4
4
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
5
|
+
import {
|
|
6
|
+
Select,
|
|
7
|
+
SelectContent,
|
|
8
|
+
SelectItem,
|
|
9
|
+
SelectTrigger,
|
|
10
|
+
SelectValue
|
|
11
|
+
} from "@open-mercato/ui/primitives/select";
|
|
5
12
|
import { ConditionRow } from "./ConditionRow.js";
|
|
6
13
|
import { isGroupCondition, getLogicalOperators } from "./utils/conditionValidation.js";
|
|
7
14
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
@@ -80,13 +87,15 @@ function ConditionGroup({ group, onChange, onDelete, depth, maxDepth = 5, entity
|
|
|
80
87
|
children: [
|
|
81
88
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
82
89
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: t("business_rules.components.conditionGroup.group", { depth: depth + 1 }) }),
|
|
83
|
-
/* @__PURE__ */
|
|
84
|
-
|
|
90
|
+
/* @__PURE__ */ jsxs(
|
|
91
|
+
Select,
|
|
85
92
|
{
|
|
86
93
|
value: group.operator,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
onValueChange: (value) => handleOperatorChange({ target: { value } }),
|
|
95
|
+
children: [
|
|
96
|
+
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-auto min-w-[6rem] font-semibold", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
97
|
+
/* @__PURE__ */ jsx(SelectContent, { children: logicalOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: op.label }, op.value)) })
|
|
98
|
+
]
|
|
90
99
|
}
|
|
91
100
|
),
|
|
92
101
|
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/business_rules/components/ConditionGroup.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Plus, X } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { ConditionRow } from './ConditionRow'\nimport type { GroupCondition, ConditionExpression, SimpleCondition } from './utils/conditionValidation'\nimport type { LogicalOperator } from './../data/validators'\nimport { isGroupCondition, getLogicalOperators } from './utils/conditionValidation'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ConditionGroupProps = {\n group: GroupCondition\n onChange: (group: GroupCondition) => void\n onDelete?: () => void\n depth: number\n maxDepth?: number\n entityType?: string\n}\n\nconst DEPTH_COLORS = [\n 'border-blue-300 bg-blue-50 dark:border-blue-700 dark:bg-blue-950/50',\n 'border-green-300 bg-green-50 dark:border-green-700 dark:bg-green-950/50',\n 'border-purple-300 bg-purple-50 dark:border-purple-700 dark:bg-purple-950/50',\n 'border-orange-300 bg-orange-50 dark:border-orange-700 dark:bg-orange-950/50',\n 'border-pink-300 bg-pink-50 dark:border-pink-700 dark:bg-pink-950/50',\n]\n\nexport function ConditionGroup({ group, onChange, onDelete, depth, maxDepth = 5, entityType }: ConditionGroupProps) {\n const t = useT()\n const logicalOperators = getLogicalOperators(t)\n const colorClass = DEPTH_COLORS[depth % DEPTH_COLORS.length]\n\n const handleOperatorChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n onChange({\n ...group,\n operator: e.target.value as LogicalOperator,\n })\n }\n\n const handleRuleChange = (index: number, updatedRule: ConditionExpression) => {\n const newRules = [...group.rules]\n newRules[index] = updatedRule\n onChange({\n ...group,\n rules: newRules,\n })\n }\n\n const handleDeleteRule = (index: number) => {\n const newRules = group.rules.filter((_, i) => i !== index)\n if (newRules.length === 0) {\n // If no rules left, delete the group itself\n onDelete?.()\n } else {\n onChange({\n ...group,\n rules: newRules,\n })\n }\n }\n\n const addSimpleCondition = () => {\n const newCondition: SimpleCondition = {\n field: '',\n operator: '=',\n value: null,\n }\n onChange({\n ...group,\n rules: [...group.rules, newCondition],\n })\n }\n\n const addConditionGroup = () => {\n if (depth >= maxDepth) {\n alert(t('business_rules.components.conditionGroup.maxDepthReached', { maxDepth }))\n return\n }\n\n const newGroup: GroupCondition = {\n operator: 'AND',\n rules: [\n {\n field: '',\n operator: '=',\n value: null,\n },\n ],\n }\n onChange({\n ...group,\n rules: [...group.rules, newGroup],\n })\n }\n\n return (\n <div\n className={`p-3 rounded border-2 ${colorClass}`}\n style={{ marginLeft: depth > 0 ? `${depth * 16}px` : '0' }}\n >\n {/* Group Header */}\n <div className=\"flex items-center gap-2 mb-3\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n {t('business_rules.components.conditionGroup.group', { depth: depth + 1 })}\n </span>\n <
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Plus, X } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { ConditionRow } from './ConditionRow'\nimport type { GroupCondition, ConditionExpression, SimpleCondition } from './utils/conditionValidation'\nimport type { LogicalOperator } from './../data/validators'\nimport { isGroupCondition, getLogicalOperators } from './utils/conditionValidation'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ConditionGroupProps = {\n group: GroupCondition\n onChange: (group: GroupCondition) => void\n onDelete?: () => void\n depth: number\n maxDepth?: number\n entityType?: string\n}\n\nconst DEPTH_COLORS = [\n 'border-blue-300 bg-blue-50 dark:border-blue-700 dark:bg-blue-950/50',\n 'border-green-300 bg-green-50 dark:border-green-700 dark:bg-green-950/50',\n 'border-purple-300 bg-purple-50 dark:border-purple-700 dark:bg-purple-950/50',\n 'border-orange-300 bg-orange-50 dark:border-orange-700 dark:bg-orange-950/50',\n 'border-pink-300 bg-pink-50 dark:border-pink-700 dark:bg-pink-950/50',\n]\n\nexport function ConditionGroup({ group, onChange, onDelete, depth, maxDepth = 5, entityType }: ConditionGroupProps) {\n const t = useT()\n const logicalOperators = getLogicalOperators(t)\n const colorClass = DEPTH_COLORS[depth % DEPTH_COLORS.length]\n\n const handleOperatorChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n onChange({\n ...group,\n operator: e.target.value as LogicalOperator,\n })\n }\n\n const handleRuleChange = (index: number, updatedRule: ConditionExpression) => {\n const newRules = [...group.rules]\n newRules[index] = updatedRule\n onChange({\n ...group,\n rules: newRules,\n })\n }\n\n const handleDeleteRule = (index: number) => {\n const newRules = group.rules.filter((_, i) => i !== index)\n if (newRules.length === 0) {\n // If no rules left, delete the group itself\n onDelete?.()\n } else {\n onChange({\n ...group,\n rules: newRules,\n })\n }\n }\n\n const addSimpleCondition = () => {\n const newCondition: SimpleCondition = {\n field: '',\n operator: '=',\n value: null,\n }\n onChange({\n ...group,\n rules: [...group.rules, newCondition],\n })\n }\n\n const addConditionGroup = () => {\n if (depth >= maxDepth) {\n alert(t('business_rules.components.conditionGroup.maxDepthReached', { maxDepth }))\n return\n }\n\n const newGroup: GroupCondition = {\n operator: 'AND',\n rules: [\n {\n field: '',\n operator: '=',\n value: null,\n },\n ],\n }\n onChange({\n ...group,\n rules: [...group.rules, newGroup],\n })\n }\n\n return (\n <div\n className={`p-3 rounded border-2 ${colorClass}`}\n style={{ marginLeft: depth > 0 ? `${depth * 16}px` : '0' }}\n >\n {/* Group Header */}\n <div className=\"flex items-center gap-2 mb-3\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n {t('business_rules.components.conditionGroup.group', { depth: depth + 1 })}\n </span>\n <Select\n value={group.operator}\n onValueChange={(value) => handleOperatorChange({ target: { value } } as React.ChangeEvent<HTMLSelectElement>)}\n >\n <SelectTrigger size=\"sm\" className=\"w-auto min-w-[6rem] font-semibold\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {logicalOperators.map((op) => (\n <SelectItem key={op.value} value={op.value}>\n {op.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n <span className=\"text-xs text-muted-foreground\">\n ({t('business_rules.components.conditionGroup.ruleCount', { count: group.rules.length })})\n </span>\n\n {onDelete && (\n <button\n type=\"button\"\n onClick={onDelete}\n className=\"ml-auto p-1 text-muted-foreground hover:text-status-error-text hover:bg-status-error-bg rounded transition-colors\"\n title={t('business_rules.components.conditionGroup.deleteGroup')}\n >\n <X className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n\n {/* Rules */}\n <div className=\"space-y-2\">\n {group.rules.map((rule, index) => (\n <div key={index}>\n {isGroupCondition(rule) ? (\n // Recursive: Nested Group\n <ConditionGroup\n group={rule}\n onChange={(updatedGroup) => handleRuleChange(index, updatedGroup)}\n onDelete={() => handleDeleteRule(index)}\n depth={depth + 1}\n maxDepth={maxDepth}\n entityType={entityType}\n />\n ) : (\n // Base Case: Simple Condition\n <ConditionRow\n condition={rule}\n onChange={(updatedCondition) => handleRuleChange(index, updatedCondition)}\n onDelete={() => handleDeleteRule(index)}\n entityType={entityType}\n />\n )}\n </div>\n ))}\n </div>\n\n {/* Add Buttons */}\n <div className=\"flex gap-2 mt-3\">\n <Button\n type=\"button\"\n onClick={addSimpleCondition}\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs\"\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n {t('business_rules.components.conditionGroup.addCondition')}\n </Button>\n\n {depth < maxDepth && (\n <Button\n type=\"button\"\n onClick={addConditionGroup}\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs\"\n >\n <Plus className=\"w-3 h-3 mr-1\" />\n {t('business_rules.components.conditionGroup.addGroup', { depth: depth + 2 })}\n </Button>\n )}\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { Input } from "@open-mercato/ui/primitives/input";
|
|
5
|
+
import {
|
|
6
|
+
Select,
|
|
7
|
+
SelectContent,
|
|
8
|
+
SelectItem,
|
|
9
|
+
SelectTrigger,
|
|
10
|
+
SelectValue
|
|
11
|
+
} from "@open-mercato/ui/primitives/select";
|
|
4
12
|
import { X } from "lucide-react";
|
|
5
13
|
import { getComparisonOperators, isValidFieldPath } from "./utils/conditionValidation.js";
|
|
6
14
|
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
@@ -45,26 +53,28 @@ function ConditionRow({ condition, onChange, onDelete, error }) {
|
|
|
45
53
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
46
54
|
/* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-foreground mb-1", children: t("business_rules.components.conditionRow.field") }),
|
|
47
55
|
/* @__PURE__ */ jsx(
|
|
48
|
-
|
|
56
|
+
Input,
|
|
49
57
|
{
|
|
50
58
|
type: "text",
|
|
51
59
|
value: condition.field || "",
|
|
52
60
|
onChange: handleFieldChange,
|
|
53
61
|
placeholder: t("business_rules.components.conditionRow.field.placeholder"),
|
|
54
|
-
|
|
62
|
+
"aria-invalid": fieldError ? true : void 0
|
|
55
63
|
}
|
|
56
64
|
),
|
|
57
65
|
fieldError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-600 mt-0.5", children: t("business_rules.components.conditionRow.field.invalidPath") })
|
|
58
66
|
] }),
|
|
59
67
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
60
68
|
/* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-foreground mb-1", children: t("business_rules.components.conditionRow.operator") }),
|
|
61
|
-
/* @__PURE__ */
|
|
62
|
-
|
|
69
|
+
/* @__PURE__ */ jsxs(
|
|
70
|
+
Select,
|
|
63
71
|
{
|
|
64
72
|
value: condition.operator || "=",
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
onValueChange: (value) => handleOperatorChange({ target: { value } }),
|
|
74
|
+
children: [
|
|
75
|
+
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
76
|
+
/* @__PURE__ */ jsx(SelectContent, { children: operators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: op.label }, op.value)) })
|
|
77
|
+
]
|
|
68
78
|
}
|
|
69
79
|
)
|
|
70
80
|
] }),
|
|
@@ -83,13 +93,12 @@ function ConditionRow({ condition, onChange, onDelete, error }) {
|
|
|
83
93
|
)
|
|
84
94
|
] }),
|
|
85
95
|
/* @__PURE__ */ jsx(
|
|
86
|
-
|
|
96
|
+
Input,
|
|
87
97
|
{
|
|
88
98
|
type: "text",
|
|
89
99
|
value: useFieldComparison ? condition.valueField || "" : condition.value === null || condition.value === void 0 ? "" : typeof condition.value === "string" ? condition.value : JSON.stringify(condition.value),
|
|
90
100
|
onChange: useFieldComparison ? handleValueFieldChange : handleValueChange,
|
|
91
|
-
placeholder: useFieldComparison ? t("business_rules.components.conditionRow.field.comparisonPlaceholder") : t("business_rules.components.conditionRow.value.placeholder")
|
|
92
|
-
className: "w-full px-2 py-1.5 text-sm border border-border rounded bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
101
|
+
placeholder: useFieldComparison ? t("business_rules.components.conditionRow.field.comparisonPlaceholder") : t("business_rules.components.conditionRow.value.placeholder")
|
|
93
102
|
}
|
|
94
103
|
),
|
|
95
104
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: useFieldComparison ? t("business_rules.components.conditionRow.field.comparisonHelp") : t("business_rules.components.conditionRow.value.help") })
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/business_rules/components/ConditionRow.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { X } from 'lucide-react'\nimport type { SimpleCondition } from './utils/conditionValidation'\nimport { getComparisonOperators, isValidFieldPath } from './utils/conditionValidation'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ConditionRowProps = {\n condition: SimpleCondition\n onChange: (condition: SimpleCondition) => void\n onDelete: () => void\n entityType?: string\n error?: string\n}\n\nexport function ConditionRow({ condition, onChange, onDelete, error }: ConditionRowProps) {\n const t = useT()\n const operators = getComparisonOperators(t)\n const [useFieldComparison, setUseFieldComparison] = React.useState(!!condition.valueField)\n\n const handleFieldChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange({ ...condition, field: e.target.value })\n }\n\n const handleOperatorChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n onChange({ ...condition, operator: e.target.value as any })\n }\n\n const handleValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.target.value\n\n // Try to parse as JSON for arrays/objects\n let parsedValue: any = rawValue\n if (rawValue.trim().startsWith('[') || rawValue.trim().startsWith('{')) {\n try {\n parsedValue = JSON.parse(rawValue)\n } catch {\n // Keep as string if not valid JSON\n parsedValue = rawValue\n }\n }\n\n onChange({ ...condition, value: parsedValue, valueField: undefined })\n }\n\n const handleValueFieldChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange({ ...condition, valueField: e.target.value, value: null })\n }\n\n const toggleFieldComparison = () => {\n if (useFieldComparison) {\n onChange({ ...condition, valueField: undefined, value: null })\n setUseFieldComparison(false)\n } else {\n onChange({ ...condition, value: null, valueField: '' })\n setUseFieldComparison(true)\n }\n }\n\n // Operators that don't need a value\n const operatorNeedsValue = !['IS_EMPTY', 'IS_NOT_EMPTY'].includes(condition.operator)\n\n const fieldError = condition.field && !isValidFieldPath(condition.field)\n\n return (\n <div className=\"flex items-start gap-2 p-3 bg-muted rounded border border-border\">\n <div className=\"flex-1 grid grid-cols-1 md:grid-cols-3 gap-2\">\n {/* Field Input */}\n <div>\n <label className=\"block text-xs font-medium text-foreground mb-1\">\n {t('business_rules.components.conditionRow.field')}\n </label>\n <
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { X } from 'lucide-react'\nimport type { SimpleCondition } from './utils/conditionValidation'\nimport { getComparisonOperators, isValidFieldPath } from './utils/conditionValidation'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type ConditionRowProps = {\n condition: SimpleCondition\n onChange: (condition: SimpleCondition) => void\n onDelete: () => void\n entityType?: string\n error?: string\n}\n\nexport function ConditionRow({ condition, onChange, onDelete, error }: ConditionRowProps) {\n const t = useT()\n const operators = getComparisonOperators(t)\n const [useFieldComparison, setUseFieldComparison] = React.useState(!!condition.valueField)\n\n const handleFieldChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange({ ...condition, field: e.target.value })\n }\n\n const handleOperatorChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n onChange({ ...condition, operator: e.target.value as any })\n }\n\n const handleValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.target.value\n\n // Try to parse as JSON for arrays/objects\n let parsedValue: any = rawValue\n if (rawValue.trim().startsWith('[') || rawValue.trim().startsWith('{')) {\n try {\n parsedValue = JSON.parse(rawValue)\n } catch {\n // Keep as string if not valid JSON\n parsedValue = rawValue\n }\n }\n\n onChange({ ...condition, value: parsedValue, valueField: undefined })\n }\n\n const handleValueFieldChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange({ ...condition, valueField: e.target.value, value: null })\n }\n\n const toggleFieldComparison = () => {\n if (useFieldComparison) {\n onChange({ ...condition, valueField: undefined, value: null })\n setUseFieldComparison(false)\n } else {\n onChange({ ...condition, value: null, valueField: '' })\n setUseFieldComparison(true)\n }\n }\n\n // Operators that don't need a value\n const operatorNeedsValue = !['IS_EMPTY', 'IS_NOT_EMPTY'].includes(condition.operator)\n\n const fieldError = condition.field && !isValidFieldPath(condition.field)\n\n return (\n <div className=\"flex items-start gap-2 p-3 bg-muted rounded border border-border\">\n <div className=\"flex-1 grid grid-cols-1 md:grid-cols-3 gap-2\">\n {/* Field Input */}\n <div>\n <label className=\"block text-xs font-medium text-foreground mb-1\">\n {t('business_rules.components.conditionRow.field')}\n </label>\n <Input\n type=\"text\"\n value={condition.field || ''}\n onChange={handleFieldChange}\n placeholder={t('business_rules.components.conditionRow.field.placeholder')}\n aria-invalid={fieldError ? true : undefined}\n />\n {fieldError && (\n <p className=\"text-xs text-red-600 mt-0.5\">\n {t('business_rules.components.conditionRow.field.invalidPath')}\n </p>\n )}\n </div>\n\n {/* Operator Select */}\n <div>\n <label className=\"block text-xs font-medium text-foreground mb-1\">\n {t('business_rules.components.conditionRow.operator')}\n </label>\n <Select\n value={condition.operator || '='}\n onValueChange={(value) => handleOperatorChange({ target: { value } } as React.ChangeEvent<HTMLSelectElement>)}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {operators.map((op) => (\n <SelectItem key={op.value} value={op.value}>\n {op.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {/* Value Input */}\n {operatorNeedsValue && (\n <div>\n <div className=\"flex items-center justify-between mb-1\">\n <label className=\"block text-xs font-medium text-foreground\">\n {useFieldComparison\n ? t('business_rules.components.conditionRow.compareToField')\n : t('business_rules.components.conditionRow.value')\n }\n </label>\n <button\n type=\"button\"\n onClick={toggleFieldComparison}\n className=\"text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300\"\n title={t('business_rules.components.conditionRow.toggleFieldComparison')}\n >\n {useFieldComparison\n ? t('business_rules.components.conditionRow.useValue')\n : t('business_rules.components.conditionRow.useField')\n }\n </button>\n </div>\n <Input\n type=\"text\"\n value={\n useFieldComparison\n ? (condition.valueField || '')\n : (condition.value === null || condition.value === undefined)\n ? ''\n : typeof condition.value === 'string'\n ? condition.value\n : JSON.stringify(condition.value)\n }\n onChange={useFieldComparison ? handleValueFieldChange : handleValueChange}\n placeholder={useFieldComparison\n ? t('business_rules.components.conditionRow.field.comparisonPlaceholder')\n : t('business_rules.components.conditionRow.value.placeholder')\n }\n />\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {useFieldComparison\n ? t('business_rules.components.conditionRow.field.comparisonHelp')\n : t('business_rules.components.conditionRow.value.help')\n }\n </p>\n </div>\n )}\n </div>\n\n {/* Delete Button */}\n <button\n type=\"button\"\n onClick={onDelete}\n className=\"p-1.5 text-muted-foreground hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors\"\n title={t('business_rules.components.conditionRow.deleteCondition')}\n >\n <X className=\"w-4 h-4\" />\n </button>\n\n {/* Error Display */}\n {error && (\n <div className=\"col-span-full mt-2\">\n <p className=\"text-xs text-red-600\">{error}</p>\n </div>\n )}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
5
|
+
import { Input } from "@open-mercato/ui/primitives/input";
|
|
6
|
+
import {
|
|
7
|
+
Select,
|
|
8
|
+
SelectContent,
|
|
9
|
+
SelectItem,
|
|
10
|
+
SelectTrigger,
|
|
11
|
+
SelectValue
|
|
12
|
+
} from "@open-mercato/ui/primitives/select";
|
|
5
13
|
import { Plus, ChevronUp, ChevronDown, X } from "lucide-react";
|
|
6
14
|
import { useQuery } from "@tanstack/react-query";
|
|
7
15
|
import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
|
|
@@ -110,19 +118,18 @@ function RuleSetMembers({ members, onAdd, onUpdate, onRemove }) {
|
|
|
110
118
|
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
111
119
|
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: t("business_rules.sets.members.form.selectRule") }),
|
|
112
120
|
/* @__PURE__ */ jsxs(
|
|
113
|
-
|
|
121
|
+
Select,
|
|
114
122
|
{
|
|
115
|
-
value: selectedRuleId,
|
|
116
|
-
|
|
117
|
-
className: "w-full px-3 py-2 border border-border rounded bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
123
|
+
value: selectedRuleId || void 0,
|
|
124
|
+
onValueChange: (value) => setSelectedRuleId(value ?? ""),
|
|
118
125
|
children: [
|
|
119
|
-
/* @__PURE__ */ jsx(
|
|
120
|
-
rulesNotInSet.map((rule) => /* @__PURE__ */ jsxs(
|
|
126
|
+
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("business_rules.sets.members.form.selectRulePlaceholder") }) }),
|
|
127
|
+
/* @__PURE__ */ jsx(SelectContent, { children: rulesNotInSet.map((rule) => /* @__PURE__ */ jsxs(SelectItem, { value: rule.id, children: [
|
|
121
128
|
rule.ruleName,
|
|
122
129
|
" (",
|
|
123
130
|
rule.ruleId,
|
|
124
131
|
")"
|
|
125
|
-
] }, rule.id))
|
|
132
|
+
] }, rule.id)) })
|
|
126
133
|
]
|
|
127
134
|
}
|
|
128
135
|
)
|
|
@@ -130,13 +137,12 @@ function RuleSetMembers({ members, onAdd, onUpdate, onRemove }) {
|
|
|
130
137
|
/* @__PURE__ */ jsxs("div", { className: "w-32", children: [
|
|
131
138
|
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: t("business_rules.sets.members.form.sequence") }),
|
|
132
139
|
/* @__PURE__ */ jsx(
|
|
133
|
-
|
|
140
|
+
Input,
|
|
134
141
|
{
|
|
135
142
|
type: "number",
|
|
136
143
|
value: sequence,
|
|
137
144
|
onChange: (e) => setSequence(parseInt(e.target.value) || 0),
|
|
138
|
-
min: 0
|
|
139
|
-
className: "w-full px-3 py-2 border border-border rounded bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
145
|
+
min: 0
|
|
140
146
|
}
|
|
141
147
|
)
|
|
142
148
|
] })
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/business_rules/components/RuleSetMembers.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Plus, ChevronUp, ChevronDown, X } from 'lucide-react'\nimport { useQuery } from '@tanstack/react-query'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype Member = {\n id: string\n ruleId: string\n ruleName: string\n ruleType: string\n sequence: number\n enabled: boolean\n}\n\ntype RuleOption = {\n id: string\n ruleId: string\n ruleName: string\n ruleType: string\n}\n\ntype RuleSetMembersProps = {\n members: Member[]\n onAdd: (ruleId: string, sequence: number) => Promise<void>\n onUpdate: (memberId: string, updates: { sequence?: number; enabled?: boolean }) => Promise<void>\n onRemove: (memberId: string, ruleName: string) => Promise<void>\n}\n\nexport function RuleSetMembers({ members, onAdd, onUpdate, onRemove }: RuleSetMembersProps) {\n const t = useT()\n const [showAddForm, setShowAddForm] = React.useState(false)\n const [selectedRuleId, setSelectedRuleId] = React.useState('')\n const [sequence, setSequence] = React.useState(0)\n\n // Fetch available rules\n const { data: availableRules } = useQuery({\n queryKey: ['business-rules', 'rules-list'],\n queryFn: async () => {\n const result = await apiCall<{ items: RuleOption[] }>(\n '/api/business_rules/rules?page=1&pageSize=100&sortField=ruleName&sortDir=asc'\n )\n if (!result.ok) {\n throw new Error('Failed to fetch rules')\n }\n return result.result?.items || []\n },\n })\n\n // Filter out already added rules (memoized to avoid re-computation on every render)\n const rulesNotInSet = React.useMemo(() => {\n const memberRuleIds = new Set(members.map(m => m.ruleId))\n return availableRules?.filter(r => !memberRuleIds.has(r.id)) || []\n }, [members, availableRules])\n\n const handleAdd = async () => {\n if (!selectedRuleId) return\n await onAdd(selectedRuleId, sequence)\n setSelectedRuleId('')\n setSequence(0)\n setShowAddForm(false)\n }\n\n const handleMoveUp = async (member: Member, index: number) => {\n if (index === 0) return\n const prevMember = members[index - 1]\n // Swap sequences\n await onUpdate(member.id, { sequence: prevMember.sequence })\n await onUpdate(prevMember.id, { sequence: member.sequence })\n }\n\n const handleMoveDown = async (member: Member, index: number) => {\n if (index === members.length - 1) return\n const nextMember = members[index + 1]\n // Swap sequences\n await onUpdate(member.id, { sequence: nextMember.sequence })\n await onUpdate(nextMember.id, { sequence: member.sequence })\n }\n\n const handleToggleEnabled = async (member: Member) => {\n await onUpdate(member.id, { enabled: !member.enabled })\n }\n\n return (\n <div className=\"space-y-4\">\n {/* Members List */}\n {members.length === 0 ? (\n <div className=\"text-center py-8 text-muted-foreground\">\n <p>{t('business_rules.sets.members.empty')}</p>\n </div>\n ) : (\n <div className=\"space-y-2\">\n {members.map((member, index) => (\n <div\n key={member.id}\n className=\"flex items-center gap-3 p-3 bg-muted rounded border border-border\"\n >\n {/* Order Controls */}\n <div className=\"flex flex-col gap-1\">\n <button\n onClick={() => handleMoveUp(member, index)}\n disabled={index === 0}\n className=\"p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n title={t('common.moveUp')}\n >\n <ChevronUp className=\"w-4 h-4\" />\n </button>\n <button\n onClick={() => handleMoveDown(member, index)}\n disabled={index === members.length - 1}\n className=\"p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n title={t('common.moveDown')}\n >\n <ChevronDown className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Sequence Number */}\n <div className=\"flex items-center justify-center w-8 h-8 bg-status-info-bg text-status-info-text rounded font-mono text-sm font-medium\">\n {member.sequence}\n </div>\n\n {/* Rule Info */}\n <div className=\"flex-1\">\n <div className=\"font-medium\">{member.ruleName}</div>\n <div className=\"text-xs text-muted-foreground font-mono\">{member.ruleId}</div>\n </div>\n\n {/* Rule Type Badge */}\n <div className=\"px-2 py-1 bg-muted text-muted-foreground text-xs rounded font-medium\">\n {member.ruleType}\n </div>\n\n {/* Enabled Toggle */}\n <button\n onClick={() => handleToggleEnabled(member)}\n className={`px-2 py-1 rounded text-xs font-medium cursor-pointer ${\n member.enabled\n ? 'bg-status-success-bg text-status-success-text hover:bg-status-success-bg/80'\n : 'bg-muted text-muted-foreground hover:bg-muted/50'\n }`}\n title={t('business_rules.sets.members.actions.toggleEnabled')}\n >\n {member.enabled ? t('common.enabled') : t('common.disabled')}\n </button>\n\n {/* Remove Button */}\n <button\n onClick={() => onRemove(member.id, member.ruleName)}\n className=\"p-1.5 text-muted-foreground hover:text-status-error-text hover:bg-status-error-bg rounded transition-colors\"\n title={t('common.remove')}\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Add Rule Form */}\n {showAddForm ? (\n <div className=\"p-4 bg-status-info-bg border border-status-info-border rounded space-y-3\">\n <div className=\"flex items-end gap-3\">\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium text-foreground mb-1\">\n {t('business_rules.sets.members.form.selectRule')}\n </label>\n <
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Plus, ChevronUp, ChevronDown, X } from 'lucide-react'\nimport { useQuery } from '@tanstack/react-query'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype Member = {\n id: string\n ruleId: string\n ruleName: string\n ruleType: string\n sequence: number\n enabled: boolean\n}\n\ntype RuleOption = {\n id: string\n ruleId: string\n ruleName: string\n ruleType: string\n}\n\ntype RuleSetMembersProps = {\n members: Member[]\n onAdd: (ruleId: string, sequence: number) => Promise<void>\n onUpdate: (memberId: string, updates: { sequence?: number; enabled?: boolean }) => Promise<void>\n onRemove: (memberId: string, ruleName: string) => Promise<void>\n}\n\nexport function RuleSetMembers({ members, onAdd, onUpdate, onRemove }: RuleSetMembersProps) {\n const t = useT()\n const [showAddForm, setShowAddForm] = React.useState(false)\n const [selectedRuleId, setSelectedRuleId] = React.useState('')\n const [sequence, setSequence] = React.useState(0)\n\n // Fetch available rules\n const { data: availableRules } = useQuery({\n queryKey: ['business-rules', 'rules-list'],\n queryFn: async () => {\n const result = await apiCall<{ items: RuleOption[] }>(\n '/api/business_rules/rules?page=1&pageSize=100&sortField=ruleName&sortDir=asc'\n )\n if (!result.ok) {\n throw new Error('Failed to fetch rules')\n }\n return result.result?.items || []\n },\n })\n\n // Filter out already added rules (memoized to avoid re-computation on every render)\n const rulesNotInSet = React.useMemo(() => {\n const memberRuleIds = new Set(members.map(m => m.ruleId))\n return availableRules?.filter(r => !memberRuleIds.has(r.id)) || []\n }, [members, availableRules])\n\n const handleAdd = async () => {\n if (!selectedRuleId) return\n await onAdd(selectedRuleId, sequence)\n setSelectedRuleId('')\n setSequence(0)\n setShowAddForm(false)\n }\n\n const handleMoveUp = async (member: Member, index: number) => {\n if (index === 0) return\n const prevMember = members[index - 1]\n // Swap sequences\n await onUpdate(member.id, { sequence: prevMember.sequence })\n await onUpdate(prevMember.id, { sequence: member.sequence })\n }\n\n const handleMoveDown = async (member: Member, index: number) => {\n if (index === members.length - 1) return\n const nextMember = members[index + 1]\n // Swap sequences\n await onUpdate(member.id, { sequence: nextMember.sequence })\n await onUpdate(nextMember.id, { sequence: member.sequence })\n }\n\n const handleToggleEnabled = async (member: Member) => {\n await onUpdate(member.id, { enabled: !member.enabled })\n }\n\n return (\n <div className=\"space-y-4\">\n {/* Members List */}\n {members.length === 0 ? (\n <div className=\"text-center py-8 text-muted-foreground\">\n <p>{t('business_rules.sets.members.empty')}</p>\n </div>\n ) : (\n <div className=\"space-y-2\">\n {members.map((member, index) => (\n <div\n key={member.id}\n className=\"flex items-center gap-3 p-3 bg-muted rounded border border-border\"\n >\n {/* Order Controls */}\n <div className=\"flex flex-col gap-1\">\n <button\n onClick={() => handleMoveUp(member, index)}\n disabled={index === 0}\n className=\"p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n title={t('common.moveUp')}\n >\n <ChevronUp className=\"w-4 h-4\" />\n </button>\n <button\n onClick={() => handleMoveDown(member, index)}\n disabled={index === members.length - 1}\n className=\"p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n title={t('common.moveDown')}\n >\n <ChevronDown className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Sequence Number */}\n <div className=\"flex items-center justify-center w-8 h-8 bg-status-info-bg text-status-info-text rounded font-mono text-sm font-medium\">\n {member.sequence}\n </div>\n\n {/* Rule Info */}\n <div className=\"flex-1\">\n <div className=\"font-medium\">{member.ruleName}</div>\n <div className=\"text-xs text-muted-foreground font-mono\">{member.ruleId}</div>\n </div>\n\n {/* Rule Type Badge */}\n <div className=\"px-2 py-1 bg-muted text-muted-foreground text-xs rounded font-medium\">\n {member.ruleType}\n </div>\n\n {/* Enabled Toggle */}\n <button\n onClick={() => handleToggleEnabled(member)}\n className={`px-2 py-1 rounded text-xs font-medium cursor-pointer ${\n member.enabled\n ? 'bg-status-success-bg text-status-success-text hover:bg-status-success-bg/80'\n : 'bg-muted text-muted-foreground hover:bg-muted/50'\n }`}\n title={t('business_rules.sets.members.actions.toggleEnabled')}\n >\n {member.enabled ? t('common.enabled') : t('common.disabled')}\n </button>\n\n {/* Remove Button */}\n <button\n onClick={() => onRemove(member.id, member.ruleName)}\n className=\"p-1.5 text-muted-foreground hover:text-status-error-text hover:bg-status-error-bg rounded transition-colors\"\n title={t('common.remove')}\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n {/* Add Rule Form */}\n {showAddForm ? (\n <div className=\"p-4 bg-status-info-bg border border-status-info-border rounded space-y-3\">\n <div className=\"flex items-end gap-3\">\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium text-foreground mb-1\">\n {t('business_rules.sets.members.form.selectRule')}\n </label>\n <Select\n value={selectedRuleId || undefined}\n onValueChange={(value) => setSelectedRuleId(value ?? '')}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('business_rules.sets.members.form.selectRulePlaceholder')} />\n </SelectTrigger>\n <SelectContent>\n {rulesNotInSet.map((rule) => (\n <SelectItem key={rule.id} value={rule.id}>\n {rule.ruleName} ({rule.ruleId})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"w-32\">\n <label className=\"block text-sm font-medium text-foreground mb-1\">\n {t('business_rules.sets.members.form.sequence')}\n </label>\n <Input\n type=\"number\"\n value={sequence}\n onChange={(e) => setSequence(parseInt(e.target.value) || 0)}\n min={0}\n />\n </div>\n </div>\n\n <div className=\"flex gap-2\">\n <Button onClick={handleAdd} disabled={!selectedRuleId} size=\"sm\">\n {t('business_rules.sets.members.actions.add')}\n </Button>\n <Button\n onClick={() => {\n setShowAddForm(false)\n setSelectedRuleId('')\n setSequence(0)\n }}\n variant=\"outline\"\n size=\"sm\"\n >\n {t('common.cancel')}\n </Button>\n </div>\n </div>\n ) : (\n <Button onClick={() => setShowAddForm(true)} variant=\"outline\" size=\"sm\">\n <Plus className=\"w-4 h-4 mr-2\" />\n {t('business_rules.sets.members.actions.addRule')}\n </Button>\n )}\n\n {/* Help Text */}\n <div className=\"text-xs text-muted-foreground space-y-1\">\n <p>\n <strong>{t('business_rules.sets.members.help.ordering')}:</strong>{' '}\n {t('business_rules.sets.members.help.orderingDescription')}\n </p>\n <p>\n <strong>{t('business_rules.sets.members.help.enabled')}:</strong>{' '}\n {t('business_rules.sets.members.help.enabledDescription')}\n </p>\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|