@cellarnode/ui 0.206.0 → 0.207.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 (222) hide show
  1. package/dist/commercial-price/commercial-price-format.d.ts +2 -0
  2. package/dist/commercial-price/commercial-price-format.d.ts.map +1 -1
  3. package/dist/commercial-price/commercial-price-format.js +4 -0
  4. package/dist/commercial-price/commercial-price-format.js.map +1 -1
  5. package/dist/commercial-price/commercial-terms.d.ts.map +1 -1
  6. package/dist/commercial-price/commercial-terms.js +9 -1
  7. package/dist/commercial-price/commercial-terms.js.map +1 -1
  8. package/dist/components/animated-shadcn-select.d.ts +2 -1
  9. package/dist/components/animated-shadcn-select.d.ts.map +1 -1
  10. package/dist/components/animated-shadcn-select.js +1 -1
  11. package/dist/components/animated-shadcn-select.js.map +1 -1
  12. package/dist/components/api-error-message.d.ts +17 -0
  13. package/dist/components/api-error-message.d.ts.map +1 -0
  14. package/dist/components/api-error-message.js +13 -0
  15. package/dist/components/api-error-message.js.map +1 -0
  16. package/dist/components/attachment-row.d.ts.map +1 -1
  17. package/dist/components/attachment-row.js +9 -1
  18. package/dist/components/attachment-row.js.map +1 -1
  19. package/dist/components/branch-resolution-modal.d.ts +9 -1
  20. package/dist/components/branch-resolution-modal.d.ts.map +1 -1
  21. package/dist/components/branch-resolution-modal.js +11 -5
  22. package/dist/components/branch-resolution-modal.js.map +1 -1
  23. package/dist/components/certification-upload-card.d.ts +19 -1
  24. package/dist/components/certification-upload-card.d.ts.map +1 -1
  25. package/dist/components/certification-upload-card.js +35 -7
  26. package/dist/components/certification-upload-card.js.map +1 -1
  27. package/dist/components/composition-editor.d.ts +24 -1
  28. package/dist/components/composition-editor.d.ts.map +1 -1
  29. package/dist/components/composition-editor.js +65 -13
  30. package/dist/components/composition-editor.js.map +1 -1
  31. package/dist/components/currency-select.d.ts +11 -1
  32. package/dist/components/currency-select.d.ts.map +1 -1
  33. package/dist/components/currency-select.js +2 -2
  34. package/dist/components/currency-select.js.map +1 -1
  35. package/dist/components/file-dropzone.d.ts.map +1 -1
  36. package/dist/components/file-dropzone.js +4 -1
  37. package/dist/components/file-dropzone.js.map +1 -1
  38. package/dist/index.d.ts +4 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/lib/describe-api-error.d.ts +19 -0
  43. package/dist/lib/describe-api-error.d.ts.map +1 -0
  44. package/dist/lib/describe-api-error.js +228 -0
  45. package/dist/lib/describe-api-error.js.map +1 -0
  46. package/dist/offer/counter-slide-over.d.ts +38 -12
  47. package/dist/offer/counter-slide-over.d.ts.map +1 -1
  48. package/dist/offer/counter-slide-over.js +130 -36
  49. package/dist/offer/counter-slide-over.js.map +1 -1
  50. package/dist/offer/facts-card.d.ts +3 -1
  51. package/dist/offer/facts-card.d.ts.map +1 -1
  52. package/dist/offer/facts-card.js +19 -10
  53. package/dist/offer/facts-card.js.map +1 -1
  54. package/dist/offer/index.d.ts +1 -1
  55. package/dist/offer/index.d.ts.map +1 -1
  56. package/dist/offer/index.js.map +1 -1
  57. package/dist/offer/negotiation-flow-timeline.d.ts.map +1 -1
  58. package/dist/offer/negotiation-flow-timeline.js +7 -4
  59. package/dist/offer/negotiation-flow-timeline.js.map +1 -1
  60. package/dist/offer/offer-document.d.ts.map +1 -1
  61. package/dist/offer/offer-document.js +8 -30
  62. package/dist/offer/offer-document.js.map +1 -1
  63. package/dist/offer/offer-product-record.d.ts.map +1 -1
  64. package/dist/offer/offer-product-record.js +7 -2
  65. package/dist/offer/offer-product-record.js.map +1 -1
  66. package/dist/offer/offered-product-props.d.ts +20 -0
  67. package/dist/offer/offered-product-props.d.ts.map +1 -0
  68. package/dist/offer/offered-product-props.js +42 -0
  69. package/dist/offer/offered-product-props.js.map +1 -0
  70. package/dist/offer/round-diff-banner.d.ts.map +1 -1
  71. package/dist/offer/round-diff-banner.js +6 -1
  72. package/dist/offer/round-diff-banner.js.map +1 -1
  73. package/dist/offer/terms-card.d.ts.map +1 -1
  74. package/dist/offer/terms-card.js +2 -0
  75. package/dist/offer/terms-card.js.map +1 -1
  76. package/dist/offer/timeline-event.d.ts.map +1 -1
  77. package/dist/offer/timeline-event.js +7 -4
  78. package/dist/offer/timeline-event.js.map +1 -1
  79. package/dist/offer/types.d.ts +4 -0
  80. package/dist/offer/types.d.ts.map +1 -1
  81. package/dist/opportunities/index.d.ts +5 -1
  82. package/dist/opportunities/index.d.ts.map +1 -1
  83. package/dist/opportunities/index.js +2 -0
  84. package/dist/opportunities/index.js.map +1 -1
  85. package/dist/opportunities/wizard/allowed-delivery-terms-section.d.ts +14 -1
  86. package/dist/opportunities/wizard/allowed-delivery-terms-section.d.ts.map +1 -1
  87. package/dist/opportunities/wizard/allowed-delivery-terms-section.js +84 -4
  88. package/dist/opportunities/wizard/allowed-delivery-terms-section.js.map +1 -1
  89. package/dist/opportunities/wizard/mixed-delivery-terms.d.ts +25 -0
  90. package/dist/opportunities/wizard/mixed-delivery-terms.d.ts.map +1 -0
  91. package/dist/opportunities/wizard/mixed-delivery-terms.js +33 -0
  92. package/dist/opportunities/wizard/mixed-delivery-terms.js.map +1 -0
  93. package/dist/opportunities/wizard/opportunity-wizard.d.ts +18 -0
  94. package/dist/opportunities/wizard/opportunity-wizard.d.ts.map +1 -1
  95. package/dist/opportunities/wizard/opportunity-wizard.js +30 -63
  96. package/dist/opportunities/wizard/opportunity-wizard.js.map +1 -1
  97. package/dist/opportunities/wizard/package-sizes-field.d.ts +13 -0
  98. package/dist/opportunities/wizard/package-sizes-field.d.ts.map +1 -0
  99. package/dist/opportunities/wizard/package-sizes-field.js +66 -0
  100. package/dist/opportunities/wizard/package-sizes-field.js.map +1 -0
  101. package/dist/opportunities/wizard/price-ranges-editor.d.ts +17 -0
  102. package/dist/opportunities/wizard/price-ranges-editor.d.ts.map +1 -0
  103. package/dist/opportunities/wizard/price-ranges-editor.js +84 -0
  104. package/dist/opportunities/wizard/price-ranges-editor.js.map +1 -0
  105. package/dist/opportunities/wizard/price-ranges.d.ts +54 -0
  106. package/dist/opportunities/wizard/price-ranges.d.ts.map +1 -0
  107. package/dist/opportunities/wizard/price-ranges.js +104 -0
  108. package/dist/opportunities/wizard/price-ranges.js.map +1 -0
  109. package/dist/opportunities/wizard/publish-issues.d.ts +32 -0
  110. package/dist/opportunities/wizard/publish-issues.d.ts.map +1 -0
  111. package/dist/opportunities/wizard/publish-issues.js +124 -0
  112. package/dist/opportunities/wizard/publish-issues.js.map +1 -0
  113. package/dist/opportunities/wizard/step-opportunities.d.ts.map +1 -1
  114. package/dist/opportunities/wizard/step-opportunities.js +12 -7
  115. package/dist/opportunities/wizard/step-opportunities.js.map +1 -1
  116. package/dist/opportunities/wizard/step-pricing-timeline.d.ts +1 -1
  117. package/dist/opportunities/wizard/step-pricing-timeline.d.ts.map +1 -1
  118. package/dist/opportunities/wizard/step-pricing-timeline.js +7 -9
  119. package/dist/opportunities/wizard/step-pricing-timeline.js.map +1 -1
  120. package/dist/opportunities/wizard/step-review.d.ts +19 -3
  121. package/dist/opportunities/wizard/step-review.d.ts.map +1 -1
  122. package/dist/opportunities/wizard/step-review.js +58 -13
  123. package/dist/opportunities/wizard/step-review.js.map +1 -1
  124. package/dist/opportunities/wizard/wizard.types.d.ts +4 -4
  125. package/dist/opportunities/wizard/wizard.types.d.ts.map +1 -1
  126. package/dist/opportunities/wizard/wizard.types.js +13 -6
  127. package/dist/opportunities/wizard/wizard.types.js.map +1 -1
  128. package/dist/opportunity-facts/build-opportunity-facts.d.ts.map +1 -1
  129. package/dist/opportunity-facts/build-opportunity-facts.js +11 -1
  130. package/dist/opportunity-facts/build-opportunity-facts.js.map +1 -1
  131. package/dist/opportunity-facts/glossary.en.d.ts +34 -0
  132. package/dist/opportunity-facts/glossary.en.d.ts.map +1 -1
  133. package/dist/opportunity-facts/glossary.en.js +34 -0
  134. package/dist/opportunity-facts/glossary.en.js.map +1 -1
  135. package/dist/opportunity-facts/index.d.ts +3 -1
  136. package/dist/opportunity-facts/index.d.ts.map +1 -1
  137. package/dist/opportunity-facts/index.js +2 -0
  138. package/dist/opportunity-facts/index.js.map +1 -1
  139. package/dist/opportunity-facts/labels.d.ts +38 -0
  140. package/dist/opportunity-facts/labels.d.ts.map +1 -1
  141. package/dist/opportunity-facts/labels.js +34 -0
  142. package/dist/opportunity-facts/labels.js.map +1 -1
  143. package/dist/opportunity-facts/opportunity-fact-sheet.d.ts +9 -1
  144. package/dist/opportunity-facts/opportunity-fact-sheet.d.ts.map +1 -1
  145. package/dist/opportunity-facts/opportunity-fact-sheet.js +21 -2
  146. package/dist/opportunity-facts/opportunity-fact-sheet.js.map +1 -1
  147. package/dist/opportunity-facts/price-cases-section.d.ts +18 -0
  148. package/dist/opportunity-facts/price-cases-section.d.ts.map +1 -0
  149. package/dist/opportunity-facts/price-cases-section.js +36 -0
  150. package/dist/opportunity-facts/price-cases-section.js.map +1 -0
  151. package/dist/opportunity-facts/price-cases.d.ts +5 -0
  152. package/dist/opportunity-facts/price-cases.d.ts.map +1 -0
  153. package/dist/opportunity-facts/price-cases.js +127 -0
  154. package/dist/opportunity-facts/price-cases.js.map +1 -0
  155. package/dist/opportunity-facts/source-document-download.d.ts +34 -0
  156. package/dist/opportunity-facts/source-document-download.d.ts.map +1 -0
  157. package/dist/opportunity-facts/source-document-download.js +91 -0
  158. package/dist/opportunity-facts/source-document-download.js.map +1 -0
  159. package/dist/opportunity-facts/types.d.ts +69 -0
  160. package/dist/opportunity-facts/types.d.ts.map +1 -1
  161. package/dist/portfolio-import/review-queue-panel.d.ts.map +1 -1
  162. package/dist/portfolio-import/review-queue-panel.js +36 -4
  163. package/dist/portfolio-import/review-queue-panel.js.map +1 -1
  164. package/dist/portfolio-import/session/index.d.ts +1 -1
  165. package/dist/portfolio-import/session/index.d.ts.map +1 -1
  166. package/dist/portfolio-import/session/index.js +1 -1
  167. package/dist/portfolio-import/session/index.js.map +1 -1
  168. package/dist/portfolio-import/session/save-review-field.d.ts +29 -4
  169. package/dist/portfolio-import/session/save-review-field.d.ts.map +1 -1
  170. package/dist/portfolio-import/session/save-review-field.js +115 -30
  171. package/dist/portfolio-import/session/save-review-field.js.map +1 -1
  172. package/dist/portfolio-import/session/types.d.ts +6 -0
  173. package/dist/portfolio-import/session/types.d.ts.map +1 -1
  174. package/dist/portfolio-import/types.d.ts +6 -0
  175. package/dist/portfolio-import/types.d.ts.map +1 -1
  176. package/dist/portfolio-import/types.js.map +1 -1
  177. package/dist/product-editor/field-routing.d.ts +2 -1
  178. package/dist/product-editor/field-routing.d.ts.map +1 -1
  179. package/dist/product-editor/field-routing.js +9 -1
  180. package/dist/product-editor/field-routing.js.map +1 -1
  181. package/dist/product-editor/index.d.ts +1 -1
  182. package/dist/product-editor/index.d.ts.map +1 -1
  183. package/dist/product-editor/index.js.map +1 -1
  184. package/dist/product-editor/product-editor-form.d.ts +37 -2
  185. package/dist/product-editor/product-editor-form.d.ts.map +1 -1
  186. package/dist/product-editor/product-editor-form.js +96 -3
  187. package/dist/product-editor/product-editor-form.js.map +1 -1
  188. package/dist/product-editor/product-editor-surface.d.ts.map +1 -1
  189. package/dist/product-editor/product-editor-surface.js +2 -4
  190. package/dist/product-editor/product-editor-surface.js.map +1 -1
  191. package/dist/product-editor/product-editor.d.ts.map +1 -1
  192. package/dist/product-editor/product-editor.js +17 -6
  193. package/dist/product-editor/product-editor.js.map +1 -1
  194. package/dist/product-editor/schema.d.ts +20 -0
  195. package/dist/product-editor/schema.d.ts.map +1 -1
  196. package/dist/product-editor/schema.js +70 -0
  197. package/dist/product-editor/schema.js.map +1 -1
  198. package/dist/product-editor/tabs/product-composition-section.d.ts +26 -0
  199. package/dist/product-editor/tabs/product-composition-section.d.ts.map +1 -0
  200. package/dist/product-editor/tabs/product-composition-section.js +47 -0
  201. package/dist/product-editor/tabs/product-composition-section.js.map +1 -0
  202. package/dist/product-editor/tabs/product-essentials-details-sections.d.ts +4 -2
  203. package/dist/product-editor/tabs/product-essentials-details-sections.d.ts.map +1 -1
  204. package/dist/product-editor/tabs/product-essentials-details-sections.js +4 -2
  205. package/dist/product-editor/tabs/product-essentials-details-sections.js.map +1 -1
  206. package/dist/product-editor/tabs/product-essentials-tab.d.ts +4 -2
  207. package/dist/product-editor/tabs/product-essentials-tab.d.ts.map +1 -1
  208. package/dist/product-editor/tabs/product-essentials-tab.js +2 -2
  209. package/dist/product-editor/tabs/product-essentials-tab.js.map +1 -1
  210. package/dist/product-editor/tabs/product-production-capacity-field.d.ts +23 -0
  211. package/dist/product-editor/tabs/product-production-capacity-field.d.ts.map +1 -0
  212. package/dist/product-editor/tabs/product-production-capacity-field.js +57 -0
  213. package/dist/product-editor/tabs/product-production-capacity-field.js.map +1 -0
  214. package/dist/product-editor/tabs/product-resources-tab.d.ts.map +1 -1
  215. package/dist/product-editor/tabs/product-resources-tab.js +1 -1
  216. package/dist/product-editor/tabs/product-resources-tab.js.map +1 -1
  217. package/dist/product-editor/tabs/resources/certifications-panel.d.ts.map +1 -1
  218. package/dist/product-editor/tabs/resources/certifications-panel.js +47 -47
  219. package/dist/product-editor/tabs/resources/certifications-panel.js.map +1 -1
  220. package/dist/product-editor/types.d.ts +61 -4
  221. package/dist/product-editor/types.d.ts.map +1 -1
  222. package/package.json +1 -1
