@open-mercato/core 0.8.1-develop.7266.1.8e520bbe03 → 0.8.1-develop.7268.1.033c0546d5

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.
Files changed (128) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities.ids.generated.js +0 -4
  3. package/dist/generated/entities.ids.generated.js.map +2 -2
  4. package/dist/generated/entity-fields-registry.js +0 -21
  5. package/dist/generated/entity-fields-registry.js.map +2 -2
  6. package/dist/modules/customers/backend/customers/companies/create/page.js +5 -0
  7. package/dist/modules/customers/backend/customers/companies/create/page.js.map +2 -2
  8. package/dist/modules/wms/di.js +0 -3
  9. package/dist/modules/wms/di.js.map +2 -2
  10. package/generated/entities.ids.generated.ts +0 -4
  11. package/generated/entity-fields-registry.ts +0 -21
  12. package/package.json +7 -7
  13. package/src/modules/auth/i18n/de.json +0 -3
  14. package/src/modules/auth/i18n/en.json +0 -3
  15. package/src/modules/auth/i18n/es.json +0 -3
  16. package/src/modules/auth/i18n/ko.json +0 -3
  17. package/src/modules/auth/i18n/pl.json +0 -3
  18. package/src/modules/customer_accounts/AGENTS.md +1 -1
  19. package/src/modules/customers/backend/customers/companies/create/page.tsx +6 -0
  20. package/src/modules/wms/di.ts +0 -6
  21. package/dist/generated/entities/availability_policy/index.js +0 -41
  22. package/dist/generated/entities/availability_policy/index.js.map +0 -7
  23. package/dist/modules/availability/acl.js +0 -16
  24. package/dist/modules/availability/acl.js.map +0 -7
  25. package/dist/modules/availability/api/check/route.js +0 -95
  26. package/dist/modules/availability/api/check/route.js.map +0 -7
  27. package/dist/modules/availability/api/openapi.js +0 -27
  28. package/dist/modules/availability/api/openapi.js.map +0 -7
  29. package/dist/modules/availability/api/policies/resolve-preview/route.js +0 -58
  30. package/dist/modules/availability/api/policies/resolve-preview/route.js.map +0 -7
  31. package/dist/modules/availability/api/policies/route.js +0 -188
  32. package/dist/modules/availability/api/policies/route.js.map +0 -7
  33. package/dist/modules/availability/backend/availability/check/page.js +0 -185
  34. package/dist/modules/availability/backend/availability/check/page.js.map +0 -7
  35. package/dist/modules/availability/backend/availability/check/page.meta.js +0 -16
  36. package/dist/modules/availability/backend/availability/check/page.meta.js.map +0 -7
  37. package/dist/modules/availability/backend/availability/policies/ResolutionPreviewPanel.js +0 -79
  38. package/dist/modules/availability/backend/availability/policies/ResolutionPreviewPanel.js.map +0 -7
  39. package/dist/modules/availability/backend/availability/policies/ScopeFields.js +0 -53
  40. package/dist/modules/availability/backend/availability/policies/ScopeFields.js.map +0 -7
  41. package/dist/modules/availability/backend/availability/policies/[id]/page.js +0 -152
  42. package/dist/modules/availability/backend/availability/policies/[id]/page.js.map +0 -7
  43. package/dist/modules/availability/backend/availability/policies/[id]/page.meta.js +0 -12
  44. package/dist/modules/availability/backend/availability/policies/[id]/page.meta.js.map +0 -7
  45. package/dist/modules/availability/backend/availability/policies/create/page.js +0 -94
  46. package/dist/modules/availability/backend/availability/policies/create/page.js.map +0 -7
  47. package/dist/modules/availability/backend/availability/policies/create/page.meta.js +0 -12
  48. package/dist/modules/availability/backend/availability/policies/create/page.meta.js.map +0 -7
  49. package/dist/modules/availability/backend/availability/policies/formGroups.js +0 -75
  50. package/dist/modules/availability/backend/availability/policies/formGroups.js.map +0 -7
  51. package/dist/modules/availability/backend/availability/policies/page.js +0 -176
  52. package/dist/modules/availability/backend/availability/policies/page.js.map +0 -7
  53. package/dist/modules/availability/backend/availability/policies/page.meta.js +0 -16
  54. package/dist/modules/availability/backend/availability/policies/page.meta.js.map +0 -7
  55. package/dist/modules/availability/commands/policies.js +0 -312
  56. package/dist/modules/availability/commands/policies.js.map +0 -7
  57. package/dist/modules/availability/commands/scope.js +0 -19
  58. package/dist/modules/availability/commands/scope.js.map +0 -7
  59. package/dist/modules/availability/data/entities.js +0 -95
  60. package/dist/modules/availability/data/entities.js.map +0 -7
  61. package/dist/modules/availability/data/validators.js +0 -53
  62. package/dist/modules/availability/data/validators.js.map +0 -7
  63. package/dist/modules/availability/di.js +0 -41
  64. package/dist/modules/availability/di.js.map +0 -7
  65. package/dist/modules/availability/events.js +0 -18
  66. package/dist/modules/availability/events.js.map +0 -7
  67. package/dist/modules/availability/index.js +0 -15
  68. package/dist/modules/availability/index.js.map +0 -7
  69. package/dist/modules/availability/lib/policyResolution.js +0 -155
  70. package/dist/modules/availability/lib/policyResolution.js.map +0 -7
  71. package/dist/modules/availability/lib/tryResolve.js +0 -11
  72. package/dist/modules/availability/lib/tryResolve.js.map +0 -7
  73. package/dist/modules/availability/migrations/Migration20260922095844_availability.js +0 -16
  74. package/dist/modules/availability/migrations/Migration20260922095844_availability.js.map +0 -7
  75. package/dist/modules/availability/setup.js +0 -12
  76. package/dist/modules/availability/setup.js.map +0 -7
  77. package/dist/modules/wms/lib/availabilityCache.js +0 -85
  78. package/dist/modules/wms/lib/availabilityCache.js.map +0 -7
  79. package/dist/modules/wms/lib/availabilityCalculation.js +0 -178
  80. package/dist/modules/wms/lib/availabilityCalculation.js.map +0 -7
  81. package/dist/modules/wms/lib/availabilityProvider.js +0 -14
  82. package/dist/modules/wms/lib/availabilityProvider.js.map +0 -7
  83. package/dist/modules/wms/lib/sqlInClause.js +0 -9
  84. package/dist/modules/wms/lib/sqlInClause.js.map +0 -7
  85. package/dist/modules/wms/lib/tryResolve.js +0 -11
  86. package/dist/modules/wms/lib/tryResolve.js.map +0 -7
  87. package/dist/modules/wms/subscribers/invalidate-availability-cache.js +0 -16
  88. package/dist/modules/wms/subscribers/invalidate-availability-cache.js.map +0 -7
  89. package/generated/entities/availability_policy/index.ts +0 -19
  90. package/src/modules/availability/acl.ts +0 -12
  91. package/src/modules/availability/api/check/route.ts +0 -114
  92. package/src/modules/availability/api/openapi.ts +0 -28
  93. package/src/modules/availability/api/policies/resolve-preview/route.ts +0 -67
  94. package/src/modules/availability/api/policies/route.ts +0 -224
  95. package/src/modules/availability/backend/availability/check/page.meta.ts +0 -12
  96. package/src/modules/availability/backend/availability/check/page.tsx +0 -223
  97. package/src/modules/availability/backend/availability/policies/ResolutionPreviewPanel.tsx +0 -106
  98. package/src/modules/availability/backend/availability/policies/ScopeFields.tsx +0 -55
  99. package/src/modules/availability/backend/availability/policies/[id]/page.meta.ts +0 -8
  100. package/src/modules/availability/backend/availability/policies/[id]/page.tsx +0 -182
  101. package/src/modules/availability/backend/availability/policies/create/page.meta.ts +0 -8
  102. package/src/modules/availability/backend/availability/policies/create/page.tsx +0 -105
  103. package/src/modules/availability/backend/availability/policies/formGroups.ts +0 -77
  104. package/src/modules/availability/backend/availability/policies/page.meta.ts +0 -12
  105. package/src/modules/availability/backend/availability/policies/page.tsx +0 -196
  106. package/src/modules/availability/commands/policies.ts +0 -358
  107. package/src/modules/availability/commands/scope.ts +0 -26
  108. package/src/modules/availability/data/entities.ts +0 -92
  109. package/src/modules/availability/data/validators.ts +0 -70
  110. package/src/modules/availability/di.ts +0 -54
  111. package/src/modules/availability/events.ts +0 -17
  112. package/src/modules/availability/i18n/de.json +0 -81
  113. package/src/modules/availability/i18n/en.json +0 -81
  114. package/src/modules/availability/i18n/es.json +0 -81
  115. package/src/modules/availability/i18n/ko.json +0 -81
  116. package/src/modules/availability/i18n/pl.json +0 -81
  117. package/src/modules/availability/index.ts +0 -13
  118. package/src/modules/availability/lib/policyResolution.ts +0 -264
  119. package/src/modules/availability/lib/tryResolve.ts +0 -8
  120. package/src/modules/availability/migrations/.snapshot-open-mercato.json +0 -375
  121. package/src/modules/availability/migrations/Migration20260922095844_availability.ts +0 -13
  122. package/src/modules/availability/setup.ts +0 -10
  123. package/src/modules/wms/lib/availabilityCache.ts +0 -136
  124. package/src/modules/wms/lib/availabilityCalculation.ts +0 -289
  125. package/src/modules/wms/lib/availabilityProvider.ts +0 -29
  126. package/src/modules/wms/lib/sqlInClause.ts +0 -21
  127. package/src/modules/wms/lib/tryResolve.ts +0 -8
  128. package/src/modules/wms/subscribers/invalidate-availability-cache.ts +0 -30
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../src/modules/availability/backend/availability/policies/ScopeFields.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type PolicyScope = {\n productId: string\n variantId: string\n storeId: string\n}\n\n/**\n * Product/variant/store target fields, kept as controlled local state\n * (outside `CrudForm`'s own field list) so a value change can drive the live\n * resolution-chain preview immediately \u2014 `CrudForm` does not expose a\n * live-values callback. Rendered via `CrudForm`'s `contentHeader` slot.\n */\nexport function ScopeFields({ value, onChange, disabled }: { value: PolicyScope; onChange: (next: PolicyScope) => void; disabled?: boolean }) {\n const t = useT()\n return (\n <div className=\"grid grid-cols-1 gap-4 rounded-md border p-4 sm:grid-cols-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"availability-policy-product-id\">{t('availability.policies.form.field.productId')}</Label>\n <Input\n id=\"availability-policy-product-id\"\n value={value.productId}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, productId: e.target.value.trim() })}\n placeholder={t('availability.policies.form.field.productId.placeholder')}\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"availability-policy-variant-id\">{t('availability.policies.form.field.variantId')}</Label>\n <Input\n id=\"availability-policy-variant-id\"\n value={value.variantId}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, variantId: e.target.value.trim() })}\n placeholder={t('availability.policies.form.field.variantId.placeholder')}\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"availability-policy-store-id\">{t('availability.policies.form.field.storeId')}</Label>\n <Input\n id=\"availability-policy-store-id\"\n value={value.storeId}\n disabled={disabled}\n onChange={(e) => onChange({ ...value, storeId: e.target.value.trim() })}\n placeholder={t('availability.policies.form.field.storeId.placeholder')}\n />\n </div>\n </div>\n )\n}\n"],
5
- "mappings": ";AAsBM,SACE,KADF;AApBN,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,YAAY;AAcd,SAAS,YAAY,EAAE,OAAO,UAAU,SAAS,GAAsF;AAC5I,QAAM,IAAI,KAAK;AACf,SACE,qBAAC,SAAI,WAAU,+DACb;AAAA,yBAAC,SAAI,WAAU,eACb;AAAA,0BAAC,SAAM,SAAQ,kCAAkC,YAAE,4CAA4C,GAAE;AAAA,MACjG;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,OAAO,MAAM;AAAA,UACb;AAAA,UACA,UAAU,CAAC,MAAM,SAAS,EAAE,GAAG,OAAO,WAAW,EAAE,OAAO,MAAM,KAAK,EAAE,CAAC;AAAA,UACxE,aAAa,EAAE,wDAAwD;AAAA;AAAA,MACzE;AAAA,OACF;AAAA,IACA,qBAAC,SAAI,WAAU,eACb;AAAA,0BAAC,SAAM,SAAQ,kCAAkC,YAAE,4CAA4C,GAAE;AAAA,MACjG;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,OAAO,MAAM;AAAA,UACb;AAAA,UACA,UAAU,CAAC,MAAM,SAAS,EAAE,GAAG,OAAO,WAAW,EAAE,OAAO,MAAM,KAAK,EAAE,CAAC;AAAA,UACxE,aAAa,EAAE,wDAAwD;AAAA;AAAA,MACzE;AAAA,OACF;AAAA,IACA,qBAAC,SAAI,WAAU,eACb;AAAA,0BAAC,SAAM,SAAQ,gCAAgC,YAAE,0CAA0C,GAAE;AAAA,MAC7F;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,OAAO,MAAM;AAAA,UACb;AAAA,UACA,UAAU,CAAC,MAAM,SAAS,EAAE,GAAG,OAAO,SAAS,EAAE,OAAO,MAAM,KAAK,EAAE,CAAC;AAAA,UACtE,aAAa,EAAE,sDAAsD;AAAA;AAAA,MACvE;AAAA,OACF;AAAA,KACF;AAEJ;",
6
- "names": []
7
- }
@@ -1,152 +0,0 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import { useRouter } from "next/navigation";
5
- import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
6
- import { updateCrud, deleteCrud } from "@open-mercato/ui/backend/utils/crud";
7
- import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
8
- import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
9
- import { flash } from "@open-mercato/ui/backend/FlashMessages";
10
- import { LoadingMessage, ErrorMessage } from "@open-mercato/ui/backend/detail";
11
- import { useT } from "@open-mercato/shared/lib/i18n/context";
12
- import { useBackendChrome } from "@open-mercato/ui/backend/BackendChromeProvider";
13
- import { hasFeature } from "@open-mercato/shared/security/features";
14
- import { ScopeFields } from "../ScopeFields.js";
15
- import { ResolutionPreviewPanel } from "../ResolutionPreviewPanel.js";
16
- import { buildPolicyFieldGroups } from "../formGroups.js";
17
- function toNullableInt(value) {
18
- if (value === null || value === void 0 || value === "") return null;
19
- const parsed = typeof value === "number" ? value : parseInt(value, 10);
20
- return Number.isFinite(parsed) ? parsed : null;
21
- }
22
- function AvailabilityPolicyEditPage({ params }) {
23
- const t = useT();
24
- const router = useRouter();
25
- const id = params?.id ?? "";
26
- const { payload } = useBackendChrome();
27
- const canManage = hasFeature(payload?.grantedFeatures, "availability.policies.manage");
28
- const [policy, setPolicy] = React.useState(null);
29
- const [isLoading, setIsLoading] = React.useState(true);
30
- const [error, setError] = React.useState(null);
31
- const [scope, setScope] = React.useState({ productId: "", variantId: "", storeId: "" });
32
- React.useEffect(() => {
33
- if (!id) return;
34
- let cancelled = false;
35
- async function load() {
36
- setIsLoading(true);
37
- setError(null);
38
- try {
39
- const call = await apiCall(`/api/availability/policies?id=${encodeURIComponent(id)}`, void 0, {
40
- fallback: { items: [] }
41
- });
42
- if (cancelled) return;
43
- const record = call.ok ? call.result?.items?.[0] ?? null : null;
44
- if (!record) {
45
- setError(t("availability.policies.edit.notFound"));
46
- return;
47
- }
48
- setPolicy(record);
49
- setScope({ productId: record.productId ?? "", variantId: record.variantId ?? "", storeId: record.storeId ?? "" });
50
- } catch (e) {
51
- if (!cancelled) setError(e instanceof Error ? e.message : t("availability.policies.list.error.loadFailed"));
52
- } finally {
53
- if (!cancelled) setIsLoading(false);
54
- }
55
- }
56
- load();
57
- return () => {
58
- cancelled = true;
59
- };
60
- }, [id, t]);
61
- const groups = React.useMemo(() => buildPolicyFieldGroups(t), [t]);
62
- if (isLoading) return /* @__PURE__ */ jsx(LoadingMessage, { label: t("common.loading") });
63
- if (error || !policy) return /* @__PURE__ */ jsx(ErrorMessage, { label: error ?? t("availability.policies.edit.notFound") });
64
- return /* @__PURE__ */ jsx(
65
- CrudForm,
66
- {
67
- title: t("availability.policies.edit.title"),
68
- titleHeadingLevel: 1,
69
- backHref: "/backend/availability/policies",
70
- fields: [],
71
- groups,
72
- readOnly: !canManage,
73
- submitLabel: t("availability.policies.form.action.save"),
74
- cancelHref: "/backend/availability/policies",
75
- optimisticLockUpdatedAt: policy.updatedAt ?? null,
76
- initialValues: {
77
- isStockManaged: policy.isStockManaged,
78
- allowBackorder: policy.allowBackorder,
79
- backorderLeadTimeDays: policy.backorderLeadTimeDays,
80
- preorderReleaseAt: policy.preorderReleaseAt,
81
- lowStockThreshold: policy.lowStockThreshold,
82
- minOrderQuantity: policy.minOrderQuantity,
83
- maxOrderQuantity: policy.maxOrderQuantity,
84
- quantityIncrement: policy.quantityIncrement,
85
- hideWhenOutOfStock: policy.hideWhenOutOfStock,
86
- isActive: policy.isActive
87
- },
88
- contentHeader: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
89
- /* @__PURE__ */ jsx(ScopeFields, { value: scope, onChange: setScope, disabled: !canManage }),
90
- /* @__PURE__ */ jsx(
91
- ResolutionPreviewPanel,
92
- {
93
- productId: scope.productId,
94
- variantId: scope.variantId || null,
95
- storeId: scope.storeId || null
96
- }
97
- )
98
- ] }),
99
- deleteVisible: canManage,
100
- onDelete: async () => {
101
- await deleteCrud("availability/policies", id);
102
- flash(t("availability.policies.flash.deleted"), "success");
103
- router.push("/backend/availability/policies");
104
- },
105
- onSubmit: async (values) => {
106
- if (scope.variantId && !scope.productId) {
107
- throw createCrudFormError(
108
- t("availability.policies.errors.variantRequiresProduct"),
109
- { productId: t("availability.policies.errors.variantRequiresProduct") }
110
- );
111
- }
112
- if (values.allowBackorder && toNullableInt(values.backorderLeadTimeDays) == null) {
113
- throw createCrudFormError(
114
- t("availability.policies.errors.backorderRequiresLeadTime"),
115
- { backorderLeadTimeDays: t("availability.policies.errors.backorderRequiresLeadTime") }
116
- );
117
- }
118
- const min = toNullableInt(values.minOrderQuantity);
119
- const max = toNullableInt(values.maxOrderQuantity);
120
- if (min != null && max != null && max < min) {
121
- throw createCrudFormError(
122
- t("availability.policies.errors.maxBelowMin"),
123
- { maxOrderQuantity: t("availability.policies.errors.maxBelowMin") }
124
- );
125
- }
126
- const payloadBody = {
127
- id,
128
- productId: scope.productId || null,
129
- variantId: scope.variantId || null,
130
- storeId: scope.storeId || null,
131
- isStockManaged: !!values.isStockManaged,
132
- allowBackorder: !!values.allowBackorder,
133
- backorderLeadTimeDays: toNullableInt(values.backorderLeadTimeDays),
134
- preorderReleaseAt: values.preorderReleaseAt || null,
135
- lowStockThreshold: toNullableInt(values.lowStockThreshold),
136
- minOrderQuantity: min,
137
- maxOrderQuantity: max,
138
- quantityIncrement: toNullableInt(values.quantityIncrement),
139
- hideWhenOutOfStock: !!values.hideWhenOutOfStock,
140
- isActive: values.isActive !== false
141
- };
142
- await updateCrud("availability/policies", payloadBody);
143
- flash(t("availability.policies.flash.updated"), "success");
144
- router.push("/backend/availability/policies");
145
- }
146
- }
147
- );
148
- }
149
- export {
150
- AvailabilityPolicyEditPage as default
151
- };
152
- //# sourceMappingURL=page.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../../src/modules/availability/backend/availability/policies/%5Bid%5D/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useBackendChrome } from '@open-mercato/ui/backend/BackendChromeProvider'\nimport { hasFeature } from '@open-mercato/shared/security/features'\nimport { ScopeFields, type PolicyScope } from '../ScopeFields'\nimport { ResolutionPreviewPanel } from '../ResolutionPreviewPanel'\nimport { buildPolicyFieldGroups } from '../formGroups'\n\ntype PolicyRecord = {\n id: string\n storeId: string | null\n productId: string | null\n variantId: string | null\n isStockManaged: boolean\n allowBackorder: boolean\n backorderLeadTimeDays: number | null\n preorderReleaseAt: string | null\n lowStockThreshold: number | null\n minOrderQuantity: number | null\n maxOrderQuantity: number | null\n quantityIncrement: number | null\n hideWhenOutOfStock: boolean\n isActive: boolean\n updatedAt: string | null\n}\n\ntype FormValues = {\n isStockManaged?: boolean\n allowBackorder?: boolean\n backorderLeadTimeDays?: number | string | null\n preorderReleaseAt?: string | null\n lowStockThreshold?: number | string | null\n minOrderQuantity?: number | string | null\n maxOrderQuantity?: number | string | null\n quantityIncrement?: number | string | null\n hideWhenOutOfStock?: boolean\n isActive?: boolean\n}\n\nfunction toNullableInt(value: number | string | null | undefined): number | null {\n if (value === null || value === undefined || value === '') return null\n const parsed = typeof value === 'number' ? value : parseInt(value, 10)\n return Number.isFinite(parsed) ? parsed : null\n}\n\nexport default function AvailabilityPolicyEditPage({ params }: { params?: { id?: string } }) {\n const t = useT()\n const router = useRouter()\n const id = params?.id ?? ''\n const { payload } = useBackendChrome()\n const canManage = hasFeature(payload?.grantedFeatures, 'availability.policies.manage')\n\n const [policy, setPolicy] = React.useState<PolicyRecord | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [scope, setScope] = React.useState<PolicyScope>({ productId: '', variantId: '', storeId: '' })\n\n React.useEffect(() => {\n if (!id) return\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setError(null)\n try {\n const call = await apiCall<{ items: PolicyRecord[] }>(`/api/availability/policies?id=${encodeURIComponent(id)}`, undefined, {\n fallback: { items: [] },\n })\n if (cancelled) return\n const record = call.ok ? call.result?.items?.[0] ?? null : null\n if (!record) {\n setError(t('availability.policies.edit.notFound'))\n return\n }\n setPolicy(record)\n setScope({ productId: record.productId ?? '', variantId: record.variantId ?? '', storeId: record.storeId ?? '' })\n } catch (e) {\n if (!cancelled) setError(e instanceof Error ? e.message : t('availability.policies.list.error.loadFailed'))\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [id, t])\n\n const groups = React.useMemo(() => buildPolicyFieldGroups(t), [t])\n\n if (isLoading) return <LoadingMessage label={t('common.loading')} />\n if (error || !policy) return <ErrorMessage label={error ?? t('availability.policies.edit.notFound')} />\n\n return (\n <CrudForm<FormValues>\n title={t('availability.policies.edit.title')}\n titleHeadingLevel={1}\n backHref=\"/backend/availability/policies\"\n fields={[]}\n groups={groups}\n readOnly={!canManage}\n submitLabel={t('availability.policies.form.action.save')}\n cancelHref=\"/backend/availability/policies\"\n optimisticLockUpdatedAt={policy.updatedAt ?? null}\n initialValues={{\n isStockManaged: policy.isStockManaged,\n allowBackorder: policy.allowBackorder,\n backorderLeadTimeDays: policy.backorderLeadTimeDays,\n preorderReleaseAt: policy.preorderReleaseAt,\n lowStockThreshold: policy.lowStockThreshold,\n minOrderQuantity: policy.minOrderQuantity,\n maxOrderQuantity: policy.maxOrderQuantity,\n quantityIncrement: policy.quantityIncrement,\n hideWhenOutOfStock: policy.hideWhenOutOfStock,\n isActive: policy.isActive,\n }}\n contentHeader={(\n <div className=\"space-y-4\">\n <ScopeFields value={scope} onChange={setScope} disabled={!canManage} />\n <ResolutionPreviewPanel\n productId={scope.productId}\n variantId={scope.variantId || null}\n storeId={scope.storeId || null}\n />\n </div>\n )}\n deleteVisible={canManage}\n onDelete={async () => {\n await deleteCrud('availability/policies', id)\n flash(t('availability.policies.flash.deleted'), 'success')\n router.push('/backend/availability/policies')\n }}\n onSubmit={async (values) => {\n if (scope.variantId && !scope.productId) {\n throw createCrudFormError(\n t('availability.policies.errors.variantRequiresProduct'),\n { productId: t('availability.policies.errors.variantRequiresProduct') },\n )\n }\n if (values.allowBackorder && toNullableInt(values.backorderLeadTimeDays) == null) {\n throw createCrudFormError(\n t('availability.policies.errors.backorderRequiresLeadTime'),\n { backorderLeadTimeDays: t('availability.policies.errors.backorderRequiresLeadTime') },\n )\n }\n const min = toNullableInt(values.minOrderQuantity)\n const max = toNullableInt(values.maxOrderQuantity)\n if (min != null && max != null && max < min) {\n throw createCrudFormError(\n t('availability.policies.errors.maxBelowMin'),\n { maxOrderQuantity: t('availability.policies.errors.maxBelowMin') },\n )\n }\n\n const payloadBody = {\n id,\n productId: scope.productId || null,\n variantId: scope.variantId || null,\n storeId: scope.storeId || null,\n isStockManaged: !!values.isStockManaged,\n allowBackorder: !!values.allowBackorder,\n backorderLeadTimeDays: toNullableInt(values.backorderLeadTimeDays),\n preorderReleaseAt: values.preorderReleaseAt || null,\n lowStockThreshold: toNullableInt(values.lowStockThreshold),\n minOrderQuantity: min,\n maxOrderQuantity: max,\n quantityIncrement: toNullableInt(values.quantityIncrement),\n hideWhenOutOfStock: !!values.hideWhenOutOfStock,\n isActive: values.isActive !== false,\n }\n await updateCrud('availability/policies', payloadBody)\n flash(t('availability.policies.flash.updated'), 'success')\n router.push('/backend/availability/policies')\n }}\n />\n )\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,12 +0,0 @@
1
- const metadata = {
2
- requireAuth: true,
3
- requireFeatures: ["availability.policies.view"],
4
- breadcrumb: [
5
- { label: "Availability Policies", labelKey: "availability.policies.nav.title", href: "/backend/availability/policies" },
6
- { label: "Edit", labelKey: "availability.policies.edit.title" }
7
- ]
8
- };
9
- export {
10
- metadata
11
- };
12
- //# sourceMappingURL=page.meta.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../../src/modules/availability/backend/availability/policies/%5Bid%5D/page.meta.ts"],
4
- "sourcesContent": ["export const metadata = {\n requireAuth: true,\n requireFeatures: ['availability.policies.view'],\n breadcrumb: [\n { label: 'Availability Policies', labelKey: 'availability.policies.nav.title', href: '/backend/availability/policies' },\n { label: 'Edit', labelKey: 'availability.policies.edit.title' },\n ],\n}\n"],
5
- "mappings": "AAAO,MAAM,WAAW;AAAA,EACtB,aAAa;AAAA,EACb,iBAAiB,CAAC,4BAA4B;AAAA,EAC9C,YAAY;AAAA,IACV,EAAE,OAAO,yBAAyB,UAAU,mCAAmC,MAAM,iCAAiC;AAAA,IACtH,EAAE,OAAO,QAAQ,UAAU,mCAAmC;AAAA,EAChE;AACF;",
6
- "names": []
7
- }
@@ -1,94 +0,0 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import { useRouter } from "next/navigation";
5
- import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
6
- import { createCrud } from "@open-mercato/ui/backend/utils/crud";
7
- import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
8
- import { flash } from "@open-mercato/ui/backend/FlashMessages";
9
- import { useT } from "@open-mercato/shared/lib/i18n/context";
10
- import { useOrganizationScopeDetail } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
11
- import { ScopeFields } from "../ScopeFields.js";
12
- import { ResolutionPreviewPanel } from "../ResolutionPreviewPanel.js";
13
- import { buildPolicyFieldGroups } from "../formGroups.js";
14
- function toNullableInt(value) {
15
- if (value === null || value === void 0 || value === "") return null;
16
- const parsed = typeof value === "number" ? value : parseInt(value, 10);
17
- return Number.isFinite(parsed) ? parsed : null;
18
- }
19
- function AvailabilityPolicyCreatePage() {
20
- const t = useT();
21
- const router = useRouter();
22
- const { organizationId, tenantId } = useOrganizationScopeDetail();
23
- const [scope, setScope] = React.useState({ productId: "", variantId: "", storeId: "" });
24
- const groups = React.useMemo(() => buildPolicyFieldGroups(t), [t]);
25
- return /* @__PURE__ */ jsx(
26
- CrudForm,
27
- {
28
- title: t("availability.policies.create.title"),
29
- titleHeadingLevel: 1,
30
- backHref: "/backend/availability/policies",
31
- fields: [],
32
- groups,
33
- submitLabel: t("availability.policies.form.action.create"),
34
- cancelHref: "/backend/availability/policies",
35
- contentHeader: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
36
- /* @__PURE__ */ jsx(ScopeFields, { value: scope, onChange: setScope }),
37
- /* @__PURE__ */ jsx(
38
- ResolutionPreviewPanel,
39
- {
40
- productId: scope.productId,
41
- variantId: scope.variantId || null,
42
- storeId: scope.storeId || null
43
- }
44
- )
45
- ] }),
46
- onSubmit: async (values) => {
47
- if (scope.variantId && !scope.productId) {
48
- throw createCrudFormError(
49
- t("availability.policies.errors.variantRequiresProduct"),
50
- { productId: t("availability.policies.errors.variantRequiresProduct") }
51
- );
52
- }
53
- if (values.allowBackorder && toNullableInt(values.backorderLeadTimeDays) == null) {
54
- throw createCrudFormError(
55
- t("availability.policies.errors.backorderRequiresLeadTime"),
56
- { backorderLeadTimeDays: t("availability.policies.errors.backorderRequiresLeadTime") }
57
- );
58
- }
59
- const min = toNullableInt(values.minOrderQuantity);
60
- const max = toNullableInt(values.maxOrderQuantity);
61
- if (min != null && max != null && max < min) {
62
- throw createCrudFormError(
63
- t("availability.policies.errors.maxBelowMin"),
64
- { maxOrderQuantity: t("availability.policies.errors.maxBelowMin") }
65
- );
66
- }
67
- const payload = {
68
- organizationId,
69
- tenantId,
70
- productId: scope.productId || null,
71
- variantId: scope.variantId || null,
72
- storeId: scope.storeId || null,
73
- isStockManaged: !!values.isStockManaged,
74
- allowBackorder: !!values.allowBackorder,
75
- backorderLeadTimeDays: toNullableInt(values.backorderLeadTimeDays),
76
- preorderReleaseAt: values.preorderReleaseAt || null,
77
- lowStockThreshold: toNullableInt(values.lowStockThreshold),
78
- minOrderQuantity: min,
79
- maxOrderQuantity: max,
80
- quantityIncrement: toNullableInt(values.quantityIncrement),
81
- hideWhenOutOfStock: !!values.hideWhenOutOfStock,
82
- isActive: values.isActive !== false
83
- };
84
- await createCrud("availability/policies", payload);
85
- flash(t("availability.policies.flash.created"), "success");
86
- router.push("/backend/availability/policies");
87
- }
88
- }
89
- );
90
- }
91
- export {
92
- AvailabilityPolicyCreatePage as default
93
- };
94
- //# sourceMappingURL=page.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../../src/modules/availability/backend/availability/policies/create/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { createCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { ScopeFields, type PolicyScope } from '../ScopeFields'\nimport { ResolutionPreviewPanel } from '../ResolutionPreviewPanel'\nimport { buildPolicyFieldGroups } from '../formGroups'\n\ntype FormValues = {\n isStockManaged?: boolean\n allowBackorder?: boolean\n backorderLeadTimeDays?: number | string | null\n preorderReleaseAt?: string | null\n lowStockThreshold?: number | string | null\n minOrderQuantity?: number | string | null\n maxOrderQuantity?: number | string | null\n quantityIncrement?: number | string | null\n hideWhenOutOfStock?: boolean\n isActive?: boolean\n}\n\nfunction toNullableInt(value: number | string | null | undefined): number | null {\n if (value === null || value === undefined || value === '') return null\n const parsed = typeof value === 'number' ? value : parseInt(value, 10)\n return Number.isFinite(parsed) ? parsed : null\n}\n\nexport default function AvailabilityPolicyCreatePage() {\n const t = useT()\n const router = useRouter()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const [scope, setScope] = React.useState<PolicyScope>({ productId: '', variantId: '', storeId: '' })\n\n const groups = React.useMemo(() => buildPolicyFieldGroups(t), [t])\n\n return (\n <CrudForm<FormValues>\n title={t('availability.policies.create.title')}\n titleHeadingLevel={1}\n backHref=\"/backend/availability/policies\"\n fields={[]}\n groups={groups}\n submitLabel={t('availability.policies.form.action.create')}\n cancelHref=\"/backend/availability/policies\"\n contentHeader={(\n <div className=\"space-y-4\">\n <ScopeFields value={scope} onChange={setScope} />\n <ResolutionPreviewPanel\n productId={scope.productId}\n variantId={scope.variantId || null}\n storeId={scope.storeId || null}\n />\n </div>\n )}\n onSubmit={async (values) => {\n if (scope.variantId && !scope.productId) {\n throw createCrudFormError(\n t('availability.policies.errors.variantRequiresProduct'),\n { productId: t('availability.policies.errors.variantRequiresProduct') },\n )\n }\n if (values.allowBackorder && toNullableInt(values.backorderLeadTimeDays) == null) {\n throw createCrudFormError(\n t('availability.policies.errors.backorderRequiresLeadTime'),\n { backorderLeadTimeDays: t('availability.policies.errors.backorderRequiresLeadTime') },\n )\n }\n const min = toNullableInt(values.minOrderQuantity)\n const max = toNullableInt(values.maxOrderQuantity)\n if (min != null && max != null && max < min) {\n throw createCrudFormError(\n t('availability.policies.errors.maxBelowMin'),\n { maxOrderQuantity: t('availability.policies.errors.maxBelowMin') },\n )\n }\n\n const payload = {\n organizationId,\n tenantId,\n productId: scope.productId || null,\n variantId: scope.variantId || null,\n storeId: scope.storeId || null,\n isStockManaged: !!values.isStockManaged,\n allowBackorder: !!values.allowBackorder,\n backorderLeadTimeDays: toNullableInt(values.backorderLeadTimeDays),\n preorderReleaseAt: values.preorderReleaseAt || null,\n lowStockThreshold: toNullableInt(values.lowStockThreshold),\n minOrderQuantity: min,\n maxOrderQuantity: max,\n quantityIncrement: toNullableInt(values.quantityIncrement),\n hideWhenOutOfStock: !!values.hideWhenOutOfStock,\n isActive: values.isActive !== false,\n }\n await createCrud('availability/policies', payload)\n flash(t('availability.policies.flash.created'), 'success')\n router.push('/backend/availability/policies')\n }}\n />\n )\n}\n"],
5
- "mappings": ";AAkDQ,SACE,KADF;AAjDR,YAAY,WAAW;AACvB,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,kCAAkC;AAC3C,SAAS,mBAAqC;AAC9C,SAAS,8BAA8B;AACvC,SAAS,8BAA8B;AAevC,SAAS,cAAc,OAA0D;AAC/E,MAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,GAAI,QAAO;AAClE,QAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,SAAS,OAAO,EAAE;AACrE,SAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAC5C;AAEe,SAAR,+BAAgD;AACrD,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,EAAE,gBAAgB,SAAS,IAAI,2BAA2B;AAChE,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAsB,EAAE,WAAW,IAAI,WAAW,IAAI,SAAS,GAAG,CAAC;AAEnG,QAAM,SAAS,MAAM,QAAQ,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC;AAEjE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,oCAAoC;AAAA,MAC7C,mBAAmB;AAAA,MACnB,UAAS;AAAA,MACT,QAAQ,CAAC;AAAA,MACT;AAAA,MACA,aAAa,EAAE,0CAA0C;AAAA,MACzD,YAAW;AAAA,MACX,eACE,qBAAC,SAAI,WAAU,aACb;AAAA,4BAAC,eAAY,OAAO,OAAO,UAAU,UAAU;AAAA,QAC/C;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,MAAM;AAAA,YACjB,WAAW,MAAM,aAAa;AAAA,YAC9B,SAAS,MAAM,WAAW;AAAA;AAAA,QAC5B;AAAA,SACF;AAAA,MAEF,UAAU,OAAO,WAAW;AAC1B,YAAI,MAAM,aAAa,CAAC,MAAM,WAAW;AACvC,gBAAM;AAAA,YACJ,EAAE,qDAAqD;AAAA,YACvD,EAAE,WAAW,EAAE,qDAAqD,EAAE;AAAA,UACxE;AAAA,QACF;AACA,YAAI,OAAO,kBAAkB,cAAc,OAAO,qBAAqB,KAAK,MAAM;AAChF,gBAAM;AAAA,YACJ,EAAE,wDAAwD;AAAA,YAC1D,EAAE,uBAAuB,EAAE,wDAAwD,EAAE;AAAA,UACvF;AAAA,QACF;AACA,cAAM,MAAM,cAAc,OAAO,gBAAgB;AACjD,cAAM,MAAM,cAAc,OAAO,gBAAgB;AACjD,YAAI,OAAO,QAAQ,OAAO,QAAQ,MAAM,KAAK;AAC3C,gBAAM;AAAA,YACJ,EAAE,0CAA0C;AAAA,YAC5C,EAAE,kBAAkB,EAAE,0CAA0C,EAAE;AAAA,UACpE;AAAA,QACF;AAEA,cAAM,UAAU;AAAA,UACd;AAAA,UACA;AAAA,UACA,WAAW,MAAM,aAAa;AAAA,UAC9B,WAAW,MAAM,aAAa;AAAA,UAC9B,SAAS,MAAM,WAAW;AAAA,UAC1B,gBAAgB,CAAC,CAAC,OAAO;AAAA,UACzB,gBAAgB,CAAC,CAAC,OAAO;AAAA,UACzB,uBAAuB,cAAc,OAAO,qBAAqB;AAAA,UACjE,mBAAmB,OAAO,qBAAqB;AAAA,UAC/C,mBAAmB,cAAc,OAAO,iBAAiB;AAAA,UACzD,kBAAkB;AAAA,UAClB,kBAAkB;AAAA,UAClB,mBAAmB,cAAc,OAAO,iBAAiB;AAAA,UACzD,oBAAoB,CAAC,CAAC,OAAO;AAAA,UAC7B,UAAU,OAAO,aAAa;AAAA,QAChC;AACA,cAAM,WAAW,yBAAyB,OAAO;AACjD,cAAM,EAAE,qCAAqC,GAAG,SAAS;AACzD,eAAO,KAAK,gCAAgC;AAAA,MAC9C;AAAA;AAAA,EACF;AAEJ;",
6
- "names": []
7
- }
@@ -1,12 +0,0 @@
1
- const metadata = {
2
- requireAuth: true,
3
- requireFeatures: ["availability.policies.manage"],
4
- breadcrumb: [
5
- { label: "Availability Policies", labelKey: "availability.policies.nav.title", href: "/backend/availability/policies" },
6
- { label: "Create", labelKey: "availability.policies.create.title" }
7
- ]
8
- };
9
- export {
10
- metadata
11
- };
12
- //# sourceMappingURL=page.meta.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../../src/modules/availability/backend/availability/policies/create/page.meta.ts"],
4
- "sourcesContent": ["export const metadata = {\n requireAuth: true,\n requireFeatures: ['availability.policies.manage'],\n breadcrumb: [\n { label: 'Availability Policies', labelKey: 'availability.policies.nav.title', href: '/backend/availability/policies' },\n { label: 'Create', labelKey: 'availability.policies.create.title' },\n ],\n}\n"],
5
- "mappings": "AAAO,MAAM,WAAW;AAAA,EACtB,aAAa;AAAA,EACb,iBAAiB,CAAC,8BAA8B;AAAA,EAChD,YAAY;AAAA,IACV,EAAE,OAAO,yBAAyB,UAAU,mCAAmC,MAAM,iCAAiC;AAAA,IACtH,EAAE,OAAO,UAAU,UAAU,qCAAqC;AAAA,EACpE;AACF;",
6
- "names": []
7
- }
@@ -1,75 +0,0 @@
1
- function buildPolicyFieldGroups(t) {
2
- return [
3
- {
4
- id: "sell-policy",
5
- column: 1,
6
- title: t("availability.policies.form.group.sellPolicy"),
7
- fields: [
8
- {
9
- id: "isStockManaged",
10
- type: "checkbox",
11
- label: t("availability.policies.form.field.isStockManaged"),
12
- description: t("availability.policies.form.field.isStockManaged.help")
13
- },
14
- {
15
- id: "allowBackorder",
16
- type: "checkbox",
17
- label: t("availability.policies.form.field.allowBackorder")
18
- },
19
- {
20
- id: "backorderLeadTimeDays",
21
- type: "number",
22
- label: t("availability.policies.form.field.backorderLeadTimeDays"),
23
- description: t("availability.policies.form.field.backorderLeadTimeDays.help")
24
- },
25
- {
26
- id: "preorderReleaseAt",
27
- type: "datetime-local",
28
- label: t("availability.policies.form.field.preorderReleaseAt")
29
- }
30
- ]
31
- },
32
- {
33
- id: "thresholds",
34
- column: 2,
35
- title: t("availability.policies.form.group.thresholds"),
36
- fields: [
37
- {
38
- id: "lowStockThreshold",
39
- type: "number",
40
- label: t("availability.policies.form.field.lowStockThreshold")
41
- },
42
- {
43
- id: "minOrderQuantity",
44
- type: "number",
45
- label: t("availability.policies.form.field.minOrderQuantity")
46
- },
47
- {
48
- id: "maxOrderQuantity",
49
- type: "number",
50
- label: t("availability.policies.form.field.maxOrderQuantity")
51
- },
52
- {
53
- id: "quantityIncrement",
54
- type: "number",
55
- label: t("availability.policies.form.field.quantityIncrement")
56
- },
57
- {
58
- id: "hideWhenOutOfStock",
59
- type: "checkbox",
60
- label: t("availability.policies.form.field.hideWhenOutOfStock")
61
- },
62
- {
63
- id: "isActive",
64
- type: "checkbox",
65
- label: t("availability.policies.form.field.isActive"),
66
- defaultValue: true
67
- }
68
- ]
69
- }
70
- ];
71
- }
72
- export {
73
- buildPolicyFieldGroups
74
- };
75
- //# sourceMappingURL=formGroups.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../src/modules/availability/backend/availability/policies/formGroups.ts"],
4
- "sourcesContent": ["import type { CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\n\n/**\n * Shared field groups for the create and edit policy forms. Scope fields\n * (productId/variantId/storeId) live outside this list \u2014 see `ScopeFields`.\n */\nexport function buildPolicyFieldGroups(t: (key: string) => string): CrudFormGroup[] {\n return [\n {\n id: 'sell-policy',\n column: 1,\n title: t('availability.policies.form.group.sellPolicy'),\n fields: [\n {\n id: 'isStockManaged',\n type: 'checkbox',\n label: t('availability.policies.form.field.isStockManaged'),\n description: t('availability.policies.form.field.isStockManaged.help'),\n },\n {\n id: 'allowBackorder',\n type: 'checkbox',\n label: t('availability.policies.form.field.allowBackorder'),\n },\n {\n id: 'backorderLeadTimeDays',\n type: 'number',\n label: t('availability.policies.form.field.backorderLeadTimeDays'),\n description: t('availability.policies.form.field.backorderLeadTimeDays.help'),\n },\n {\n id: 'preorderReleaseAt',\n type: 'datetime-local',\n label: t('availability.policies.form.field.preorderReleaseAt'),\n },\n ],\n },\n {\n id: 'thresholds',\n column: 2,\n title: t('availability.policies.form.group.thresholds'),\n fields: [\n {\n id: 'lowStockThreshold',\n type: 'number',\n label: t('availability.policies.form.field.lowStockThreshold'),\n },\n {\n id: 'minOrderQuantity',\n type: 'number',\n label: t('availability.policies.form.field.minOrderQuantity'),\n },\n {\n id: 'maxOrderQuantity',\n type: 'number',\n label: t('availability.policies.form.field.maxOrderQuantity'),\n },\n {\n id: 'quantityIncrement',\n type: 'number',\n label: t('availability.policies.form.field.quantityIncrement'),\n },\n {\n id: 'hideWhenOutOfStock',\n type: 'checkbox',\n label: t('availability.policies.form.field.hideWhenOutOfStock'),\n },\n {\n id: 'isActive',\n type: 'checkbox',\n label: t('availability.policies.form.field.isActive'),\n defaultValue: true,\n },\n ],\n },\n ]\n}\n"],
5
- "mappings": "AAMO,SAAS,uBAAuB,GAA6C;AAClF,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,OAAO,EAAE,6CAA6C;AAAA,MACtD,QAAQ;AAAA,QACN;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,iDAAiD;AAAA,UAC1D,aAAa,EAAE,sDAAsD;AAAA,QACvE;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,iDAAiD;AAAA,QAC5D;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,wDAAwD;AAAA,UACjE,aAAa,EAAE,6DAA6D;AAAA,QAC9E;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,oDAAoD;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,OAAO,EAAE,6CAA6C;AAAA,MACtD,QAAQ;AAAA,QACN;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,oDAAoD;AAAA,QAC/D;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,mDAAmD;AAAA,QAC9D;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,mDAAmD;AAAA,QAC9D;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,oDAAoD;AAAA,QAC/D;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,qDAAqD;AAAA,QAChE;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,2CAA2C;AAAA,UACpD,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;",
6
- "names": []
7
- }
@@ -1,176 +0,0 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import Link from "next/link";
5
- import { Page, PageBody } from "@open-mercato/ui/backend/Page";
6
- import { DataTable } from "@open-mercato/ui/backend/DataTable";
7
- import { Button } from "@open-mercato/ui/primitives/button";
8
- import { RowActions } from "@open-mercato/ui/backend/RowActions";
9
- import { apiCall, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
10
- import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
11
- import { flash } from "@open-mercato/ui/backend/FlashMessages";
12
- import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
13
- import { useT } from "@open-mercato/shared/lib/i18n/context";
14
- import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
15
- function ScopeCell({ value, allLabel }) {
16
- if (!value) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: allLabel });
17
- return /* @__PURE__ */ jsx("code", { className: "text-xs", children: value });
18
- }
19
- function AvailabilityPoliciesListPage() {
20
- const [rows, setRows] = React.useState([]);
21
- const [page, setPage] = React.useState(1);
22
- const [total, setTotal] = React.useState(0);
23
- const [totalPages, setTotalPages] = React.useState(1);
24
- const [totalIsCapped, setTotalIsCapped] = React.useState(false);
25
- const [isLoading, setIsLoading] = React.useState(true);
26
- const [reloadToken, setReloadToken] = React.useState(0);
27
- const scopeVersion = useOrganizationScopeVersion();
28
- const t = useT();
29
- const { confirm, ConfirmDialogElement } = useConfirmDialog();
30
- const [filterValues, setFilterValues] = React.useState({});
31
- const filters = React.useMemo(() => [
32
- { id: "productId", label: t("availability.policies.list.columns.product"), type: "text" },
33
- { id: "storeId", label: t("availability.policies.list.columns.store"), type: "text" },
34
- {
35
- id: "isActive",
36
- label: t("availability.policies.list.columns.active"),
37
- type: "select",
38
- options: [
39
- { value: "true", label: t("common.yes") },
40
- { value: "false", label: t("common.no") }
41
- ]
42
- }
43
- ], [t]);
44
- React.useEffect(() => {
45
- let cancelled = false;
46
- async function load() {
47
- setIsLoading(true);
48
- try {
49
- const params = new URLSearchParams();
50
- params.set("page", String(page));
51
- params.set("pageSize", "50");
52
- const productId = typeof filterValues.productId === "string" ? filterValues.productId.trim() : "";
53
- const storeId = typeof filterValues.storeId === "string" ? filterValues.storeId.trim() : "";
54
- const isActive = typeof filterValues.isActive === "string" ? filterValues.isActive : "";
55
- if (productId) params.set("productId", productId);
56
- if (storeId) params.set("storeId", storeId);
57
- if (isActive) params.set("isActive", isActive);
58
- const fallback = { items: [], total: 0, page, totalPages: 1 };
59
- const call = await apiCall(`/api/availability/policies?${params.toString()}`, void 0, { fallback });
60
- if (!call.ok) {
61
- const errorPayload = call.result;
62
- const message = typeof errorPayload?.error === "string" ? errorPayload.error : t("availability.policies.list.error.loadFailed");
63
- flash(message, "error");
64
- return;
65
- }
66
- const payload = call.result ?? fallback;
67
- if (!cancelled) {
68
- setRows(Array.isArray(payload.items) ? payload.items : []);
69
- setTotal(payload.total || 0);
70
- setTotalPages(payload.totalPages || 1);
71
- setTotalIsCapped(payload?.totalIsCapped === true);
72
- }
73
- } catch (error) {
74
- if (!cancelled) {
75
- const message = error instanceof Error ? error.message : t("availability.policies.list.error.loadFailed");
76
- flash(message, "error");
77
- }
78
- } finally {
79
- if (!cancelled) setIsLoading(false);
80
- }
81
- }
82
- load();
83
- return () => {
84
- cancelled = true;
85
- };
86
- }, [page, reloadToken, scopeVersion, filterValues, t]);
87
- const handleDelete = React.useCallback(async (row) => {
88
- const confirmed = await confirm({ title: t("availability.policies.list.confirmDelete"), variant: "destructive" });
89
- if (!confirmed) return;
90
- try {
91
- const call = await withScopedApiRequestHeaders(
92
- buildOptimisticLockHeader(row.updatedAt),
93
- () => apiCall(`/api/availability/policies?id=${encodeURIComponent(row.id)}`, { method: "DELETE" }, { fallback: null })
94
- );
95
- if (!call.ok) {
96
- const errorPayload = call.result;
97
- const message = typeof errorPayload?.error === "string" ? errorPayload.error : t("availability.policies.list.error.deleteFailed");
98
- flash(message, "error");
99
- return;
100
- }
101
- flash(t("availability.policies.list.success.deleted"), "success");
102
- setReloadToken((token) => token + 1);
103
- } catch (error) {
104
- const message = error instanceof Error ? error.message : t("availability.policies.list.error.deleteFailed");
105
- flash(message, "error");
106
- }
107
- }, [confirm, t]);
108
- const columns = React.useMemo(() => [
109
- {
110
- accessorKey: "productId",
111
- header: t("availability.policies.list.columns.product"),
112
- cell: ({ row }) => /* @__PURE__ */ jsx(ScopeCell, { value: row.original.productId, allLabel: t("availability.policies.list.storeDefault") })
113
- },
114
- {
115
- accessorKey: "variantId",
116
- header: t("availability.policies.list.columns.variant"),
117
- cell: ({ row }) => /* @__PURE__ */ jsx(ScopeCell, { value: row.original.variantId, allLabel: t("availability.policies.list.allVariants") })
118
- },
119
- {
120
- accessorKey: "storeId",
121
- header: t("availability.policies.list.columns.store"),
122
- cell: ({ row }) => /* @__PURE__ */ jsx(ScopeCell, { value: row.original.storeId, allLabel: t("availability.policies.list.allStores") })
123
- },
124
- {
125
- accessorKey: "isStockManaged",
126
- header: t("availability.policies.list.columns.stockManaged"),
127
- cell: ({ row }) => row.original.isStockManaged ? t("common.yes") : t("common.no")
128
- },
129
- {
130
- accessorKey: "allowBackorder",
131
- header: t("availability.policies.list.columns.backorder"),
132
- cell: ({ row }) => row.original.allowBackorder ? t("common.yes") : t("common.no")
133
- },
134
- {
135
- accessorKey: "isActive",
136
- header: t("availability.policies.list.columns.active"),
137
- cell: ({ row }) => row.original.isActive ? t("common.yes") : t("common.no")
138
- }
139
- ], [t]);
140
- return /* @__PURE__ */ jsxs(Page, { children: [
141
- /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(
142
- DataTable,
143
- {
144
- title: t("availability.policies.list.title"),
145
- titleHeadingLevel: 1,
146
- actions: /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsx(Link, { href: "/backend/availability/policies/create", children: t("availability.policies.list.actions.create") }) }),
147
- columns,
148
- data: rows,
149
- filters,
150
- filterValues,
151
- onFiltersApply: (values) => {
152
- setFilterValues(values);
153
- setPage(1);
154
- },
155
- onFiltersClear: () => {
156
- setFilterValues({});
157
- setPage(1);
158
- },
159
- perspective: { tableId: "availability.policies.list" },
160
- rowActions: (row) => /* @__PURE__ */ jsx(RowActions, { items: [
161
- { id: "edit", label: t("common.edit"), href: `/backend/availability/policies/${row.id}` },
162
- { id: "delete", label: t("common.delete"), destructive: true, onSelect: () => {
163
- void handleDelete(row);
164
- } }
165
- ] }),
166
- pagination: { page, pageSize: 50, total, totalPages, totalIsCapped, onPageChange: setPage },
167
- isLoading
168
- }
169
- ) }),
170
- ConfirmDialogElement
171
- ] });
172
- }
173
- export {
174
- AvailabilityPoliciesListPage as default
175
- };
176
- //# sourceMappingURL=page.js.map