@endora-commerce/mod-price-lists 0.100.0

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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/admin/components/ApplicationRuleBuilder.d.ts +24 -0
  4. package/dist/admin/components/ApplicationRuleBuilder.d.ts.map +1 -0
  5. package/dist/admin/components/ApplicationRuleBuilder.js +249 -0
  6. package/dist/admin/components/ApplicationRuleBuilder.js.map +1 -0
  7. package/dist/admin/components/BracketGrid.d.ts +29 -0
  8. package/dist/admin/components/BracketGrid.d.ts.map +1 -0
  9. package/dist/admin/components/BracketGrid.js +252 -0
  10. package/dist/admin/components/BracketGrid.js.map +1 -0
  11. package/dist/admin/components/DisplayModeOverrideRow.d.ts +46 -0
  12. package/dist/admin/components/DisplayModeOverrideRow.d.ts.map +1 -0
  13. package/dist/admin/components/DisplayModeOverrideRow.js +109 -0
  14. package/dist/admin/components/DisplayModeOverrideRow.js.map +1 -0
  15. package/dist/admin/components/LinkedPriceListsPanel.d.ts +55 -0
  16. package/dist/admin/components/LinkedPriceListsPanel.d.ts.map +1 -0
  17. package/dist/admin/components/LinkedPriceListsPanel.js +131 -0
  18. package/dist/admin/components/LinkedPriceListsPanel.js.map +1 -0
  19. package/dist/admin/index.d.ts +34 -0
  20. package/dist/admin/index.d.ts.map +1 -0
  21. package/dist/admin/index.js +119 -0
  22. package/dist/admin/index.js.map +1 -0
  23. package/dist/admin/pages/DisplayModeOverridesPage.d.ts +25 -0
  24. package/dist/admin/pages/DisplayModeOverridesPage.d.ts.map +1 -0
  25. package/dist/admin/pages/DisplayModeOverridesPage.js +266 -0
  26. package/dist/admin/pages/DisplayModeOverridesPage.js.map +1 -0
  27. package/dist/admin/pages/PriceListDetailPage.d.ts +23 -0
  28. package/dist/admin/pages/PriceListDetailPage.d.ts.map +1 -0
  29. package/dist/admin/pages/PriceListDetailPage.js +421 -0
  30. package/dist/admin/pages/PriceListDetailPage.js.map +1 -0
  31. package/dist/admin/pages/PriceListsPage.d.ts +17 -0
  32. package/dist/admin/pages/PriceListsPage.d.ts.map +1 -0
  33. package/dist/admin/pages/PriceListsPage.js +198 -0
  34. package/dist/admin/pages/PriceListsPage.js.map +1 -0
  35. package/dist/admin/zones/CategoryDisplayMode.d.ts +27 -0
  36. package/dist/admin/zones/CategoryDisplayMode.d.ts.map +1 -0
  37. package/dist/admin/zones/CategoryDisplayMode.js +11 -0
  38. package/dist/admin/zones/CategoryDisplayMode.js.map +1 -0
  39. package/dist/admin/zones/OrganizationDisplayMode.d.ts +36 -0
  40. package/dist/admin/zones/OrganizationDisplayMode.d.ts.map +1 -0
  41. package/dist/admin/zones/OrganizationDisplayMode.js +12 -0
  42. package/dist/admin/zones/OrganizationDisplayMode.js.map +1 -0
  43. package/dist/admin/zones/ProductLinkedPriceLists.d.ts +16 -0
  44. package/dist/admin/zones/ProductLinkedPriceLists.d.ts.map +1 -0
  45. package/dist/admin/zones/ProductLinkedPriceLists.js +7 -0
  46. package/dist/admin/zones/ProductLinkedPriceLists.js.map +1 -0
  47. package/dist/backend/entities/price-display-mode-override.entity.d.ts +23 -0
  48. package/dist/backend/entities/price-display-mode-override.entity.d.ts.map +1 -0
  49. package/dist/backend/entities/price-display-mode-override.entity.js +58 -0
  50. package/dist/backend/entities/price-display-mode-override.entity.js.map +1 -0
  51. package/dist/backend/entities/price-list-price-bracket.entity.d.ts +26 -0
  52. package/dist/backend/entities/price-list-price-bracket.entity.d.ts.map +1 -0
  53. package/dist/backend/entities/price-list-price-bracket.entity.js +73 -0
  54. package/dist/backend/entities/price-list-price-bracket.entity.js.map +1 -0
  55. package/dist/backend/entities/price-list-product.entity.d.ts +15 -0
  56. package/dist/backend/entities/price-list-product.entity.d.ts.map +1 -0
  57. package/dist/backend/entities/price-list-product.entity.js +43 -0
  58. package/dist/backend/entities/price-list-product.entity.js.map +1 -0
  59. package/dist/backend/entities/price-list.entity.d.ts +34 -0
  60. package/dist/backend/entities/price-list.entity.d.ts.map +1 -0
  61. package/dist/backend/entities/price-list.entity.js +115 -0
  62. package/dist/backend/entities/price-list.entity.js.map +1 -0
  63. package/dist/backend/index.d.ts +125 -0
  64. package/dist/backend/index.d.ts.map +1 -0
  65. package/dist/backend/index.js +179 -0
  66. package/dist/backend/index.js.map +1 -0
  67. package/dist/backend/plugin.d.ts +68 -0
  68. package/dist/backend/plugin.d.ts.map +1 -0
  69. package/dist/backend/plugin.js +88 -0
  70. package/dist/backend/plugin.js.map +1 -0
  71. package/dist/backend/routes.d.ts +40 -0
  72. package/dist/backend/routes.d.ts.map +1 -0
  73. package/dist/backend/routes.js +447 -0
  74. package/dist/backend/routes.js.map +1 -0
  75. package/dist/backend/routes.storefront.d.ts +47 -0
  76. package/dist/backend/routes.storefront.d.ts.map +1 -0
  77. package/dist/backend/routes.storefront.js +131 -0
  78. package/dist/backend/routes.storefront.js.map +1 -0
  79. package/dist/backend/services/application-rule-evaluator.d.ts +25 -0
  80. package/dist/backend/services/application-rule-evaluator.d.ts.map +1 -0
  81. package/dist/backend/services/application-rule-evaluator.js +2 -0
  82. package/dist/backend/services/application-rule-evaluator.js.map +1 -0
  83. package/dist/backend/services/audit-references.d.ts +11 -0
  84. package/dist/backend/services/audit-references.d.ts.map +1 -0
  85. package/dist/backend/services/audit-references.js +23 -0
  86. package/dist/backend/services/audit-references.js.map +1 -0
  87. package/dist/backend/services/default-price-list-migration.d.ts +70 -0
  88. package/dist/backend/services/default-price-list-migration.d.ts.map +1 -0
  89. package/dist/backend/services/default-price-list-migration.js +177 -0
  90. package/dist/backend/services/default-price-list-migration.js.map +1 -0
  91. package/dist/backend/services/display-mode-resolver.d.ts +78 -0
  92. package/dist/backend/services/display-mode-resolver.d.ts.map +1 -0
  93. package/dist/backend/services/display-mode-resolver.js +71 -0
  94. package/dist/backend/services/display-mode-resolver.js.map +1 -0
  95. package/dist/backend/services/listing-price-chain.d.ts +26 -0
  96. package/dist/backend/services/listing-price-chain.d.ts.map +1 -0
  97. package/dist/backend/services/listing-price-chain.js +55 -0
  98. package/dist/backend/services/listing-price-chain.js.map +1 -0
  99. package/dist/backend/services/price-bracket-resolver.d.ts +24 -0
  100. package/dist/backend/services/price-bracket-resolver.d.ts.map +1 -0
  101. package/dist/backend/services/price-bracket-resolver.js +16 -0
  102. package/dist/backend/services/price-bracket-resolver.js.map +1 -0
  103. package/dist/backend/services/price-list-candidate-vector.d.ts +116 -0
  104. package/dist/backend/services/price-list-candidate-vector.d.ts.map +1 -0
  105. package/dist/backend/services/price-list-candidate-vector.js +133 -0
  106. package/dist/backend/services/price-list-candidate-vector.js.map +1 -0
  107. package/dist/backend/services/price-list-currency-reference.d.ts +12 -0
  108. package/dist/backend/services/price-list-currency-reference.d.ts.map +1 -0
  109. package/dist/backend/services/price-list-currency-reference.js +24 -0
  110. package/dist/backend/services/price-list-currency-reference.js.map +1 -0
  111. package/dist/backend/services/price-list-read-port.d.ts +29 -0
  112. package/dist/backend/services/price-list-read-port.d.ts.map +1 -0
  113. package/dist/backend/services/price-list-read-port.js +64 -0
  114. package/dist/backend/services/price-list-read-port.js.map +1 -0
  115. package/dist/backend/services/price-list-resolver.d.ts +26 -0
  116. package/dist/backend/services/price-list-resolver.d.ts.map +1 -0
  117. package/dist/backend/services/price-list-resolver.js +37 -0
  118. package/dist/backend/services/price-list-resolver.js.map +1 -0
  119. package/dist/backend/services/price-list-service.d.ts +431 -0
  120. package/dist/backend/services/price-list-service.d.ts.map +1 -0
  121. package/dist/backend/services/price-list-service.js +1238 -0
  122. package/dist/backend/services/price-list-service.js.map +1 -0
  123. package/dist/backend/services/price-list-status-worker.d.ts +28 -0
  124. package/dist/backend/services/price-list-status-worker.d.ts.map +1 -0
  125. package/dist/backend/services/price-list-status-worker.js +38 -0
  126. package/dist/backend/services/price-list-status-worker.js.map +1 -0
  127. package/dist/backend/services/pricing-cache.d.ts +53 -0
  128. package/dist/backend/services/pricing-cache.d.ts.map +1 -0
  129. package/dist/backend/services/pricing-cache.js +88 -0
  130. package/dist/backend/services/pricing-cache.js.map +1 -0
  131. package/dist/backend/services/pricing-service.d.ts +304 -0
  132. package/dist/backend/services/pricing-service.d.ts.map +1 -0
  133. package/dist/backend/services/pricing-service.interface.d.ts +151 -0
  134. package/dist/backend/services/pricing-service.interface.d.ts.map +1 -0
  135. package/dist/backend/services/pricing-service.interface.js +10 -0
  136. package/dist/backend/services/pricing-service.interface.js.map +1 -0
  137. package/dist/backend/services/pricing-service.js +803 -0
  138. package/dist/backend/services/pricing-service.js.map +1 -0
  139. package/dist/backend/services/unit-price-ordering.d.ts +121 -0
  140. package/dist/backend/services/unit-price-ordering.d.ts.map +1 -0
  141. package/dist/backend/services/unit-price-ordering.js +164 -0
  142. package/dist/backend/services/unit-price-ordering.js.map +1 -0
  143. package/dist/manifest.d.ts +218 -0
  144. package/dist/manifest.d.ts.map +1 -0
  145. package/dist/manifest.js +228 -0
  146. package/dist/manifest.js.map +1 -0
  147. package/dist/migrations/20260426T075235_price_lists_pricing_init.d.ts +24 -0
  148. package/dist/migrations/20260426T075235_price_lists_pricing_init.d.ts.map +1 -0
  149. package/dist/migrations/20260426T075235_price_lists_pricing_init.js +89 -0
  150. package/dist/migrations/20260426T075235_price_lists_pricing_init.js.map +1 -0
  151. package/dist/migrations/20260504T125655_price_lists_engine.d.ts +6 -0
  152. package/dist/migrations/20260504T125655_price_lists_engine.d.ts.map +1 -0
  153. package/dist/migrations/20260504T125655_price_lists_engine.js +319 -0
  154. package/dist/migrations/20260504T125655_price_lists_engine.js.map +1 -0
  155. package/dist/migrations/20260817T055457_price_lists_single_system_price_list.d.ts +15 -0
  156. package/dist/migrations/20260817T055457_price_lists_single_system_price_list.d.ts.map +1 -0
  157. package/dist/migrations/20260817T055457_price_lists_single_system_price_list.js +58 -0
  158. package/dist/migrations/20260817T055457_price_lists_single_system_price_list.js.map +1 -0
  159. package/dist/migrations/20260821T135907_price_lists_unit_price_amount_index.d.ts +40 -0
  160. package/dist/migrations/20260821T135907_price_lists_unit_price_amount_index.d.ts.map +1 -0
  161. package/dist/migrations/20260821T135907_price_lists_unit_price_amount_index.js +46 -0
  162. package/dist/migrations/20260821T135907_price_lists_unit_price_amount_index.js.map +1 -0
  163. package/dist/migrations/index.d.ts +30 -0
  164. package/dist/migrations/index.d.ts.map +1 -0
  165. package/dist/migrations/index.js +35 -0
  166. package/dist/migrations/index.js.map +1 -0
  167. package/docs/price_lists.md +278 -0
  168. package/i18n/en.json +14 -0
  169. package/i18n/pl.json +14 -0
  170. package/package.json +99 -0
  171. package/tailwind.css +14 -0
