@things-factory/ops-master 10.1.33 → 10.1.35

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 (150) hide show
  1. package/dist-client/index.d.ts +1 -0
  2. package/dist-client/index.js +1 -0
  3. package/dist-client/index.js.map +1 -1
  4. package/dist-client/master-change-approval.d.ts +14 -0
  5. package/dist-client/master-change-approval.js +36 -0
  6. package/dist-client/master-change-approval.js.map +1 -0
  7. package/dist-client/pages/master/material-definition.d.ts +4 -11
  8. package/dist-client/pages/master/material-definition.js +5 -53
  9. package/dist-client/pages/master/material-definition.js.map +1 -1
  10. package/dist-client/pages/master/material-revision-fields.d.ts +2 -0
  11. package/dist-client/pages/master/material-revision-fields.js +43 -0
  12. package/dist-client/pages/master/material-revision-fields.js.map +1 -0
  13. package/dist-client/pages/master/recipe-definition.d.ts +4 -135
  14. package/dist-client/pages/master/recipe-definition.js +7 -397
  15. package/dist-client/pages/master/recipe-definition.js.map +1 -1
  16. package/dist-client/pages/master/revision-comparison.d.ts +48 -0
  17. package/dist-client/pages/master/revision-comparison.js +553 -0
  18. package/dist-client/pages/master/revision-comparison.js.map +1 -0
  19. package/dist-client/pages/master/revision-view.d.ts +19 -0
  20. package/dist-client/pages/master/revision-view.js +133 -0
  21. package/dist-client/pages/master/revision-view.js.map +1 -0
  22. package/dist-client/pages/master/revision-workspace.d.ts +50 -0
  23. package/dist-client/pages/master/revision-workspace.js +752 -0
  24. package/dist-client/pages/master/revision-workspace.js.map +1 -0
  25. package/dist-client/pages/master/test-specification.d.ts +4 -92
  26. package/dist-client/pages/master/test-specification.js +5 -440
  27. package/dist-client/pages/master/test-specification.js.map +1 -1
  28. package/dist-client/tsconfig.tsbuildinfo +1 -1
  29. package/dist-server/service/asset/asset-master-resolver.js +38 -34
  30. package/dist-server/service/asset/asset-master-resolver.js.map +1 -1
  31. package/dist-server/service/asset/index.d.ts +2 -2
  32. package/dist-server/service/equipment/equipment-master-resolver.js +54 -49
  33. package/dist-server/service/equipment/equipment-master-resolver.js.map +1 -1
  34. package/dist-server/service/equipment/index.d.ts +2 -2
  35. package/dist-server/service/index.d.ts +18 -2
  36. package/dist-server/service/index.js +18 -0
  37. package/dist-server/service/index.js.map +1 -1
  38. package/dist-server/service/location/index.d.ts +1 -1
  39. package/dist-server/service/location/location-master-resolver.js +34 -31
  40. package/dist-server/service/location/location-master-resolver.js.map +1 -1
  41. package/dist-server/service/master-axis.js +1 -1
  42. package/dist-server/service/master-axis.js.map +1 -1
  43. package/dist-server/service/master-change-policy.d.ts +23 -0
  44. package/dist-server/service/master-change-policy.js +134 -0
  45. package/dist-server/service/master-change-policy.js.map +1 -0
  46. package/dist-server/service/master-conformance-resolver.js +11 -1
  47. package/dist-server/service/master-conformance-resolver.js.map +1 -1
  48. package/dist-server/service/master-crud.js +9 -0
  49. package/dist-server/service/master-crud.js.map +1 -1
  50. package/dist-server/service/master-list.js +6 -0
  51. package/dist-server/service/master-list.js.map +1 -1
  52. package/dist-server/service/material/index.d.ts +3 -2
  53. package/dist-server/service/material/index.js +4 -2
  54. package/dist-server/service/material/index.js.map +1 -1
  55. package/dist-server/service/material/material-axis-status.d.ts +8 -0
  56. package/dist-server/service/material/material-axis-status.js +19 -0
  57. package/dist-server/service/material/material-axis-status.js.map +1 -0
  58. package/dist-server/service/material/material-definition.d.ts +3 -0
  59. package/dist-server/service/material/material-definition.js +13 -0
  60. package/dist-server/service/material/material-definition.js.map +1 -1
  61. package/dist-server/service/material/material-effective-list.d.ts +39 -0
  62. package/dist-server/service/material/material-effective-list.js +54 -0
  63. package/dist-server/service/material/material-effective-list.js.map +1 -0
  64. package/dist-server/service/material/material-master-resolver.js +59 -61
  65. package/dist-server/service/material/material-master-resolver.js.map +1 -1
  66. package/dist-server/service/material/material-query.js +9 -2
  67. package/dist-server/service/material/material-query.js.map +1 -1
  68. package/dist-server/service/material/material-revision-content.d.ts +10 -0
  69. package/dist-server/service/material/material-revision-content.js +92 -0
  70. package/dist-server/service/material/material-revision-content.js.map +1 -0
  71. package/dist-server/service/material/material-revision-resolver.d.ts +54 -0
  72. package/dist-server/service/material/material-revision-resolver.js +76 -0
  73. package/dist-server/service/material/material-revision-resolver.js.map +1 -0
  74. package/dist-server/service/material/material-revision-service.d.ts +144 -0
  75. package/dist-server/service/material/material-revision-service.js +534 -0
  76. package/dist-server/service/material/material-revision-service.js.map +1 -0
  77. package/dist-server/service/material/material-revision.d.ts +84 -0
  78. package/dist-server/service/material/material-revision.js +339 -0
  79. package/dist-server/service/material/material-revision.js.map +1 -0
  80. package/dist-server/service/operation/index.d.ts +1 -1
  81. package/dist-server/service/operation/operation-definition.js +1 -0
  82. package/dist-server/service/operation/operation-definition.js.map +1 -1
  83. package/dist-server/service/operation/operation-master-resolver.js +30 -30
  84. package/dist-server/service/operation/operation-master-resolver.js.map +1 -1
  85. package/dist-server/service/personnel/index.d.ts +2 -2
  86. package/dist-server/service/personnel/personnel-master-resolver.js +38 -34
  87. package/dist-server/service/personnel/personnel-master-resolver.js.map +1 -1
  88. package/dist-server/service/quality/nonconformance-cause-resolver.js +17 -14
  89. package/dist-server/service/quality/nonconformance-cause-resolver.js.map +1 -1
  90. package/dist-server/service/recipe/index.d.ts +3 -2
  91. package/dist-server/service/recipe/index.js +4 -2
  92. package/dist-server/service/recipe/index.js.map +1 -1
  93. package/dist-server/service/recipe/recipe-definition.d.ts +4 -0
  94. package/dist-server/service/recipe/recipe-definition.js +14 -1
  95. package/dist-server/service/recipe/recipe-definition.js.map +1 -1
  96. package/dist-server/service/recipe/recipe-effective-list.d.ts +49 -0
  97. package/dist-server/service/recipe/recipe-effective-list.js +96 -0
  98. package/dist-server/service/recipe/recipe-effective-list.js.map +1 -0
  99. package/dist-server/service/recipe/recipe-master-resolver.js +32 -28
  100. package/dist-server/service/recipe/recipe-master-resolver.js.map +1 -1
  101. package/dist-server/service/recipe/recipe-query.js +9 -2
  102. package/dist-server/service/recipe/recipe-query.js.map +1 -1
  103. package/dist-server/service/recipe/recipe-revision-content.d.ts +32 -0
  104. package/dist-server/service/recipe/recipe-revision-content.js +65 -0
  105. package/dist-server/service/recipe/recipe-revision-content.js.map +1 -0
  106. package/dist-server/service/recipe/recipe-revision-line.d.ts +30 -0
  107. package/dist-server/service/recipe/recipe-revision-line.js +95 -0
  108. package/dist-server/service/recipe/recipe-revision-line.js.map +1 -0
  109. package/dist-server/service/recipe/recipe-revision-resolver.d.ts +59 -0
  110. package/dist-server/service/recipe/recipe-revision-resolver.js +76 -0
  111. package/dist-server/service/recipe/recipe-revision-resolver.js.map +1 -0
  112. package/dist-server/service/recipe/recipe-revision-service.d.ts +147 -0
  113. package/dist-server/service/recipe/recipe-revision-service.js +591 -0
  114. package/dist-server/service/recipe/recipe-revision-service.js.map +1 -0
  115. package/dist-server/service/recipe/recipe-revision.d.ts +100 -0
  116. package/dist-server/service/recipe/recipe-revision.js +373 -0
  117. package/dist-server/service/recipe/recipe-revision.js.map +1 -0
  118. package/dist-server/service/recipe/route-definition.js +1 -0
  119. package/dist-server/service/recipe/route-definition.js.map +1 -1
  120. package/dist-server/service/resource/class-members.js +9 -0
  121. package/dist-server/service/resource/class-members.js.map +1 -1
  122. package/dist-server/service/status/master-status.js +2 -1
  123. package/dist-server/service/status/master-status.js.map +1 -1
  124. package/dist-server/service/test-spec/index.d.ts +3 -2
  125. package/dist-server/service/test-spec/index.js +4 -2
  126. package/dist-server/service/test-spec/index.js.map +1 -1
  127. package/dist-server/service/test-spec/test-spec-effective-list.d.ts +34 -0
  128. package/dist-server/service/test-spec/test-spec-effective-list.js +42 -0
  129. package/dist-server/service/test-spec/test-spec-effective-list.js.map +1 -0
  130. package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +4 -14
  131. package/dist-server/service/test-spec/test-spec-master-resolver.js +12 -83
  132. package/dist-server/service/test-spec/test-spec-master-resolver.js.map +1 -1
  133. package/dist-server/service/test-spec/test-spec-query.js +7 -1
  134. package/dist-server/service/test-spec/test-spec-query.js.map +1 -1
  135. package/dist-server/service/test-spec/test-spec-revision-resolver.d.ts +53 -0
  136. package/dist-server/service/test-spec/test-spec-revision-resolver.js +76 -0
  137. package/dist-server/service/test-spec/test-spec-revision-resolver.js.map +1 -0
  138. package/dist-server/service/test-spec/test-spec-revision-service.d.ts +138 -0
  139. package/dist-server/service/test-spec/test-spec-revision-service.js +538 -0
  140. package/dist-server/service/test-spec/test-spec-revision-service.js.map +1 -0
  141. package/dist-server/service/test-spec/test-spec-revision.d.ts +84 -0
  142. package/dist-server/service/test-spec/test-spec-revision.js +334 -0
  143. package/dist-server/service/test-spec/test-spec-revision.js.map +1 -0
  144. package/dist-server/service/test-spec/test-specification.d.ts +6 -0
  145. package/dist-server/service/test-spec/test-specification.js +15 -2
  146. package/dist-server/service/test-spec/test-specification.js.map +1 -1
  147. package/dist-server/tsconfig.tsbuildinfo +1 -1
  148. package/package.json +10 -6
  149. package/translations/en.json +148 -0
  150. package/translations/ko.json +148 -0