@@ -0,0 +1,127 @@
1
+ /**
2
+ * CEL-2594: headless view-model for the buyer's price cases (`qualifiedPriceTerms[]`) and
3
+ * purchase rounds (`purchaseSchedule[]`) on an opportunity.
4
+ *
5
+ * Display only. A price case carries no delivery term and none is invented here (D16), and
6
+ * its review state is neither shown nor interpreted (CEL-2595). Only what the wire states is
7
+ * rendered; a missing kind, currency or basis is said to be missing, never guessed.
8
+ */
9
+ import { formatCommercialAmount } from "../commercial-price/commercial-price-format.js";
10
+ import { presentText } from "./format.js";
11
+ function formatDate(value, locale) {
12
+ const day = /^\d{4}-\d{2}-\d{2}/.exec(value)?.[0];
13
+ if (!day)
14
+ return value;
15
+ const parsed = new Date(`${day}T00:00:00.000Z`);
16
+ if (Number.isNaN(parsed.getTime()))
17
+ return value;
18
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeZone: "UTC" }).format(parsed);
19
+ }
20
+ export function buildPriceCases(opportunity, locale, labels) {
21
+ const terms = opportunity.qualifiedPriceTerms ?? [];
22
+ const L = labels.priceCases;
23
+ return terms.map((term, index) => {
24
+ const kind = term.priceKind === "input" || term.priceKind === "retail" || term.priceKind === "other"
25
+ ? term.priceKind
26
+ : "unknown";
27
+ const currencyMissing = !presentText(term.currency ?? null);
28
+ // Without a currency, `formatMoney` appends a placeholder dash; show the bare figures and
29
+ // say the currency is missing instead.
30
+ const plain = (n) => new Intl.NumberFormat(locale).format(n);
31
+ const min = typeof term.min === "number" ? term.min : null;
32
+ const max = typeof term.max === "number" ? term.max : null;
33
+ const amount = currencyMissing
34
+ ? min != null && max != null
35
+ ? min === max
36
+ ? plain(min)
37
+ : labels.commercial.range(plain(min), plain(max))
38
+ : min != null
39
+ ? labels.commercial.from(plain(min))
40
+ : max != null
41
+ ? labels.commercial.upTo(plain(max))
42
+ : labels.commercial.notSpecified
43
+ : formatCommercialAmount({ min: term.min ?? null, max: term.max ?? null, currency: term.currency ?? null }, locale, labels.commercial);
44
+ const basis = term.basis === "per_unit"
45
+ ? labels.basis.perUnit
46
+ : term.basis === "per_litre"
47
+ ? labels.basis.perLitre
48
+ : term.basis === "other"
49
+ ? labels.basis.other
50
+ : null;
51
+ const conditions = [];
52
+ if (typeof term.volumeMl === "number" && term.volumeMl > 0) {
53
+ conditions.push(L.packageSize(new Intl.NumberFormat(locale).format(term.volumeMl)));
54
+ }
55
+ if (term.organicStatus === "organic")
56
+ conditions.push(L.organic);
57
+ if (term.organicStatus === "conventional")
58
+ conditions.push(L.conventional);
59
+ const cert = presentText(term.certificationText ?? null);
60
+ if (cert)
61
+ conditions.push(cert);
62
+ if (term.assortmentKind === "fixed")
63
+ conditions.push(L.assortmentFixed);
64
+ if (term.assortmentKind === "temporary")
65
+ conditions.push(L.assortmentTemporary);
66
+ if (typeof term.purchaseOrdinal === "number") {
67
+ conditions.push(L.round(String(term.purchaseOrdinal)));
68
+ }
69
+ // Keep the extracted qualifier opaque. It may contain a restriction that did not fit a
70
+ // structured field, so preserve its wording without interpreting it as a delivery term.
71
+ const sourceQualifier = presentText(term.rawQualifier ?? null);
72
+ // Extraction can expose the same wording in both fields. Compare only after trimming,
73
+ // Unicode normalization, whitespace folding and case folding; do not erase punctuation
74
+ // or negate/rewrite wording, since those can change a restriction's meaning.
75
+ const unresolved = presentText(term.unresolvedQualifierText ?? null);
76
+ const qualifierKey = (value) => value.normalize("NFKC").replace(/\s+/g, " ").toLowerCase();
77
+ if (unresolved &&
78
+ (!sourceQualifier || qualifierKey(unresolved) !== qualifierKey(sourceQualifier))) {
79
+ conditions.push(unresolved);
80
+ }
81
+ return {
82
+ key: `case-${index}`,
83
+ kind,
84
+ kindLabel: {
85
+ input: L.kindInput,
86
+ retail: L.kindShelf,
87
+ other: L.kindOther,
88
+ unknown: L.kindUnknown,
89
+ }[kind],
90
+ amount,
91
+ basis,
92
+ currencyMissing,
93
+ basisMissing: basis === null,
94
+ conditions,
95
+ sourceQualifier,
96
+ source: presentText(term.sourceText ?? null),
97
+ sourcePage: typeof term.sourcePage === "number" ? term.sourcePage : null,
98
+ };
99
+ });
100
+ }
101
+ export function buildPurchaseRounds(opportunity, locale, labels) {
102
+ const L = labels.priceCases;
103
+ return (opportunity.purchaseSchedule ?? []).map((item, index) => {
104
+ const details = [];
105
+ if (item.assortmentKind === "fixed")
106
+ details.push(L.assortmentFixed);
107
+ if (item.assortmentKind === "temporary")
108
+ details.push(L.assortmentTemporary);
109
+ const assortment = presentText(item.assortmentText ?? null);
110
+ if (assortment)
111
+ details.push(assortment);
112
+ const launch = presentText(item.launchDate ?? null);
113
+ if (launch)
114
+ details.push(L.launch(formatDate(launch, locale)));
115
+ const distribution = presentText(item.distribution ?? null);
116
+ if (distribution)
117
+ details.push(distribution);
118
+ return {
119
+ key: `round-${index}`,
120
+ title: L.round(String(item.ordinal)),
121
+ details,
122
+ source: presentText(item.sourceText ?? null),
123
+ sourcePage: typeof item.sourcePage === "number" ? item.sourcePage : null,
124
+ };
125
+ });
126
+ }
127
+ //# sourceMappingURL=price-cases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price-cases.js","sourceRoot":"","sources":["../../src/opportunity-facts/price-cases.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { OpportunityFactLabels } from "./labels.js";
2
+ import type { Perspective } from "./types.js";
3
+ export interface SourceDocumentDownloadProps {
4
+ /** The tender or opportunity source document's storage key (`documentStorageKey`). */
5
+ readonly storageKey: string;
6
+ /**
7
+ * Resolves a FRESH signed URL for the key (the backend's `POST /download/url`). It is called
8
+ * on every click, never cached, so an expired link cannot happen. Reject with an error that
9
+ * carries `status` (HTTP) or `code` when the backend answered, so the copy can be specific.
10
+ */
11
+ readonly getDownloadUrl: (storageKey: string) => Promise<{
12
+ readonly url: string;
13
+ }>;
14
+ readonly labels: OpportunityFactLabels;
15
+ /**
16
+ * Who is looking. The tender's own importer can attach the document, so they get the instruction to do that;
17
+ * everyone else (a producer, an importer reading someone else's tender) can only be told the buyer has not.
18
+ */
19
+ readonly perspective?: Perspective;
20
+ readonly className?: string;
21
+ }
22
+ /**
23
+ * CEL-2596: one reliable "download the source document" control for every opportunity view.
24
+ *
25
+ * Why it exists: the per-app buttons called `window.open(url)` AFTER awaiting the signed URL.
26
+ * Browsers only allow a new tab inside the click itself, so Safari and strict popup settings
27
+ * silently blocked it, and a failed request (404, expired session) left no message at all.
28
+ *
29
+ * This opens the tab synchronously on click (blank), navigates it once the URL arrives, and:
30
+ * - if the browser still blocked the tab, shows a visible link to the document instead;
31
+ * - if the request failed, says so in words, with the fix, and offers Try again.
32
+ */
33
+ export declare function SourceDocumentDownload(props: SourceDocumentDownloadProps): import("react/jsx-runtime").JSX.Element;
34
+ //# sourceMappingURL=source-document-download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-document-download.d.ts","sourceRoot":"","sources":["../../src/opportunity-facts/source-document-download.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,WAAW,2BAA2B;IAC1C,sFAAsF;IACtF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnF,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAwBD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,2CAIxE"}
@@ -0,0 +1,91 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { Download, Loader2 } from "lucide-react";
4
+ import { cn } from "../lib/utils.js";
5
+ function errorKind(error) {
6
+ const e = error;
7
+ const message = typeof e?.message === "string" ? e.message : "";
8
+ if (e?.status === 401 ||
9
+ e?.status === 403 ||
10
+ /\b40[13]\b|UNAUTHORI[SZ]ED|FORBIDDEN/i.test(message)) {
11
+ return "session";
12
+ }
13
+ if (e?.status === 404 || e?.code === "FILE_NOT_FOUND" || /FILE_NOT_FOUND|\b404\b/.test(message)) {
14
+ return "notFound";
15
+ }
16
+ return "failed";
17
+ }
18
+ /**
19
+ * CEL-2596: one reliable "download the source document" control for every opportunity view.
20
+ *
21
+ * Why it exists: the per-app buttons called `window.open(url)` AFTER awaiting the signed URL.
22
+ * Browsers only allow a new tab inside the click itself, so Safari and strict popup settings
23
+ * silently blocked it, and a failed request (404, expired session) left no message at all.
24
+ *
25
+ * This opens the tab synchronously on click (blank), navigates it once the URL arrives, and:
26
+ * - if the browser still blocked the tab, shows a visible link to the document instead;
27
+ * - if the request failed, says so in words, with the fix, and offers Try again.
28
+ */
29
+ export function SourceDocumentDownload(props) {
30
+ // A document change is a new interaction lifetime. Keying the internal instance here keeps
31
+ // that guarantee for both direct consumers and controls created by OpportunityFactSheet.
32
+ return _jsx(SourceDocumentDownloadForDocument, { ...props }, props.storageKey);
33
+ }
34
+ function SourceDocumentDownloadForDocument({ storageKey, getDownloadUrl, labels, perspective, className, }) {
35
+ const L = labels.sourceDocument;
36
+ const [state, setState] = React.useState({ phase: "idle" });
37
+ const activeRequest = React.useRef(null);
38
+ React.useEffect(() => () => {
39
+ // Do not leave a blank popup behind or let a late URL navigate it after this document
40
+ // has been replaced or the control has been removed.
41
+ const request = activeRequest.current;
42
+ if (request) {
43
+ request.cancelled = true;
44
+ request.tab?.close();
45
+ activeRequest.current = null;
46
+ }
47
+ }, []);
48
+ const start = async () => {
49
+ // A second click while this request is in flight would open a second tab: ignore it.
50
+ if (activeRequest.current)
51
+ return;
52
+ // Synchronous, inside the user gesture: this is what makes the tab openable at all.
53
+ const tab = window.open("", "_blank");
54
+ if (tab)
55
+ tab.opener = null;
56
+ const request = { tab, cancelled: false };
57
+ activeRequest.current = request;
58
+ setState({ phase: "loading" });
59
+ try {
60
+ const { url } = await getDownloadUrl(storageKey);
61
+ if (request.cancelled || activeRequest.current !== request)
62
+ return;
63
+ if (request.tab && !request.tab.closed) {
64
+ request.tab.location.href = url;
65
+ setState({ phase: "idle" });
66
+ }
67
+ else {
68
+ setState({ phase: "blocked", url });
69
+ }
70
+ }
71
+ catch (error) {
72
+ if (request.cancelled || activeRequest.current !== request)
73
+ return;
74
+ request.tab?.close();
75
+ setState({ phase: "error", kind: errorKind(error) });
76
+ }
77
+ finally {
78
+ if (activeRequest.current === request)
79
+ activeRequest.current = null;
80
+ }
81
+ };
82
+ const loading = state.phase === "loading";
83
+ return (_jsxs("div", { className: cn("flex flex-col items-start gap-2", className), children: [_jsxs("button", { type: "button", onClick: () => void start(), "aria-disabled": loading || undefined, "aria-busy": loading || undefined, className: "inline-flex min-h-11 items-center gap-2 rounded-md border border-border bg-background px-3 text-sm/5 font-medium text-foreground transition-[color,background-color,transform] duration-[var(--duration-micro)] ease-[var(--ease-emphasized)] hover:bg-muted active:scale-[0.98] focus-visible:outline-hidden focus-visible:ring-3 focus-visible:ring-ring/70 aria-disabled:cursor-progress aria-disabled:opacity-70", children: [loading ? (_jsx(Loader2, { "aria-hidden": true, className: "size-4 animate-spin motion-reduce:animate-none" })) : (_jsx(Download, { "aria-hidden": true, className: "size-4", strokeWidth: 1.75 })), state.phase === "error" ? L.tryAgain : L.download] }), _jsxs("div", { "aria-live": "polite", className: "text-sm/5", children: [loading ? _jsx("span", { className: "sr-only", children: L.opening }) : null, state.phase === "blocked" ? (_jsxs("p", { className: "max-w-prose text-muted-foreground", children: [L.blocked, " ", _jsx("a", { href: state.url, target: "_blank", rel: "noopener noreferrer", className: "font-medium text-foreground underline underline-offset-2 focus-visible:outline-hidden focus-visible:ring-3 focus-visible:ring-ring/70", children: L.openLink })] })) : null, state.phase === "error" ? (_jsx("p", { role: "alert", className: "max-w-prose text-[var(--tone-danger-fg)]", children: state.kind === "session"
84
+ ? L.sessionExpired
85
+ : state.kind === "notFound"
86
+ ? perspective === "importer-owner"
87
+ ? L.notFoundOwner
88
+ : L.notFoundViewer
89
+ : L.failed })) : null] })] }));
90
+ }
91
+ //# sourceMappingURL=source-document-download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-document-download.js","sourceRoot":"","sources":["../../src/opportunity-facts/source-document-download.tsx"],"names":[],"mappings":"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"}
@@ -62,6 +62,65 @@ export interface FactSection {
62
62
  * exactly the leakage this builder exists to remove.
63
63
  */
64
64
  export type CommercialTermsData = Omit<CommercialTermsProps, "labels" | "locale" | "priceTypeLabel" | "deliveryTermLabel" | "className" | "perspective">;
65
+ /** CEL-2594 — one price case as the wire states it (`qualifiedPriceTerms[]`). All optional: older records omit them. */
66
+ export interface PublicOpportunityQualifiedPriceTerm {
67
+ readonly min?: number | null;
68
+ readonly max?: number | null;
69
+ readonly currency?: string | null;
70
+ readonly basis?: "per_unit" | "per_litre" | "other" | null;
71
+ readonly priceKind?: "retail" | "input" | "other" | null;
72
+ readonly volumeMl?: number | null;
73
+ readonly organicStatus?: "organic" | "conventional" | null;
74
+ readonly certificationText?: string | null;
75
+ readonly assortmentKind?: "fixed" | "temporary" | null;
76
+ readonly purchaseOrdinal?: number | null;
77
+ readonly rawQualifier?: string | null;
78
+ readonly unresolvedQualifierText?: string | null;
79
+ readonly sourceText?: string | null;
80
+ readonly sourcePage?: number | null;
81
+ /** Present on the wire; deliberately not rendered or interpreted (CEL-2595). */
82
+ readonly reviewState?: unknown;
83
+ readonly reviewCurrent?: boolean;
84
+ }
85
+ /** CEL-2594 — one purchase round (`purchaseSchedule[]`). */
86
+ export interface PublicOpportunityPurchaseScheduleItem {
87
+ readonly ordinal: number;
88
+ readonly assortmentKind?: "fixed" | "temporary" | null;
89
+ readonly assortmentText?: string | null;
90
+ readonly launchDate?: string | null;
91
+ readonly distribution?: string | null;
92
+ readonly sourceText?: string | null;
93
+ readonly sourcePage?: number | null;
94
+ readonly reviewState?: unknown;
95
+ readonly reviewCurrent?: boolean;
96
+ }
97
+ export type PriceCaseKind = "input" | "retail" | "other" | "unknown";
98
+ /** CEL-2594 — display model of one price case; every string is already localized. */
99
+ export interface PriceCaseView {
100
+ readonly key: string;
101
+ readonly kind: PriceCaseKind;
102
+ readonly kindLabel: string;
103
+ /** "EUR 5.50 to EUR 7.50", "From ...", "Up to ...", or the not-specified copy. */
104
+ readonly amount: string;
105
+ /** "per unit" and so on; `null` when the wire has no basis. */
106
+ readonly basis: string | null;
107
+ readonly currencyMissing: boolean;
108
+ /** True when the wire has no basis, so the view says so instead of staying silent. */
109
+ readonly basisMissing: boolean;
110
+ /** Structured conditions the wire states (size, organic, certification, assortment, round). */
111
+ readonly conditions: readonly string[];
112
+ /** Opaque qualifier preserved as source wording; it is not interpreted as a delivery term. */
113
+ readonly sourceQualifier: string | null;
114
+ readonly source: string | null;
115
+ readonly sourcePage: number | null;
116
+ }
117
+ export interface PurchaseRoundView {
118
+ readonly key: string;
119
+ readonly title: string;
120
+ readonly details: readonly string[];
121
+ readonly source: string | null;
122
+ readonly sourcePage: number | null;
123
+ }
65
124
  export interface FactSheet {
66
125
  /** Exactly five, order fixed per perspective (spec §2). */
67
126
  readonly strip: readonly Fact[];
@@ -72,6 +131,12 @@ export interface FactSheet {
72
131
  readonly commercialTerms: CommercialTermsData;
73
132
  /** Every fact whose state is not `"known"`, for the owner's completeness card. */
74
133
  readonly missing: readonly FactKey[];
134
+ /** CEL-2596 — the source document's storage key (`documentStorageKey` of the opportunity, else its tender); `null` when there is none. */
135
+ readonly sourceDocumentKey: string | null;
136
+ /** CEL-2594 — the buyer's price cases, wire order. Empty when the wire has none. */
137
+ readonly priceCases: readonly PriceCaseView[];
138
+ /** CEL-2594 — purchase rounds, wire order. Empty when the wire has none. */
139
+ readonly purchaseRounds: readonly PurchaseRoundView[];
75
140
  }
76
141
  export type { TranslateFn };
77
142
  export interface BuildContext {
@@ -157,6 +222,10 @@ export interface PublicOpportunity {
157
222
  readonly packaging?: string | null;
158
223
  readonly closure?: string | null;
159
224
  readonly priceRanges?: readonly PublicOpportunityPriceRange[] | null;
225
+ /** CEL-2594 — the buyer's price cases. Rendered as a "Price cases" block; no delivery term (D16). */
226
+ readonly qualifiedPriceTerms?: readonly PublicOpportunityQualifiedPriceTerm[] | null;
227
+ /** CEL-2594 — purchase rounds. */
228
+ readonly purchaseSchedule?: readonly PublicOpportunityPurchaseScheduleItem[] | null;
160
229
  readonly styleTasteProfile?: string | null;
161
230
  readonly agingProcess?: string | null;
162
231
  /** CEL-2102 — storage method / container and stated storage time. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/opportunity-facts/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/opportunity-facts/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"review-queue-panel.d.ts","sourceRoot":"","sources":["../../src/portfolio-import/review-queue-panel.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAQ9D,OAAO,KAAK,EAAwB,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE1E,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,gBAAgB,EAAE,UAAU,CAAC;CAC9B;AAiBD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,uEAAuE;IACvE,CAAC,CAAC,EAAE,WAAW,CAAC;IAChB;;;;;;OAMG;IACH,WAAW,EAAE,CACX,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,mBAAmB,KACtB,OAAO,CAAC,IAAI,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1C;;;;;OAKG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;IACvC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAC3F,0EAA0E;IAC1E,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3E,mGAAmG;IACnG,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uDAAuD;IACvD,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;IAC7D,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6CD,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,CAAY,EACZ,WAAW,EACX,cAAc,EACd,SAAS,EACT,OAAO,EACP,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,eAAe,EACf,qBAA6B,EAC7B,UAAU,EACV,gBAAwB,EACxB,kBAAkB,EAClB,SAAS,GACV,EAAE,qBAAqB,kDAuZvB"}
1
+ {"version":3,"file":"review-queue-panel.d.ts","sourceRoot":"","sources":["../../src/portfolio-import/review-queue-panel.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAQ9D,OAAO,KAAK,EAAwB,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE1E,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,gBAAgB,EAAE,UAAU,CAAC;CAC9B;AAgCD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,uEAAuE;IACvE,CAAC,CAAC,EAAE,WAAW,CAAC;IAChB;;;;;;OAMG;IACH,WAAW,EAAE,CACX,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,mBAAmB,KACtB,OAAO,CAAC,IAAI,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1C;;;;;OAKG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;IACvC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAC3F,0EAA0E;IAC1E,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3E,mGAAmG;IACnG,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uDAAuD;IACvD,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;IAC7D,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6CD,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,CAAY,EACZ,WAAW,EACX,cAAc,EACd,SAAS,EACT,OAAO,EACP,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,eAAe,EACf,qBAA6B,EAC7B,UAAU,EACV,gBAAwB,EACxB,kBAAkB,EAClB,SAAS,GACV,EAAE,qBAAqB,kDA4avB"}
@@ -34,6 +34,7 @@ import { ProductProgressList } from "../components/product-progress-list.js";
34
34
  import { groupByParent } from "../lib/group-by-parent.js";
35
35
  import { cn } from "../lib/utils.js";
36
36
  import { interpolate } from "../portfolio/interpolate.js";
37
+ import { reviewFieldLabel } from "./session/review-field-labels.js";
37
38
  import { formatPageAria, formatPageLabel, formatPageTooltip, parsePageRanges, } from "./page-ranges.js";
38
39
  /** Duck-typed read of a rejection's `matchReadiness` payload (a blocked approval). */
39
40
  function readErrorMatchReadiness(err) {
@@ -44,6 +45,17 @@ function readErrorMatchReadiness(err) {
44
45
  return null;
45
46
  return readiness;
46
47
  }
48
+ /** Duck-typed stale-approve rejection (`ReviewStaleVersionError`, code REVIEW_STALE_VERSION). */
49
+ function isStaleVersionRejection(err) {
50
+ return (!!err && typeof err === "object" && err.code === "REVIEW_STALE_VERSION");
51
+ }
52
+ /** Names of changed fields on a stale-approve rejection (null when not named). */
53
+ function readStaleChangedFields(err) {
54
+ const fields = err.changedFields;
55
+ return Array.isArray(fields) && fields.every((f) => typeof f === "string")
56
+ ? fields
57
+ : null;
58
+ }
47
59
  /** Duck-typed read of a rejection's advanced `version` (partial-failure channel). */
48
60
  function readErrorVersion(err) {
49
61
  if (!err || typeof err !== "object")
@@ -94,6 +106,8 @@ export function ReviewQueuePanel({ variants, t = defaultT, onSaveField, savingFi
94
106
  /** Pending corrections per variant id, keyed by field path. */
95
107
  const [edits, setEdits] = React.useState({});
96
108
  /** Panel-initiated saves not yet reflected in `savingFieldIds`. */
109
+ /** Rows whose approve hit a version conflict: approval stays off until a safe reload. */
110
+ const [stale, setStale] = React.useState({});
97
111
  const [localSaving, setLocalSaving] = React.useState(() => new Set());
98
112
  const [isRejecting, setIsRejecting] = React.useState(false);
99
113
  // CEL-1108 — the latest known variant version per row, seeded from the
@@ -184,6 +198,8 @@ export function ReviewQueuePanel({ variants, t = defaultT, onSaveField, savingFi
184
198
  };
185
199
  const isApproving = savingSet.size > 0 || localSaving.size > 0;
186
200
  const handleApprove = React.useCallback(async (variant) => {
201
+ if (stale[variant.id])
202
+ return;
187
203
  const corrections = edits[variant.id] ?? {};
188
204
  // Effective version: the panel's latest known version for this row
189
205
  // (advanced by a prior save outcome), falling back to the prop version.
@@ -197,6 +213,15 @@ export function ReviewQueuePanel({ variants, t = defaultT, onSaveField, savingFi
197
213
  markReviewed(variant.id);
198
214
  }
199
215
  catch (err) {
216
+ // CEL-2674: the product changed after the reviewer looked. Never adopt
217
+ // a version or retry; ask for a new review.
218
+ if (isStaleVersionRejection(err)) {
219
+ // Same human labels the review rows use, never the raw keys.
220
+ const changedFields = readStaleChangedFields(err)?.map((path) => reviewFieldLabel(path, t)) ?? null;
221
+ setStale((prev) => ({ ...prev, [variant.id]: { changedFields } }));
222
+ onToast?.("error", `${t("review.staleTitle", "This product changed since you reviewed it")}${changedFields && changedFields.length > 0 ? `: ${changedFields.join(", ")}` : ""}`);
223
+ return;
224
+ }
200
225
  // Partial-failure version channel (CEL-1108): the consumer persisted
201
226
  // the corrections (advancing the server version) but the validation
202
227
  // flip failed — the rejection carries the advanced version so the
@@ -235,7 +260,7 @@ export function ReviewQueuePanel({ variants, t = defaultT, onSaveField, savingFi
235
260
  return next;
236
261
  });
237
262
  }
238
- }, [edits, onSaveField, onToast, onReadinessUpdate, t]);
263
+ }, [edits, stale, onSaveField, onToast, onReadinessUpdate, t]);
239
264
  const handleReject = React.useCallback(async (variant) => {
240
265
  if (!onRejectVariant)
241
266
  return;
@@ -377,13 +402,13 @@ export function ReviewQueuePanel({ variants, t = defaultT, onSaveField, savingFi
377
402
  return {
378
403
  id: variant.id,
379
404
  current: isActive,
380
- content: (_jsx(ReviewRow, { variant: variant, isActive: isActive, isFlagged: variant.flaggedFields.length > 0, isApproving: isApproving, matchReadiness: readinessMap.get(variant.id), onActivate: () => setActiveIndex(idx), onApprove: () => void handleApprove(variant), onSkip: handleSkip, onCaptureFieldEdit: (path, value) => captureFieldEdit(variant.id, path, value), onClearFieldEdit: (path) => clearFieldEdit(variant.id, path), onReject: onRejectVariant ? () => void handleReject(variant) : undefined, isRejecting: isRejecting, onOpenProduct: onOpenProduct, onCitePage: onCitePage, requireKnownReadiness: requireKnownReadiness, enumOptionsError: enumOptionsError, onRetryEnumOptions: onRetryEnumOptions, t: t })),
405
+ content: (_jsx(ReviewRow, { variant: variant, isActive: isActive, isFlagged: variant.flaggedFields.length > 0, isApproving: isApproving, stale: stale[variant.id], matchReadiness: readinessMap.get(variant.id), onActivate: () => setActiveIndex(idx), onApprove: () => void handleApprove(variant), onSkip: handleSkip, onCaptureFieldEdit: (path, value) => captureFieldEdit(variant.id, path, value), onClearFieldEdit: (path) => clearFieldEdit(variant.id, path), onReject: onRejectVariant ? () => void handleReject(variant) : undefined, isRejecting: isRejecting, onOpenProduct: onOpenProduct, onCitePage: onCitePage, requireKnownReadiness: requireKnownReadiness, enumOptionsError: enumOptionsError, onRetryEnumOptions: onRetryEnumOptions, t: t })),
381
406
  };
382
407
  }),
383
408
  };
384
409
  }) })] }));
385
410
  }