@@ -0,0 +1,252 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { Copy, Plus, Save, Trash2, AlertTriangle, RotateCcw } from 'lucide-react';
4
+ import { ApiError, apiClient } from '@endora-commerce/admin-kit/lib';
5
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
6
+ /**
7
+ * Per-product per-currency multi-bracket editor (US3 / T047).
8
+ *
9
+ * Surfaces every currency the price list already carries on this
10
+ * product as a tab, plus an "Add currency" picker fed by the
11
+ * `/admin/pricing/rule-targets/currencies` endpoint. Inline overlap
12
+ * + open-end + decimal-format validation runs client-side; the same
13
+ * rules are enforced by the service layer so the save call surfaces
14
+ * a structured `400 bracket_overlap` / `400 invalid_bracket` error
15
+ * if a slip-through reaches the backend.
16
+ */
17
+ export function BracketGrid(props) {
18
+ const t = useTranslation('core');
19
+ const { priceListId, productId, productName, initial, systemList, onSaved } = props;
20
+ const initialCurrencies = Object.keys(initial).sort();
21
+ const [draft, setDraft] = useState(() => normaliseInitial(initial));
22
+ const [activeCurrency, setActiveCurrency] = useState(initialCurrencies[0] ?? '');
23
+ const [allCurrencies, setAllCurrencies] = useState([]);
24
+ const [error, setError] = useState(null);
25
+ const [info, setInfo] = useState(null);
26
+ const [submitting, setSubmitting] = useState(false);
27
+ const [showCopy, setShowCopy] = useState(false);
28
+ useEffect(() => {
29
+ setDraft(normaliseInitial(initial));
30
+ const next = Object.keys(initial).sort();
31
+ if (next.length > 0 && !next.includes(activeCurrency)) {
32
+ setActiveCurrency(next[0]);
33
+ }
34
+ // eslint-disable-next-line react-hooks/exhaustive-deps
35
+ }, [initial, productId]);
36
+ useEffect(() => {
37
+ apiClient
38
+ .get('/api/v1/admin/pricing/rule-targets/currencies')
39
+ .then((res) => setAllCurrencies(res.data.items.map((i) => i.code)))
40
+ .catch(() => setAllCurrencies([]));
41
+ }, []);
42
+ const validation = useMemo(() => validate(draft), [draft]);
43
+ const dirty = useMemo(() => JSON.stringify(normaliseInitial(initial)) !== JSON.stringify(draft), [initial, draft]);
44
+ const currencies = Object.keys(draft).sort();
45
+ const rows = activeCurrency ? draft[activeCurrency] ?? [] : [];
46
+ const setRows = (next) => {
47
+ setDraft((prev) => ({ ...prev, [activeCurrency]: next }));
48
+ };
49
+ const addBracket = () => {
50
+ const last = rows[rows.length - 1];
51
+ const nextMin = last ? Math.max(last.minQuantity + 1, (last.maxQuantity ?? last.minQuantity) + 1) : 1;
52
+ setRows([...rows, { minQuantity: nextMin, maxQuantity: null, amount: '0.00' }]);
53
+ };
54
+ const removeBracket = (idx) => {
55
+ setRows(rows.filter((_, i) => i !== idx));
56
+ };
57
+ const updateRow = (idx, patch) => {
58
+ setRows(rows.map((r, i) => (i === idx ? { ...r, ...patch } : r)));
59
+ };
60
+ const addCurrency = (code) => {
61
+ const upper = code.toUpperCase();
62
+ if (draft[upper])
63
+ return;
64
+ setDraft((prev) => ({ ...prev, [upper]: [{ minQuantity: 1, maxQuantity: null, amount: '0.00' }] }));
65
+ setActiveCurrency(upper);
66
+ };
67
+ const removeCurrency = () => {
68
+ if (!activeCurrency)
69
+ return;
70
+ if (!confirm(t('priceLists.bracket.confirmRemoveCurrency', { code: activeCurrency })))
71
+ return;
72
+ setDraft((prev) => {
73
+ const { [activeCurrency]: _, ...rest } = prev;
74
+ return rest;
75
+ });
76
+ const remaining = Object.keys(draft).filter((c) => c !== activeCurrency).sort();
77
+ setActiveCurrency(remaining[0] ?? '');
78
+ };
79
+ const handleReset = () => {
80
+ setDraft(normaliseInitial(initial));
81
+ setError(null);
82
+ setInfo(null);
83
+ };
84
+ const handleSave = async () => {
85
+ if (validation.errors.length > 0)
86
+ return;
87
+ setSubmitting(true);
88
+ setError(null);
89
+ try {
90
+ const res = await apiClient.put(`/api/v1/admin/price-lists-engine/${encodeURIComponent(priceListId)}/products/${encodeURIComponent(productId)}/brackets`, { bracketsByCurrency: draft });
91
+ onSaved(res.data.bracketsByCurrency);
92
+ setInfo(t('priceLists.bracket.info.saved'));
93
+ }
94
+ catch (err) {
95
+ setError(err instanceof ApiError ? err.envelope.error.message : t('priceLists.bracket.error.save'));
96
+ }
97
+ finally {
98
+ setSubmitting(false);
99
+ }
100
+ };
101
+ const handleCopyCurrency = async (toCurrencies) => {
102
+ if (!activeCurrency || toCurrencies.length === 0)
103
+ return;
104
+ setSubmitting(true);
105
+ setError(null);
106
+ try {
107
+ await apiClient.post(`/api/v1/admin/price-lists-engine/${encodeURIComponent(priceListId)}/products/${encodeURIComponent(productId)}/brackets/copy`, { fromCurrency: activeCurrency, toCurrencies });
108
+ // Re-load the persisted brackets via PUT response shape; the simplest
109
+ // path is to mirror the source brackets locally (server-side does the
110
+ // identity copy) and let the parent refresh the list view too.
111
+ setDraft((prev) => {
112
+ const next = { ...prev };
113
+ for (const cur of toCurrencies) {
114
+ next[cur] = [...(prev[activeCurrency] ?? [])].map((r) => ({ ...r }));
115
+ }
116
+ return next;
117
+ });
118
+ setInfo(t('priceLists.bracket.info.copied', {
119
+ source: activeCurrency,
120
+ targets: toCurrencies.join(', '),
121
+ }));
122
+ setShowCopy(false);
123
+ }
124
+ catch (err) {
125
+ setError(err instanceof ApiError ? err.envelope.error.message : t('priceLists.bracket.error.copy'));
126
+ }
127
+ finally {
128
+ setSubmitting(false);
129
+ }
130
+ };
131
+ return (_jsxs("div", { className: "b2b-col", style: { gap: 12 }, children: [_jsxs("div", { className: "b2b-row", style: { alignItems: 'baseline', gap: 8, paddingBottom: 4, borderBottom: '1px solid var(--border-color)' }, children: [_jsxs("div", { className: "b2b-grow", children: [_jsx("div", { style: { fontSize: 13, fontWeight: 600 }, children: productName }), _jsx("div", { className: "b2b-help", style: { marginTop: 2 }, children: t('priceLists.bracket.help') })] }), dirty && !systemList ? (_jsxs("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", onClick: handleReset, children: [_jsx(RotateCcw, { size: 12 }), " ", t('priceLists.bracket.discard')] })) : null, _jsxs("button", { type: "button", className: "b2b-btn b2b-btn--primary b2b-btn--sm", disabled: systemList || submitting || !dirty || validation.errors.length > 0, onClick: () => {
132
+ void handleSave();
133
+ }, children: [_jsx(Save, { size: 13 }), " ", submitting ? t('priceLists.bracket.saving') : t('priceLists.bracket.save')] })] }), info ? (_jsx("div", { style: {
134
+ padding: 8,
135
+ background: 'var(--success-soft)',
136
+ color: 'var(--success-soft-fg)',
137
+ borderRadius: 6,
138
+ border: '1px solid hsl(142 50% 80%)',
139
+ fontSize: 12,
140
+ }, children: info })) : null, error ? (_jsx("div", { style: {
141
+ padding: 8,
142
+ background: 'var(--danger-soft)',
143
+ color: 'var(--danger-soft-fg)',
144
+ borderRadius: 6,
145
+ border: '1px solid hsl(8 80% 85%)',
146
+ fontSize: 12,
147
+ }, children: error })) : null, _jsxs("div", { className: "b2b-row", style: { gap: 6, alignItems: 'center', flexWrap: 'wrap' }, children: [currencies.length === 0 ? (_jsx("span", { className: "b2b-help", children: t('priceLists.bracket.noCurrencies') })) : (currencies.map((c) => {
148
+ const isActive = c === activeCurrency;
149
+ const cErrors = validation.perCurrency[c]?.length ?? 0;
150
+ return (_jsxs("button", { type: "button", className: "b2b-btn b2b-btn--sm", onClick: () => setActiveCurrency(c), style: {
151
+ background: isActive ? 'var(--primary-color)' : 'var(--surface-color)',
152
+ color: isActive ? 'var(--primary-soft)' : 'var(--fg-default)',
153
+ border: `1px solid ${isActive ? 'var(--primary-color)' : 'var(--border-color)'}`,
154
+ }, children: [c, cErrors > 0 ? (_jsx(AlertTriangle, { size: 11, style: { marginLeft: 4, color: isActive ? '#fff' : 'hsl(8 80% 50%)' } })) : null] }, c));
155
+ })), _jsx(AddCurrencyMenu, { allCurrencies: allCurrencies, existing: currencies, onAdd: addCurrency, disabled: systemList }), currencies.length > 1 ? (_jsxs("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", disabled: systemList, onClick: () => setShowCopy(true), children: [_jsx(Copy, { size: 12 }), " ", t('priceLists.bracket.copyFrom', { code: activeCurrency })] })) : null, activeCurrency ? (_jsxs("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", disabled: systemList, onClick: removeCurrency, style: { color: 'hsl(8 80% 50%)' }, children: [_jsx(Trash2, { size: 12 }), " ", t('priceLists.bracket.removeCurrency', { code: activeCurrency })] })) : null] }), activeCurrency ? (_jsxs("table", { className: "b2b-tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { style: { width: 100 }, children: t('priceLists.bracket.column.minQty') }), _jsx("th", { style: { width: 100 }, children: t('priceLists.bracket.column.maxQty') }), _jsx("th", { children: t('priceLists.bracket.column.unitPrice', { code: activeCurrency }) }), _jsx("th", { style: { width: 50 } })] }) }), _jsx("tbody", { children: rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: 4, className: "b2b-help", style: { padding: 16 }, children: t('priceLists.bracket.emptyForCurrency', { code: activeCurrency }) }) })) : (rows.map((r, idx) => {
156
+ const rowErrors = validation.perRow[`${activeCurrency}#${idx}`] ?? [];
157
+ return (_jsxs("tr", { style: rowErrors.length > 0 ? { background: 'var(--danger-soft)' } : undefined, children: [_jsx("td", { children: _jsx("input", { type: "number", className: "b2b-field b2b-field--mono", min: 1, value: r.minQuantity, disabled: systemList, onChange: (e) => updateRow(idx, { minQuantity: Number(e.target.value) || 1 }) }) }), _jsx("td", { children: _jsx("input", { type: "number", className: "b2b-field b2b-field--mono", min: 1, placeholder: "\u221E", value: r.maxQuantity ?? '', disabled: systemList, onChange: (e) => updateRow(idx, {
158
+ maxQuantity: e.target.value === '' ? null : Number(e.target.value) || null,
159
+ }) }) }), _jsxs("td", { children: [_jsx("input", { type: "text", className: "b2b-field b2b-field--mono", inputMode: "decimal", value: r.amount, disabled: systemList, onChange: (e) => updateRow(idx, { amount: e.target.value }) }), rowErrors.length > 0 ? (_jsx("div", { style: { fontSize: 11, color: 'hsl(8 80% 40%)', marginTop: 2 }, children: rowErrors.join(' · ') })) : null] }), _jsx("td", { children: _jsx("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--icon b2b-btn--sm", disabled: systemList, onClick: () => removeBracket(idx), children: _jsx(Trash2, { size: 13 }) }) })] }, idx));
160
+ })) })] })) : null, activeCurrency && !systemList ? (_jsxs("button", { type: "button", className: "b2b-btn b2b-btn--default b2b-btn--sm", style: { alignSelf: 'flex-start' }, onClick: addBracket, children: [_jsx(Plus, { size: 12 }), " ", t('priceLists.bracket.addBracket')] })) : null, showCopy ? (_jsx(CopyDialog, { source: activeCurrency, allCurrencies: allCurrencies, existing: currencies, onClose: () => setShowCopy(false), onConfirm: (targets) => {
161
+ void handleCopyCurrency(targets);
162
+ } })) : null] }));
163
+ }
164
+ function AddCurrencyMenu({ allCurrencies, existing, onAdd, disabled, }) {
165
+ const t = useTranslation('core');
166
+ const [open, setOpen] = useState(false);
167
+ const candidates = allCurrencies.filter((c) => !existing.includes(c));
168
+ if (candidates.length === 0)
169
+ return null;
170
+ return (_jsxs("div", { style: { position: 'relative' }, children: [_jsxs("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", disabled: disabled, onClick: () => setOpen((v) => !v), children: [_jsx(Plus, { size: 12 }), " ", t('priceLists.bracket.addCurrency')] }), open ? (_jsx("div", { className: "b2b-card", style: {
171
+ position: 'absolute',
172
+ top: '100%',
173
+ left: 0,
174
+ marginTop: 4,
175
+ zIndex: 10,
176
+ padding: 4,
177
+ minWidth: 80,
178
+ }, children: candidates.map((c) => (_jsx("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", style: { width: '100%', justifyContent: 'flex-start' }, onClick: () => {
179
+ onAdd(c);
180
+ setOpen(false);
181
+ }, children: c }, c))) })) : null] }));
182
+ }
183
+ function CopyDialog({ source, allCurrencies, existing, onClose, onConfirm, }) {
184
+ const t = useTranslation('core');
185
+ const [selected, setSelected] = useState(new Set());
186
+ const candidates = Array.from(new Set([...allCurrencies, ...existing])).filter((c) => c !== source).sort();
187
+ const toggle = (c) => {
188
+ setSelected((prev) => {
189
+ const next = new Set(prev);
190
+ if (next.has(c))
191
+ next.delete(c);
192
+ else
193
+ next.add(c);
194
+ return next;
195
+ });
196
+ };
197
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "b2b-scrim", onClick: onClose }), _jsxs("aside", { className: "b2b-drawer", role: "dialog", "aria-modal": "true", style: { maxWidth: 360 }, children: [_jsxs("div", { className: "b2b-drawer__head", children: [_jsx("div", { className: "b2b-drawer__title", children: t('priceLists.bracket.copy.title', { source }) }), _jsx("div", { className: "b2b-card__sub", children: t('priceLists.bracket.copy.description') })] }), _jsx("div", { className: "b2b-drawer__body", children: candidates.length === 0 ? (_jsx("div", { className: "b2b-help", children: t('priceLists.bracket.copy.noOthers') })) : (_jsx("div", { className: "b2b-col", style: { gap: 6 }, children: candidates.map((c) => (_jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, cursor: 'pointer' }, children: [_jsx("input", { type: "checkbox", className: "b2b-cbx", checked: selected.has(c), onChange: () => toggle(c) }), c] }, c))) })) }), _jsxs("div", { className: "b2b-drawer__foot", children: [_jsx("button", { type: "button", className: "b2b-btn b2b-btn--ghost", onClick: onClose, children: t('priceLists.bracket.copy.cancel') }), _jsx("button", { type: "button", className: "b2b-btn b2b-btn--primary", disabled: selected.size === 0, onClick: () => onConfirm(Array.from(selected)), children: selected.size === 1
198
+ ? t('priceLists.bracket.copy.confirmSingle', { count: selected.size })
199
+ : t('priceLists.bracket.copy.confirmPlural', { count: selected.size }) })] })] })] }));
200
+ }
201
+ function normaliseInitial(input) {
202
+ const out = {};
203
+ for (const [cur, rows] of Object.entries(input)) {
204
+ out[cur] = [...rows]
205
+ .map((r) => ({ ...r }))
206
+ .sort((a, b) => a.minQuantity - b.minQuantity);
207
+ }
208
+ return out;
209
+ }
210
+ function validate(draft) {
211
+ const result = { errors: [], perCurrency: {}, perRow: {} };
212
+ for (const [cur, rows] of Object.entries(draft)) {
213
+ const cErrors = [];
214
+ const sorted = [...rows].sort((a, b) => a.minQuantity - b.minQuantity);
215
+ for (let i = 0; i < sorted.length; i += 1) {
216
+ const r = sorted[i];
217
+ const orig = rows.findIndex((x) => x === r);
218
+ const key = `${cur}#${orig}`;
219
+ const rowErrors = [];
220
+ if (!Number.isInteger(r.minQuantity) || r.minQuantity < 1) {
221
+ rowErrors.push('min must be ≥ 1');
222
+ }
223
+ if (r.maxQuantity !== null) {
224
+ if (!Number.isInteger(r.maxQuantity) || r.maxQuantity < r.minQuantity) {
225
+ rowErrors.push('max must be ≥ min');
226
+ }
227
+ }
228
+ if (!/^\d+(\.\d{1,4})?$/.test(r.amount)) {
229
+ rowErrors.push('amount must be a decimal');
230
+ }
231
+ if (i > 0) {
232
+ const prev = sorted[i - 1];
233
+ const prevMax = prev.maxQuantity ?? Infinity;
234
+ if (prevMax >= r.minQuantity)
235
+ rowErrors.push(`overlap with row above (${prev.minQuantity}–${prev.maxQuantity ?? '∞'})`);
236
+ if (i < sorted.length - 1 && prev.maxQuantity === null) {
237
+ rowErrors.push('previous row is open-ended; remove it or cap it first');
238
+ }
239
+ }
240
+ if (rowErrors.length > 0) {
241
+ result.perRow[key] = rowErrors;
242
+ cErrors.push(...rowErrors.map((e) => `Row ${orig + 1}: ${e}`));
243
+ }
244
+ }
245
+ if (cErrors.length > 0) {
246
+ result.perCurrency[cur] = cErrors;
247
+ result.errors.push(...cErrors);
248
+ }
249
+ }
250
+ return result;
251
+ }
252
+ //# sourceMappingURL=BracketGrid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BracketGrid.js","sourceRoot":"","sources":["../../../src/admin/components/BracketGrid.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { type ReactNode } from 'react';
2
+ type Scope = 'organization' | 'category' | 'product';
3
+ /**
4
+ * Per-entity display-mode override row (feature 011, US7 / T089 + T090).
5
+ *
6
+ * Reads the current override (if any) from
7
+ * `/api/v1/admin/pricing/display-mode-overrides/:scope/:targetId` and writes it
8
+ * with a `PUT`. `inherit` removes the override and reverts the entity to its
9
+ * parent in the resolution chain.
10
+ *
11
+ * ## What moved with it, and what did not (feature 091, P7a)
12
+ *
13
+ * The file used to live at `admin/src/modules/price_lists/`, imported by path
14
+ * from `catalog`'s category editor and `organizations`' detail screen — two of
15
+ * the admin keys the boundary ledger recorded. It is this module's control, so
16
+ * it lives in this module's package and reaches its consumers through zone
17
+ * contributions instead.
18
+ *
19
+ * **`label` and `inheritHint` did not come with it.** Both hosts passed their
20
+ * own copy for this module's control (`categories.priceDisplayMode.label`,
21
+ * `organizations.detail.pricingLabel`), which a zone cannot do: a host cannot
22
+ * hand copy to a contributor it does not know. The row renders
23
+ * `priceLists.displayMode.rowLabel` and its own hint, in every place it appears.
24
+ *
25
+ * The copy stays in the `core` namespace rather than moving to this module's
26
+ * own. That is the larger population
27
+ * `contracts/admin-component-contribution.md` §9.2 measured and deliberately
28
+ * did **not** rule on — 62 files under the admin's module root render out of
29
+ * `core` — and neither P7a nor P7b is the merge request that answers it.
30
+ *
31
+ * **P7b deleted the second copy.** One stood at
32
+ * `admin/src/modules/price_lists/DisplayModeOverrideRow.tsx` for the length of
33
+ * P7a, keeping the two props because `organizations`' detail screen still
34
+ * passed them; that screen is a zone mount now, nothing imported the file, and
35
+ * it is gone. Nothing in this estate compares two copies of one component, so
36
+ * the shorter that state lasts the better — which is why the retiring condition
37
+ * was written into this block rather than left to be remembered.
38
+ */
39
+ export declare function DisplayModeOverrideRow(props: {
40
+ scope: Scope;
41
+ targetId: string;
42
+ /** Hide the icon when embedding inside an existing labelled row. */
43
+ withoutIcon?: boolean;
44
+ }): ReactNode;
45
+ export {};
46
+ //# sourceMappingURL=DisplayModeOverrideRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DisplayModeOverrideRow.d.ts","sourceRoot":"","sources":["../../../src/admin/components/DisplayModeOverrideRow.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAM5D,KAAK,KAAK,GAAG,cAAc,GAAG,UAAU,GAAG,SAAS,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,SAAS,CAsGZ"}
@@ -0,0 +1,109 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Eye } from 'lucide-react';
4
+ import { ApiError, apiClient } from '@endora-commerce/admin-kit/lib';
5
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
6
+ /**
7
+ * Per-entity display-mode override row (feature 011, US7 / T089 + T090).
8
+ *
9
+ * Reads the current override (if any) from
10
+ * `/api/v1/admin/pricing/display-mode-overrides/:scope/:targetId` and writes it
11
+ * with a `PUT`. `inherit` removes the override and reverts the entity to its
12
+ * parent in the resolution chain.
13
+ *
14
+ * ## What moved with it, and what did not (feature 091, P7a)
15
+ *
16
+ * The file used to live at `admin/src/modules/price_lists/`, imported by path
17
+ * from `catalog`'s category editor and `organizations`' detail screen — two of
18
+ * the admin keys the boundary ledger recorded. It is this module's control, so
19
+ * it lives in this module's package and reaches its consumers through zone
20
+ * contributions instead.
21
+ *
22
+ * **`label` and `inheritHint` did not come with it.** Both hosts passed their
23
+ * own copy for this module's control (`categories.priceDisplayMode.label`,
24
+ * `organizations.detail.pricingLabel`), which a zone cannot do: a host cannot
25
+ * hand copy to a contributor it does not know. The row renders
26
+ * `priceLists.displayMode.rowLabel` and its own hint, in every place it appears.
27
+ *
28
+ * The copy stays in the `core` namespace rather than moving to this module's
29
+ * own. That is the larger population
30
+ * `contracts/admin-component-contribution.md` §9.2 measured and deliberately
31
+ * did **not** rule on — 62 files under the admin's module root render out of
32
+ * `core` — and neither P7a nor P7b is the merge request that answers it.
33
+ *
34
+ * **P7b deleted the second copy.** One stood at
35
+ * `admin/src/modules/price_lists/DisplayModeOverrideRow.tsx` for the length of
36
+ * P7a, keeping the two props because `organizations`' detail screen still
37
+ * passed them; that screen is a zone mount now, nothing imported the file, and
38
+ * it is gone. Nothing in this estate compares two copies of one component, so
39
+ * the shorter that state lasts the better — which is why the retiring condition
40
+ * was written into this block rather than left to be remembered.
41
+ */
42
+ export function DisplayModeOverrideRow(props) {
43
+ const t = useTranslation('core');
44
+ const { scope, targetId, withoutIcon } = props;
45
+ const MODE_LABEL = {
46
+ inherit: t('priceLists.displayMode.inherit'),
47
+ gross_only: t('priceLists.displayMode.grossOnly'),
48
+ net_only: t('priceLists.displayMode.netOnly'),
49
+ both: t('priceLists.displayMode.both'),
50
+ none: t('priceLists.displayMode.none'),
51
+ };
52
+ const [mode, setMode] = useState('inherit');
53
+ const [loading, setLoading] = useState(true);
54
+ const [submitting, setSubmitting] = useState(false);
55
+ const [error, setError] = useState(null);
56
+ const [saved, setSaved] = useState(false);
57
+ useEffect(() => {
58
+ let cancelled = false;
59
+ setLoading(true);
60
+ setError(null);
61
+ apiClient
62
+ .get(`/api/v1/admin/pricing/display-mode-overrides/${scope}/${encodeURIComponent(targetId)}`)
63
+ .then((res) => {
64
+ if (!cancelled)
65
+ setMode(res.data.mode);
66
+ })
67
+ .catch((err) => {
68
+ if (cancelled)
69
+ return;
70
+ // 404 means "no override yet — inherits"; anything else is an error.
71
+ if (err instanceof ApiError && err.status === 404)
72
+ setMode('inherit');
73
+ else
74
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Failed to load.');
75
+ })
76
+ .finally(() => {
77
+ if (!cancelled)
78
+ setLoading(false);
79
+ });
80
+ return () => {
81
+ cancelled = true;
82
+ };
83
+ }, [scope, targetId]);
84
+ const handleChange = async (next) => {
85
+ setMode(next);
86
+ setSubmitting(true);
87
+ setError(null);
88
+ setSaved(false);
89
+ try {
90
+ await apiClient.put(`/api/v1/admin/pricing/display-mode-overrides/${scope}/${encodeURIComponent(targetId)}`, { mode: next });
91
+ setSaved(true);
92
+ setTimeout(() => setSaved(false), 1500);
93
+ }
94
+ catch (err) {
95
+ setError(err instanceof ApiError ? err.envelope.error.message : 'Save failed.');
96
+ }
97
+ finally {
98
+ setSubmitting(false);
99
+ }
100
+ };
101
+ return (_jsxs("div", { className: "b2b-col", style: { gap: 4 }, children: [_jsxs("label", { className: "b2b-label", style: { display: 'flex', alignItems: 'center', gap: 6 }, htmlFor: `dm-${scope}-${targetId}`, children: [!withoutIcon ? _jsx(Eye, { size: 12 }) : null, t('priceLists.displayMode.rowLabel'), saved ? (_jsx("span", { style: { color: 'var(--success-soft-fg)', fontSize: 11 }, children: t('priceLists.displayMode.savedSuffix') })) : null] }), _jsx("select", { id: `dm-${scope}-${targetId}`, className: "b2b-field", value: mode, disabled: loading || submitting, onChange: (e) => {
102
+ void handleChange(e.target.value);
103
+ }, children: Object.keys(MODE_LABEL).map((m) => (_jsx("option", { value: m, children: MODE_LABEL[m] }, m))) }), _jsx("div", { className: "b2b-help", style: { marginTop: 2 }, children: mode === 'inherit'
104
+ ? 'Inherits the parent in the resolution chain (Settings → Org → Category → Product).'
105
+ : mode === 'none'
106
+ ? 'Customers will not see a price; Add-to-cart is replaced by Add-to-Quote.'
107
+ : `Customers see prices in the “${MODE_LABEL[mode]}” format on this scope.` }), error ? (_jsx("div", { style: { fontSize: 11, color: 'hsl(8 80% 40%)', marginTop: 2 }, children: error })) : null] }));
108
+ }
109
+ //# sourceMappingURL=DisplayModeOverrideRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DisplayModeOverrideRow.js","sourceRoot":"","sources":["../../../src/admin/components/DisplayModeOverrideRow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAIjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAKtC;IACC,MAAM,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,UAAU,GAA4C;QAC1D,OAAO,EAAE,CAAC,CAAC,gCAAgC,CAAC;QAC5C,UAAU,EAAE,CAAC,CAAC,kCAAkC,CAAC;QACjD,QAAQ,EAAE,CAAC,CAAC,gCAAgC,CAAC;QAC7C,IAAI,EAAE,CAAC,CAAC,6BAA6B,CAAC;QACtC,IAAI,EAAE,CAAC,CAAC,6BAA6B,CAAC;KACvC,CAAC;IACF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAA0B,SAAS,CAAC,CAAC;IACrE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,SAAS;aACN,GAAG,CACF,gDAAgD,KAAK,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CACxF;aACA,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YACZ,IAAI,CAAC,SAAS;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YACtB,IAAI,SAAS;gBAAE,OAAO;YACtB,qEAAqE;YACrE,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,CAAC,SAAS,CAAC,CAAC;;gBACjE,QAAQ,CAAC,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAC1F,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS;gBAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QACL,OAAO,GAAS,EAAE;YAChB,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEtB,MAAM,YAAY,GAAG,KAAK,EAAE,IAA6B,EAAiB,EAAE;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,GAAG,CACjB,gDAAgD,KAAK,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,EACvF,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAClF,CAAC;gBAAS,CAAC;YACT,aAAa,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,SAAS,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,aACxC,iBACE,SAAS,EAAC,WAAW,EACrB,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,EACxD,OAAO,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,aAEjC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAC,GAAG,IAAC,IAAI,EAAE,EAAE,GAAI,CAAC,CAAC,CAAC,IAAI,EACvC,CAAC,CAAC,iCAAiC,CAAC,EACpC,KAAK,CAAC,CAAC,CAAC,CACP,eAAM,KAAK,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,QAAQ,EAAE,EAAE,EAAE,YAC3D,CAAC,CAAC,oCAAoC,CAAC,GACnC,CACR,CAAC,CAAC,CAAC,IAAI,IACF,EACR,iBACE,EAAE,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,EAC7B,SAAS,EAAC,WAAW,EACrB,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,OAAO,IAAI,UAAU,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAQ,EAAE;oBACpB,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAgC,CAAC,CAAC;gBAC/D,CAAC,YAEC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAoC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACtE,iBAAgB,KAAK,EAAE,CAAC,YACrB,UAAU,CAAC,CAAC,CAAC,IADH,CAAC,CAEL,CACV,CAAC,GACK,EACT,cAAK,SAAS,EAAC,UAAU,EAAC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,YAC9C,IAAI,KAAK,SAAS;oBACjB,CAAC,CAAC,oFAAoF;oBACtF,CAAC,CAAC,IAAI,KAAK,MAAM;wBACf,CAAC,CAAC,0EAA0E;wBAC5E,CAAC,CAAC,gCAAgC,UAAU,CAAC,IAAI,CAAC,yBAAyB,GAC3E,EACL,KAAK,CAAC,CAAC,CAAC,CACP,cAAK,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC,EAAE,YAAG,KAAK,GAAO,CACnF,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { type ReactNode } from 'react';
2
+ type PriceListType = 'base' | 'sale';
3
+ type PriceListStatus = 'draft' | 'active' | 'scheduled' | 'expired';
4
+ export interface LinkedPriceListRow {
5
+ list: {
6
+ id: string;
7
+ name: string;
8
+ type: PriceListType;
9
+ status: PriceListStatus;
10
+ modifiedAt: string;
11
+ };
12
+ summary: Array<{
13
+ currencyCode: string;
14
+ summary: string;
15
+ }>;
16
+ deepLinkPath: string;
17
+ }
18
+ /**
19
+ * LinkedPriceListsPanel (US8 / T096) — Pricing tab on the admin
20
+ * product editor.
21
+ *
22
+ * Read-only: lists every price list the product is part of with the
23
+ * per-currency bracket summary and a deep link into the corresponding
24
+ * editor (`/price-lists/:id?focus=:productId`). Brackets and rules are
25
+ * edited on the price-list editor — this panel is just the index.
26
+ *
27
+ * The deep-link path returned by the backend points at
28
+ * `/admin/price-lists/...`; the admin SPA routes the same view at
29
+ * `/price-lists/...`, so we strip the `/admin` prefix when navigating
30
+ * within the React Router tree.
31
+ *
32
+ * **Moved out of `admin/src/modules/price_lists/` by feature 091's P7a**, where
33
+ * `catalog`'s product editor imported it by path — one of the three admin keys
34
+ * in `backend/scripts/ledgers/cross-module-imports/catalog.ts`. It reaches that
35
+ * screen as a `product.editor.pricing.after` contribution now, so neither
36
+ * module names the other.
37
+ */
38
+ export declare function LinkedPriceListsPanel({ productId }: {
39
+ productId: string;
40
+ }): ReactNode;
41
+ /**
42
+ * Pure render of the linked-list table — split out so it can be unit
43
+ * tested via renderToString without booting the data-fetch effect.
44
+ */
45
+ export declare function LinkedPriceListsList({ rows }: {
46
+ rows: LinkedPriceListRow[];
47
+ }): ReactNode;
48
+ /**
49
+ * Backend returns `/admin/price-lists/<id>/products?focus=<pid>`; the admin
50
+ * SPA routes the same view at `/price-lists/<id>?focus=<pid>` — strip the
51
+ * `/admin` prefix and the `/products` suffix to keep the route table simple.
52
+ */
53
+ export declare function toInternalPath(deepLink: string): string;
54
+ export {};
55
+ //# sourceMappingURL=LinkedPriceListsPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkedPriceListsPanel.d.ts","sourceRoot":"","sources":["../../../src/admin/components/LinkedPriceListsPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAO5D,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AACrC,KAAK,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAEpE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,aAAa,CAAC;QACpB,MAAM,EAAE,eAAe,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,OAAO,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,YAAY,EAAE,MAAM,CAAC;CACtB;AAUD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAuFrF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,kBAAkB,EAAE,CAAA;CAAE,GAAG,SAAS,CAwGxF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvD"}