@@ -0,0 +1,133 @@
1
+ /** View calculations only. IDs are comparison keys, never display labels. */
2
+ /** Flatten only for comparison labels. The stored structure and sibling order remain intact. */
3
+ export function materialDifferenceValues(value) {
4
+ const entries = new Map();
5
+ for (const field of ['description', 'materialClassIds', 'testSpecificationIds'])
6
+ entries.set(field, value?.[field] ?? (field === 'description' ? '' : []));
7
+ const walk = (rows, parent) => rows.forEach((row, index) => {
8
+ const key = `${parent}/${row.id}${row.uom ? ' (' + row.uom + ')' : ''}`;
9
+ entries.set(key + '/position', index + 1);
10
+ for (const field of ['description', 'value', 'dataType', 'uom', 'classPropertyId', 'source'])
11
+ entries.set(key + '/' + field, row[field] ?? '');
12
+ walk(row.children ?? [], key);
13
+ });
14
+ walk(value?.properties ?? [], 'properties');
15
+ return entries;
16
+ }
17
+ /** A detail address is scoped to the already-authorized approval, not a general revision lookup. */
18
+ export function revisionDetailAddress(input, side, href) {
19
+ const row = input?.[side];
20
+ if (!row?.detail?.revisionId)
21
+ throw new Error('Revision detail is not available');
22
+ const url = new URL(href);
23
+ const recipe = !!input.revision?.recipeId;
24
+ url.searchParams.set('f', (input.revision?.arrangementId ? 'workShifts:' : recipe ? 'recipes:' : input.revision?.materialId ? 'materialDefinitions:' : 'testSpecifications:') + (input.revision.arrangementId ?? input.revision.recipeId ?? input.revision.materialId ?? input.revision.specId));
25
+ url.searchParams.set('revision', row.detail.revisionId);
26
+ return url.href;
27
+ }
28
+ export function revisionSideAt(input, href) {
29
+ const url = new URL(href);
30
+ if (!url.searchParams.has('f') && !url.searchParams.has('revision'))
31
+ return undefined;
32
+ for (const side of ['before', 'after']) {
33
+ if (!input?.[side]?.detail?.revisionId)
34
+ continue;
35
+ const expected = new URL(revisionDetailAddress(input, side, href));
36
+ if (expected.searchParams.get('f') === url.searchParams.get('f') &&
37
+ expected.searchParams.get('revision') === url.searchParams.get('revision'))
38
+ return side;
39
+ }
40
+ throw new Error('The requested revision is not part of this approval');
41
+ }
42
+ export function revisionDifferences(axis, before, after) {
43
+ const out = [];
44
+ if (axis === 'workShift') {
45
+ for (const field of ['description', 'timezone']) {
46
+ if ((before?.[field] ?? '') !== (after?.[field] ?? ''))
47
+ out.push({ section: 'general', label: '', field, before: before?.[field], after: after?.[field], kind: before ? 'changed' : 'added' });
48
+ }
49
+ const oldRows = before?.shifts ?? [], newRows = after?.shifts ?? [];
50
+ for (const name of new Set([...oldRows, ...newRows].map(row => row.name))) {
51
+ const a = oldRows.find(row => row.name === name), b = newRows.find(row => row.name === name);
52
+ for (const field of ['description', 'fromDate', 'fromTime', 'toDate', 'toTime', 'daysOfWeek']) {
53
+ const display = (r) => r ? field === 'daysOfWeek' ? r[field] || '0,1,2,3,4,5,6' : r[field] : undefined;
54
+ if (display(a) !== display(b))
55
+ out.push({ section: 'shifts', label: String(name), field,
56
+ before: display(a), after: display(b), kind: !a ? 'added' : !b ? 'removed' : 'changed' });
57
+ }
58
+ }
59
+ return out;
60
+ }
61
+ if (axis === 'materialDefinition') {
62
+ const a = materialDifferenceValues(before), b = materialDifferenceValues(after);
63
+ for (const key of new Set([...a.keys(), ...b.keys()])) {
64
+ if (JSON.stringify(a.get(key)) === JSON.stringify(b.get(key)))
65
+ continue;
66
+ const parts = key.split('/');
67
+ out.push({ section: parts.length > 1 ? 'properties' : 'general', label: parts.slice(1, -1).join(' / '),
68
+ field: parts[parts.length - 1], before: Array.isArray(a.get(key)) ? a.get(key).join(', ') : a.get(key),
69
+ after: Array.isArray(b.get(key)) ? b.get(key).join(', ') : b.get(key), kind: !a.has(key) ? 'added' : !b.has(key) ? 'removed' : 'changed' });
70
+ }
71
+ return out;
72
+ }
73
+ for (const field of axis === 'recipeDefinition'
74
+ ? ['description', 'materialDefinitionName', 'route']
75
+ : ['description', 'version']) {
76
+ if ((before?.[field] ?? '') !== (after?.[field] ?? ''))
77
+ out.push({
78
+ section: 'general',
79
+ label: '',
80
+ field,
81
+ before: before?.[field],
82
+ after: after?.[field],
83
+ kind: !before ? 'added' : 'changed'
84
+ });
85
+ }
86
+ for (const section of axis === 'recipeDefinition' ? ['inputs', 'outputs'] : ['criteria']) {
87
+ const oldRows = before?.[section] ?? [], newRows = after?.[section] ?? [];
88
+ const key = (row) => (axis === 'recipeDefinition' ? row.lineKey : row.id);
89
+ const keys = [...new Set([...oldRows, ...newRows].map(key))];
90
+ for (const id of keys) {
91
+ const a = oldRows.find((row) => key(row) === id), b = newRows.find((row) => key(row) === id);
92
+ const fields = section === 'criteria'
93
+ ? ['id', 'description', 'evaluatedPropertyId', 'minimum', 'maximum', 'uom', 'expression']
94
+ : section === 'inputs'
95
+ ? ['material', 'qty', 'operation']
96
+ : ['material', 'qty'];
97
+ if (a && b && oldRows.indexOf(a) !== newRows.indexOf(b))
98
+ out.push({
99
+ section,
100
+ label: b.material || b.description || b.id || '',
101
+ field: 'position',
102
+ before: oldRows.indexOf(a) + 1,
103
+ after: newRows.indexOf(b) + 1,
104
+ kind: 'changed'
105
+ });
106
+ const value = (row, field) => section === 'criteria' && ['minimum', 'maximum', 'uom'].includes(field) ? row?.limit?.[field] : row?.[field];
107
+ for (const field of fields)
108
+ if ((value(a, field) ?? '') !== (value(b, field) ?? ''))
109
+ out.push({
110
+ section,
111
+ label: b?.material ?? a?.material ?? b?.description ?? a?.description ?? b?.id ?? a?.id ?? '',
112
+ field,
113
+ before: value(a, field),
114
+ after: value(b, field),
115
+ kind: !a ? 'added' : !b ? 'removed' : 'changed'
116
+ });
117
+ }
118
+ }
119
+ return out;
120
+ }
121
+ export function localDateTime(iso) {
122
+ const date = new Date(iso);
123
+ if (!Number.isFinite(date.getTime()))
124
+ return '';
125
+ return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 16);
126
+ }
127
+ export function isoFromLocal(value) {
128
+ const date = new Date(value);
129
+ if (!value || !Number.isFinite(date.getTime()) || localDateTime(date.toISOString()) !== value.slice(0, 16))
130
+ throw new Error('Invalid local date/time');
131
+ return date.toISOString();
132
+ }
133
+ //# sourceMappingURL=revision-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-view.js","sourceRoot":"","sources":["../../../client/pages/master/revision-view.ts"],"names":[],"mappings":"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","sourcesContent":["/** View calculations only. IDs are comparison keys, never display labels. */\n/** Flatten only for comparison labels. The stored structure and sibling order remain intact. */\nexport function materialDifferenceValues(value: any): Map<string, unknown> {\n const entries = new Map<string, unknown>()\n for (const field of ['description', 'materialClassIds', 'testSpecificationIds']) entries.set(field, value?.[field] ?? (field === 'description' ? '' : []))\n const walk = (rows: any[], parent: string) => rows.forEach((row, index) => {\n const key = `${parent}/${row.id}${row.uom ? ' (' + row.uom + ')' : ''}`\n entries.set(key + '/position', index + 1)\n for (const field of ['description', 'value', 'dataType', 'uom', 'classPropertyId', 'source']) entries.set(key + '/' + field, row[field] ?? '')\n walk(row.children ?? [], key)\n })\n walk(value?.properties ?? [], 'properties')\n return entries\n}\nexport type RevisionAxis = 'recipeDefinition' | 'testSpecification' | 'materialDefinition' | 'workShift'\nexport type RevisionSide = 'before' | 'after'\n\n/** A detail address is scoped to the already-authorized approval, not a general revision lookup. */\nexport function revisionDetailAddress(input: any, side: RevisionSide, href: string): string {\n const row = input?.[side]\n if (!row?.detail?.revisionId) throw new Error('Revision detail is not available')\n const url = new URL(href)\n const recipe = !!input.revision?.recipeId\n url.searchParams.set(\n 'f',\n (input.revision?.arrangementId ? 'workShifts:' : recipe ? 'recipes:' : input.revision?.materialId ? 'materialDefinitions:' : 'testSpecifications:') + (input.revision.arrangementId ?? input.revision.recipeId ?? input.revision.materialId ?? input.revision.specId)\n )\n url.searchParams.set('revision', row.detail.revisionId)\n return url.href\n}\nexport function revisionSideAt(input: any, href: string): RevisionSide | undefined {\n const url = new URL(href)\n if (!url.searchParams.has('f') && !url.searchParams.has('revision')) return undefined\n for (const side of ['before', 'after'] as const) {\n if (!input?.[side]?.detail?.revisionId) continue\n const expected = new URL(revisionDetailAddress(input, side, href))\n if (\n expected.searchParams.get('f') === url.searchParams.get('f') &&\n expected.searchParams.get('revision') === url.searchParams.get('revision')\n )\n return side\n }\n throw new Error('The requested revision is not part of this approval')\n}\nexport interface Difference {\n section: string\n label: string\n field: string\n before: unknown\n after: unknown\n kind: 'added' | 'removed' | 'changed'\n}\nexport function revisionDifferences(axis: RevisionAxis, before: any, after: any): Difference[] {\n const out: Difference[] = []\n if (axis === 'workShift') {\n for (const field of ['description', 'timezone']) {\n if ((before?.[field] ?? '') !== (after?.[field] ?? '')) out.push({ section: 'general', label: '', field, before: before?.[field], after: after?.[field], kind: before ? 'changed' : 'added' })\n }\n const oldRows = before?.shifts ?? [], newRows = after?.shifts ?? []\n for (const name of new Set([...oldRows, ...newRows].map(row => row.name))) {\n const a = oldRows.find(row => row.name === name), b = newRows.find(row => row.name === name)\n for (const field of ['description','fromDate','fromTime','toDate','toTime','daysOfWeek']) {\n const display = (r: any) => r ? field === 'daysOfWeek' ? r[field] || '0,1,2,3,4,5,6' : r[field] : undefined\n if (display(a) !== display(b)) out.push({ section: 'shifts', label: String(name), field,\n before: display(a), after: display(b), kind: !a ? 'added' : !b ? 'removed' : 'changed' })\n }\n }\n return out\n }\n if (axis === 'materialDefinition') {\n const a = materialDifferenceValues(before), b = materialDifferenceValues(after)\n for (const key of new Set([...a.keys(), ...b.keys()])) {\n if (JSON.stringify(a.get(key)) === JSON.stringify(b.get(key))) continue\n const parts = key.split('/')\n out.push({ section: parts.length > 1 ? 'properties' : 'general', label: parts.slice(1, -1).join(' / '),\n field: parts[parts.length - 1], before: Array.isArray(a.get(key)) ? (a.get(key) as string[]).join(', ') : a.get(key),\n after: Array.isArray(b.get(key)) ? (b.get(key) as string[]).join(', ') : b.get(key), kind: !a.has(key) ? 'added' : !b.has(key) ? 'removed' : 'changed' })\n }\n return out\n }\n for (const field of axis === 'recipeDefinition'\n ? ['description', 'materialDefinitionName', 'route']\n : ['description', 'version']) {\n if ((before?.[field] ?? '') !== (after?.[field] ?? ''))\n out.push({\n section: 'general',\n label: '',\n field,\n before: before?.[field],\n after: after?.[field],\n kind: !before ? 'added' : 'changed'\n })\n }\n for (const section of axis === 'recipeDefinition' ? ['inputs', 'outputs'] : ['criteria']) {\n const oldRows = before?.[section] ?? [],\n newRows = after?.[section] ?? []\n const key = (row: any) => (axis === 'recipeDefinition' ? row.lineKey : row.id)\n const keys = [...new Set([...oldRows, ...newRows].map(key))]\n for (const id of keys) {\n const a = oldRows.find((row: any) => key(row) === id),\n b = newRows.find((row: any) => key(row) === id)\n const fields =\n section === 'criteria'\n ? ['id', 'description', 'evaluatedPropertyId', 'minimum', 'maximum', 'uom', 'expression']\n : section === 'inputs'\n ? ['material', 'qty', 'operation']\n : ['material', 'qty']\n if (a && b && oldRows.indexOf(a) !== newRows.indexOf(b))\n out.push({\n section,\n label: b.material || b.description || b.id || '',\n field: 'position',\n before: oldRows.indexOf(a) + 1,\n after: newRows.indexOf(b) + 1,\n kind: 'changed'\n })\n const value = (row: any, field: string) =>\n section === 'criteria' && ['minimum', 'maximum', 'uom'].includes(field) ? row?.limit?.[field] : row?.[field]\n for (const field of fields)\n if ((value(a, field) ?? '') !== (value(b, field) ?? ''))\n out.push({\n section,\n label: b?.material ?? a?.material ?? b?.description ?? a?.description ?? b?.id ?? a?.id ?? '',\n field,\n before: value(a, field),\n after: value(b, field),\n kind: !a ? 'added' : !b ? 'removed' : 'changed'\n })\n }\n }\n return out\n}\nexport function localDateTime(iso: string): string {\n const date = new Date(iso)\n if (!Number.isFinite(date.getTime())) return ''\n return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 16)\n}\nexport function isoFromLocal(value: string): string {\n const date = new Date(value)\n if (!value || !Number.isFinite(date.getTime()) || localDateTime(date.toISOString()) !== value.slice(0, 16))\n throw new Error('Invalid local date/time')\n return date.toISOString()\n}\n"]}
@@ -0,0 +1,50 @@
1
+ import '@operato/data-grist/ox-grist.js';
2
+ import { MasterPageBase, MasterSpec } from './master-page-base.js';
3
+ import { RevisionAxis } from './revision-view.js';
4
+ /** Shared workflow, not shared domain payload. Both consumers keep their existing page/URL identities. */
5
+ export declare abstract class RevisionWorkspace extends MasterPageBase {
6
+ protected abstract axis: RevisionAxis;
7
+ static styles: import("lit").CSSResult[];
8
+ private overview;
9
+ private draft;
10
+ private newName;
11
+ private busy;
12
+ private dirty;
13
+ private failure;
14
+ private message;
15
+ private approvalRequired;
16
+ private statuses;
17
+ private serial;
18
+ private get recipe();
19
+ private get material();
20
+ private get names();
21
+ protected get spec(): MasterSpec;
22
+ protected get pathSegmentNarrowsList(): boolean;
23
+ get context(): any;
24
+ updated(changes: any): void;
25
+ protected configOf(): any;
26
+ pageInitialized(): Promise<void>;
27
+ pageUpdated(changes: any, after: any, before: any): Promise<void>;
28
+ private openResource;
29
+ private assert;
30
+ private run;
31
+ private canLeave;
32
+ private blank;
33
+ private policy;
34
+ private startNew;
35
+ private pick;
36
+ private load;
37
+ private get currentSegment();
38
+ private get current();
39
+ private get comparisonBase();
40
+ private stateOf;
41
+ private openRevision;
42
+ private change;
43
+ private line;
44
+ protected save(): Promise<void>;
45
+ private persist;
46
+ private submit;
47
+ private content;
48
+ private status;
49
+ render(): import("lit-html").TemplateResult<1>;
50
+ }