386
- function ReviewRow({ variant, isActive, isFlagged, isApproving, matchReadiness, onActivate, onApprove, onSkip, onCaptureFieldEdit, onClearFieldEdit, onReject, isRejecting, onOpenProduct, onCitePage, requireKnownReadiness, enumOptionsError, onRetryEnumOptions, t, }) {
411
+ function ReviewRow({ variant, isActive, isFlagged, isApproving, stale, matchReadiness, onActivate, onApprove, onSkip, onCaptureFieldEdit, onClearFieldEdit, onReject, isRejecting, onOpenProduct, onCitePage, requireKnownReadiness, enumOptionsError, onRetryEnumOptions, t, }) {
387
412
  const [confirmingReject, setConfirmingReject] = React.useState(false);
388
413
  const outerClass = isActive
389
414
  ? `ring-1 ring-[var(--tone-success-border)]/40 bg-[var(--tone-success-soft)]/40 p-1.5 rounded-[1.5rem] ${ACTIVE_ROW_TRANSITION}`
@@ -395,7 +420,13 @@ function ReviewRow({ variant, isActive, isFlagged, isApproving, matchReadiness,
395
420
  // activation control is the display-name button below — an interactive
396
421
  // wrapper (role="button") around the row's own buttons would be a
397
422
  // nested-interactive axe violation (Wave-1 bar: fix semantics, no opt-outs).
398
- return (_jsx("div", { "data-active": isActive ? "true" : "false", "data-row-id": variant.id, className: outerClass, onClick: onActivate, children: _jsxs("div", { className: innerClass, children: [_jsx(ProvenanceEyebrowRow, { isFlagged: isFlagged, flaggedCount: variant.flaggedFields.length, pageRanges: variant.pageRanges ?? null, classifyConfidence: variant.classifyConfidence ?? null, t: t, onCitePage: onCitePage ? () => onCitePage(variant.pageRanges) : undefined }), _jsx("button", { type: "button", "aria-pressed": isActive, "aria-label": interpolate(t("review.activateRow", "Activate row {{name}}"), {
423
+ return (_jsx("div", { "data-active": isActive ? "true" : "false", "data-row-id": variant.id, className: outerClass, onClick: onActivate, children: _jsxs("div", { className: innerClass, children: [_jsx(ProvenanceEyebrowRow, { isFlagged: isFlagged, flaggedCount: variant.flaggedFields.length, pageRanges: variant.pageRanges ?? null, classifyConfidence: variant.classifyConfidence ?? null, t: t, onCitePage: onCitePage ? () => onCitePage(variant.pageRanges) : undefined }), stale && (_jsxs("div", { role: "alert", className: "my-3 flex flex-col gap-2 rounded-lg border px-3 py-2 text-sm/6", style: {
424
+ backgroundColor: "var(--tone-warning-soft)",
425
+ borderColor: "var(--tone-warning-border)",
426
+ color: "var(--tone-warning-fg)",
427
+ }, children: [_jsx("p", { className: "font-semibold", children: t("review.staleTitle", "This product changed since you reviewed it") }), _jsx("p", { children: stale.changedFields && stale.changedFields.length > 0
428
+ ? `${t("review.staleChanged", "Changed fields")}: ${stale.changedFields.join(", ")}`
429
+ : t("review.staleUnknown", "Another session edited this product.") }), _jsx("p", { children: t("review.staleReload", "It was not approved. Reload this import to review it again.") })] })), _jsx("button", { type: "button", "aria-pressed": isActive, "aria-label": interpolate(t("review.activateRow", "Activate row {{name}}"), {
399
430
  name: variant.displayName,
400
431
  }), onClick: (e) => {
401
432
  e.stopPropagation();
@@ -428,6 +459,7 @@ function ReviewRow({ variant, isActive, isFlagged, isApproving, matchReadiness,
428
459
  e.stopPropagation();
429
460
  onApprove();
430
461
  }, disabled: isApproving ||
462
+ stale !== undefined ||
431
463
  (matchReadiness != null && !matchReadiness.canApprove) ||
432
464
  (requireKnownReadiness && matchReadiness == null), className: `group inline-flex items-center gap-3 rounded-full bg-[var(--tone-success-solid)] px-6 py-3 text-[var(--tone-success-solid-fg)] font-semibold shadow-xs hover:brightness-110 disabled:opacity-50 ${ACTIVE_ROW_TRANSITION} hover:scale-[1.02]`, children: [_jsx("span", { children: isApproving
433
465
  ? t("review.approving", "Approving…")