toga-ai 1.0.408 → 1.0.409
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.
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
| Doc | Summary | Files |
|
|
4
4
|
|-----|---------|-------|
|
|
5
5
|
| [Database Changes (dbchanges2) Repository Architecture](architecture.md) | `dbchanges2` is the **schema-migration / SQL change-set repository** for the entire 2.0 platform. | Core/, Client/, Client_<Tenant>/, Logs/, Logs_Client/, _modules/ |
|
|
6
|
-
| [Surface Layer Schema (UI presentation/config tables)](features/surface-layer-schema.md) | The persistent schema for the platform-wide **Surface** UI presentation/configuration layer (see the `_underscore` [surface-resolver](../../_underscore/features | dbchanges2/Client/2026-06-25a - SurfaceClientTables.sql, dbchanges2/Client_Compass/2026-06-25d - SalesOrderSurfaceClientSeed.sql, _underscore/Model/Client/ThemeToken.php, toga25-supply/src/themeConfig.json, dbchanges2/Core/2026-06-25a - SurfaceCoreTables.sql, dbchanges2/Core/2026-06-25b - SurfaceRecordsAndFields.sql, dbchanges2/Core/2026-06-25c - SalesOrderLoginSurfaceSeed.sql, dbchanges2/Core/2026-06-29a - ItemsSurfaceSeed.sql, dbchanges2/Core/2026-06-29b - SurfaceMetaPublicReadAcl.sql, dbchanges2/Client/2026-06-29c - SurfaceRecordScriptAcl.sql, dbchanges2/Core/2026-06-29c - SurfaceDebugPhpMethodFix.sql, dbchanges2/Core/2026-06-29d - VendorItemsSurfaceSeed.sql, dbchanges2/Core/2026-06-29e - InventorySurfaceSeed.sql, dbchanges2/Core/2026-06-30a - SurfaceMetaGroupAndSalesOrderSections.sql, dbchanges2/Client/2026-06-30a - SurfaceMetaGroupAcl.sql, dbchanges2/Client_Compass/2026-06-30a - SalesOrderDisplaySectionManagerOverrides.sql, dbchanges2/Client_CompassCanada/2026-06-30a - SalesOrderSurfaceManagerOverrides.sql, dbchanges2/Client_Quad/2026-06-30a - SalesOrderSurfaceClientOverrides.sql, dbchanges2/Client/2026-06-25a - SurfaceClientTables.sql, dbchanges2/Client/2026-06-25b - SurfaceClientSeed.sql, dbchanges2/Client/2026-06-25c - SurfaceClientAcl.sql, dbchanges2/Client/2026-06-03- BLANK_CLIENT_DATABASE.sql, dbchanges2/Core/2026-07-17h - Update - ClearApprovalsFilterButtonConfig.sql, dbchanges2/Client_Compass/2026-07-17a - SalesOrderApprovalActionsOverride.sql, dbchanges2/Client_Compass/2026-07-17b - SalesOrderApprovalsFilterButtonOverride.sql, dbchanges2/Client_CompassCanada/2026-07-17a - SalesOrderApprovalActionsOverride.sql, dbchanges2/Client_CompassCanada/2026-07-17b - SalesOrderApprovalsFilterButtonOverride.sql, dbchanges2/Client_Quad/2026-07-17a - SalesOrderApprovalActionsOverride.sql, dbchanges2/Client_Quad/2026-07-17b - SalesOrderApprovalsFilterButtonOverride.sql, dbchanges2/Core/2026-07-20a - Update - HideAdminNotesSectionByDefault.sql, dbchanges2/Core/2026-07-20b - Update - NotesSectionFieldElements.sql, dbchanges2/Client_Compass/2026-07-20a - AdminNotesSectionVisibilityOverride.sql, dbchanges2/Client_Compass/2026-07-20b - NotesSectionFieldsOverride.sql, dbchanges2/Client_CompassCanada/2026-07-20a - AdminNotesSectionVisibilityOverride.sql, dbchanges2/Client_CompassCanada/2026-07-20b - NotesSectionFieldsOverride.sql, dbchanges2/Client_Quad/2026-07-20a - NotesSectionFieldsOverride.sql, dbchanges2/Core/2026-07-20c - Update - VendorItemsToggleSurfaceSeed.sql, dbchanges2/Client_Compass/2026-07-20c - ItemRecordEditButtonEnable.sql, dbchanges2/Client_Compass/2026-07-20d - ItemRecordVendorItemsEnable.sql, dbchanges2/Client_CompassCanada/2026-07-20c - ItemRecordEditButtonEnable.sql, dbchanges2/Client_CompassCanada/2026-07-20d - ItemRecordVendorItemsEnable.sql, dbchanges2/Core/2026-07-20e - RestoreApproveDenyRowActions.sql, dbchanges2/Client_Compass/2026-07-20e - RowActionsApprovalWorkflowAdminEnable.sql, dbchanges2/Client_CompassCanada/2026-07-20e - RowActionsApprovalWorkflowAdminEnable.sql, dbchanges2/Core/2026-07-17 - README - RUN ORDER.md, dbchanges2/Client_Compass/2026-07-21a - SalesOrderApproveEnabledRuleOverride.sql, dbchanges2/Client_Compass/2026-07-21b - SalesOrderApprovalsGateEnable.sql, dbchanges2/Client_CompassCanada/2026-07-21a - SalesOrderApproveEnabledRuleOverride.sql, dbchanges2/Client_CompassCanada/2026-07-21b - SalesOrderApprovalsGateEnable.sql, dbchanges2/Client_Quad/2026-07-21a - SalesOrderApproveEnabledRuleOverride.sql, dbchanges2/Client_Quad/2026-07-21b - SalesOrderApproveDisabledTooltipTranslation.sql |
|
|
6
|
+
| [Surface Layer Schema (UI presentation/config tables)](features/surface-layer-schema.md) | The persistent schema for the platform-wide **Surface** UI presentation/configuration layer (see the `_underscore` [surface-resolver](../../_underscore/features | dbchanges2/Client/2026-06-25a - SurfaceClientTables.sql, dbchanges2/Client_Compass/2026-06-25d - SalesOrderSurfaceClientSeed.sql, _underscore/Model/Client/ThemeToken.php, toga25-supply/src/themeConfig.json, dbchanges2/Core/2026-06-25a - SurfaceCoreTables.sql, dbchanges2/Core/2026-06-25b - SurfaceRecordsAndFields.sql, dbchanges2/Core/2026-06-25c - SalesOrderLoginSurfaceSeed.sql, dbchanges2/Core/2026-06-29a - ItemsSurfaceSeed.sql, dbchanges2/Core/2026-06-29b - SurfaceMetaPublicReadAcl.sql, dbchanges2/Client/2026-06-29c - SurfaceRecordScriptAcl.sql, dbchanges2/Core/2026-06-29c - SurfaceDebugPhpMethodFix.sql, dbchanges2/Core/2026-06-29d - VendorItemsSurfaceSeed.sql, dbchanges2/Core/2026-06-29e - InventorySurfaceSeed.sql, dbchanges2/Core/2026-06-30a - SurfaceMetaGroupAndSalesOrderSections.sql, dbchanges2/Client/2026-06-30a - SurfaceMetaGroupAcl.sql, dbchanges2/Client_Compass/2026-06-30a - SalesOrderDisplaySectionManagerOverrides.sql, dbchanges2/Client_CompassCanada/2026-06-30a - SalesOrderSurfaceManagerOverrides.sql, dbchanges2/Client_Quad/2026-06-30a - SalesOrderSurfaceClientOverrides.sql, dbchanges2/Client/2026-06-25a - SurfaceClientTables.sql, dbchanges2/Client/2026-06-25b - SurfaceClientSeed.sql, dbchanges2/Client/2026-06-25c - SurfaceClientAcl.sql, dbchanges2/Client/2026-06-03- BLANK_CLIENT_DATABASE.sql, dbchanges2/Core/2026-07-17h - Update - ClearApprovalsFilterButtonConfig.sql, dbchanges2/Client_Compass/2026-07-17a - SalesOrderApprovalActionsOverride.sql, dbchanges2/Client_Compass/2026-07-17b - SalesOrderApprovalsFilterButtonOverride.sql, dbchanges2/Client_CompassCanada/2026-07-17a - SalesOrderApprovalActionsOverride.sql, dbchanges2/Client_CompassCanada/2026-07-17b - SalesOrderApprovalsFilterButtonOverride.sql, dbchanges2/Client_Quad/2026-07-17a - SalesOrderApprovalActionsOverride.sql, dbchanges2/Client_Quad/2026-07-17b - SalesOrderApprovalsFilterButtonOverride.sql, dbchanges2/Core/2026-07-20a - Update - HideAdminNotesSectionByDefault.sql, dbchanges2/Core/2026-07-20b - Update - NotesSectionFieldElements.sql, dbchanges2/Client_Compass/2026-07-20a - AdminNotesSectionVisibilityOverride.sql, dbchanges2/Client_Compass/2026-07-20b - NotesSectionFieldsOverride.sql, dbchanges2/Client_CompassCanada/2026-07-20a - AdminNotesSectionVisibilityOverride.sql, dbchanges2/Client_CompassCanada/2026-07-20b - NotesSectionFieldsOverride.sql, dbchanges2/Client_Quad/2026-07-20a - NotesSectionFieldsOverride.sql, dbchanges2/Core/2026-07-20c - Update - VendorItemsToggleSurfaceSeed.sql, dbchanges2/Client_Compass/2026-07-20c - ItemRecordEditButtonEnable.sql, dbchanges2/Client_Compass/2026-07-20d - ItemRecordVendorItemsEnable.sql, dbchanges2/Client_CompassCanada/2026-07-20c - ItemRecordEditButtonEnable.sql, dbchanges2/Client_CompassCanada/2026-07-20d - ItemRecordVendorItemsEnable.sql, dbchanges2/Core/2026-07-20e - RestoreApproveDenyRowActions.sql, dbchanges2/Client_Compass/2026-07-20e - RowActionsApprovalWorkflowAdminEnable.sql, dbchanges2/Client_CompassCanada/2026-07-20e - RowActionsApprovalWorkflowAdminEnable.sql, dbchanges2/Core/2026-07-17 - README - RUN ORDER.md, dbchanges2/Client_Compass/2026-07-21a - SalesOrderApproveEnabledRuleOverride.sql, dbchanges2/Client_Compass/2026-07-21b - SalesOrderApprovalsGateEnable.sql, dbchanges2/Client_CompassCanada/2026-07-21a - SalesOrderApproveEnabledRuleOverride.sql, dbchanges2/Client_CompassCanada/2026-07-21b - SalesOrderApprovalsGateEnable.sql, dbchanges2/Client_Quad/2026-07-21a - SalesOrderApproveEnabledRuleOverride.sql, dbchanges2/Client_Quad/2026-07-21b - SalesOrderApproveDisabledTooltipTranslation.sql, dbchanges2/Core/2026-07-21a - SalesOrderDecisionSummarySurfaceSeed.sql, dbchanges2/Core/2026-07-21b - SalesOrderDecisionActionSurfaceSeed.sql |
|
|
7
7
|
| [2.0 New-Client Onboarding (manual process)](workflows/client-onboarding.md) | > **A local browser wizard now automates this.** Steps 2–9 below (create DBs, generate Core/API > inserts, append to `Clients_Db.txt`) — plus the dbchanges2 bla | Client/, Client_<Tenant>/, Core/, Logs_Client/ |
|
|
@@ -60,6 +60,8 @@ files:
|
|
|
60
60
|
- dbchanges2/Client_CompassCanada/2026-07-21b - SalesOrderApprovalsGateEnable.sql
|
|
61
61
|
- dbchanges2/Client_Quad/2026-07-21a - SalesOrderApproveEnabledRuleOverride.sql
|
|
62
62
|
- dbchanges2/Client_Quad/2026-07-21b - SalesOrderApproveDisabledTooltipTranslation.sql
|
|
63
|
+
- dbchanges2/Core/2026-07-21a - SalesOrderDecisionSummarySurfaceSeed.sql
|
|
64
|
+
- dbchanges2/Core/2026-07-21b - SalesOrderDecisionActionSurfaceSeed.sql
|
|
63
65
|
related:
|
|
64
66
|
- ../../_underscore/features/surface-resolver.md
|
|
65
67
|
---
|
|
@@ -278,6 +280,35 @@ Both clients' `c`/`d` overrides and the Core seed were added to `Core/2026-07-17
|
|
|
278
280
|
ORDER.md`. Verified working in the UI for both clients. (Boolean toggle/badge labels in this modal
|
|
279
281
|
resolve through the resolver's new `trueLabel`/`falseLabel` emission — see the resolver doc.)
|
|
280
282
|
|
|
283
|
+
## SalesOrder decision-modal surfaces (approve + deny) — shared summary + per-action chrome
|
|
284
|
+
|
|
285
|
+
The approve/deny decision modal's display config was migrated off the per-client
|
|
286
|
+
`approvalActionFields.json` into metadata-driven surfaces (Core seed → resolved per role → overlaid
|
|
287
|
+
FE-side; see [surface-frontend](../../toga25-supply/features/surface-frontend.md)). The seed split is
|
|
288
|
+
**one shared summary surface + two per-action chrome surfaces** (the 8 order-summary rows are identical
|
|
289
|
+
across approve/deny; only the chrome diverges):
|
|
290
|
+
|
|
291
|
+
- `Core/2026-07-21a - SalesOrderDecisionSummarySurfaceSeed.sql` — surface `sales-order-decision-summary`
|
|
292
|
+
(type SECTION, `config.cardType='decisionSummary'`), **SHARED** by both modals. 8 read-only summary
|
|
293
|
+
`FIELD` elements (Assigned Manager / Order for / Submitted by / Order # / Order Date / Total / Cost
|
|
294
|
+
Center / Reason for Request) with **`recordFieldId` NULL + `config.valueKey`** binding; Total is
|
|
295
|
+
`CURRENCY`; all `isVisible=1` (a display field is the Core neutral default — visible). Messages keyed
|
|
296
|
+
`salesOrder.decision.field.*`. (Renamed from an earlier approval-only slug to
|
|
297
|
+
`sales-order-decision-summary` to reflect the shared use.)
|
|
298
|
+
- `Core/2026-07-21b - SalesOrderDecisionActionSurfaceSeed.sql` — TWO surfaces
|
|
299
|
+
`sales-order-approve-action` and `sales-order-deny-action` (`config.cardType='decisionAction'`,
|
|
300
|
+
`action='approve'`/`'deny'`). 7 role-tagged elements each (`config.role`: title / guardrail /
|
|
301
|
+
reasonInput / confirmButton / cancelButton / successToast / errorToast). **Approve reason OPTIONAL**
|
|
302
|
+
(charLimit 255, check icon, mint-700); **deny reason REQUIRED** (`showRequiredIndicator`, xmark icon).
|
|
303
|
+
Messages keyed `salesOrder.approve.*` / `salesOrder.deny.*` plus a shared `salesOrder.decision.cancel`.
|
|
304
|
+
|
|
305
|
+
Both seeds are **ADDITIVE, id-agnostic, and re-runnable**: `NOT EXISTS`-guarded per surface slug +
|
|
306
|
+
`config.role`/`valueKey`; Messages guarded by `messageKey`; the surfaces inherit `appId`/`recordId`
|
|
307
|
+
from the existing `order-details` sibling surface **by slug** (never a hardcoded id). Same authoring
|
|
308
|
+
pattern as the `2026-07-17g` seed. These are **Core→Core only** (prod-safe — no cross-DB Client
|
|
309
|
+
subselect). Per-client divergence (via `SurfaceOverride`) for Compass / Compass Canada / Quad is **not
|
|
310
|
+
yet seeded** — this session is the shared Core default + FE wiring only.
|
|
311
|
+
|
|
281
312
|
## ThemeTokens — per-tenant, physically isolated in each client DB
|
|
282
313
|
|
|
283
314
|
`ThemeTokens` lives **inside each tenant's own database** (`Client_Compass.ThemeTokens`,
|
|
@@ -442,6 +473,16 @@ rule resumes.
|
|
|
442
473
|
override is added). **Open follow-up.**
|
|
443
474
|
|
|
444
475
|
## Change history
|
|
476
|
+
- 2026-07-21 — Seeded the **SalesOrder decision-modal (approve + deny) surfaces**, migrating the
|
|
477
|
+
per-client `approvalActionFields.json` display config to metadata. `Core/2026-07-21a` = one SHARED
|
|
478
|
+
`sales-order-decision-summary` SECTION surface (cardType `decisionSummary`, 8 read-only FIELD summary
|
|
479
|
+
rows, `recordFieldId` NULL + `config.valueKey`, Total CURRENCY, all visible); `Core/2026-07-21b` = two
|
|
480
|
+
per-action chrome surfaces `sales-order-approve-action`/`sales-order-deny-action` (cardType
|
|
481
|
+
`decisionAction`, 7 role-tagged elements by `config.role`, approve reason optional / deny reason
|
|
482
|
+
required). Both additive, id-agnostic, re-runnable (NOT EXISTS by slug + role/valueKey; Messages by
|
|
483
|
+
messageKey; appId/recordId inherited from the `order-details` sibling by slug), Core→Core only
|
|
484
|
+
(prod-safe). Per-client SurfaceOverride divergence not yet seeded — shared Core default + FE wiring
|
|
485
|
+
only. (apeterson)
|
|
445
486
|
- 2026-07-21 — Added the sales-order **Approve enable-gate** per-client overrides (`Client_*/2026-07-21a`):
|
|
446
487
|
Compass/CC ADMIN `ENABLED_RULE` = `(pendingInitialApproval AND stepTwoAssigned) OR pendingApproval`
|
|
447
488
|
on surface 8 el 17 + surface 3 el 29 (rule JSON in `c_longValue`; Compass UPDATEs its existing
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
| [Force Logout on Deployment (useDeploymentGuard)](features/force-logout-on-deployment.md) | On large deployments the backend bumps the Core parameter `META_LAST_REFRESH_DATETIME`. | toga25-supply/src/hooks/useDeploymentGuard.tsx, toga25-supply/src/App.tsx |
|
|
11
11
|
| [Meta-Driven Page & Table Setup](features/meta-driven-table-data.md) | A page in this app is **meta-driven end to end**: the page view model fetches *page meta* (labels, sections, ACL) and *table meta* (the columns/fields + table s | toga25-supply/src/pages/SalesOrders/viewModel/useSalesOrdersPageViewModel.tsx, toga25-supply/src/pages/SalesOrders/hooks/useSalesOrdersTableState.ts, toga25-supply/src/hooks/useTablePageMeta.ts, toga-blox-npm/dist/hooks/useFetchPageMeta.d.ts, toga-blox-npm/dist/hooks/useFetchTablePageMeta.d.ts, toga-blox-npm/dist/hooks/useAssignTableFieldLabels.d.ts, toga-blox-npm/dist/components/Table/hooks/useTableData.d.ts |
|
|
12
12
|
| [Record Modals & Nested Tables](features/record-modals-and-nested-tables.md) | The repo's family of modal + nested-table patterns layered over toga-blox `TableRecordModal` and `PrimaryTable*Layout`. | toga25-supply/src/layout/ItemRecordModalLayout/, toga25-supply/src/layout/SalesOrderRecordModalLayout/, toga25-supply/src/layout/SalesOrderItemsTableLayout/, toga25-supply/src/layout/ItemFulfillmentModal/, toga25-supply/src/layout/GenericNestedTables/GenericNestedTables.tsx, toga25-supply/src/layout/GenericNestedTables/GenericTableLayout.tsx, toga25-supply/src/pages/Inventory/viewModel/useInventoryPageViewModel.tsx, toga25-supply/src/pages/Inventory/viewModel/FIELDS/DEFAULT/inventoryGroupings.json, toga25-supply/src/hooks/useTableCellInteractions.ts, toga25-supply/src/hooks/useServerTableUrlState.ts |
|
|
13
|
-
| [Surface Frontend (DB-driven UI consumption, src/surface/)](features/surface-frontend.md) | The frontend consumer of the platform-wide Surface layer — DB-driven UI config fetched from `GET /v2/surfaces/meta?slug=<slug>` instead of statically-imported J | toga25-supply/src/surface/useFetchSurfaceMeta.ts, toga25-supply/src/pages/SalesOrders/helpers/surfaceBundleToTenantFields.ts, toga25-supply/src/pages/SalesOrders/helpers/buildPatchedTenantFields.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/viewModel/useSalesOrderRecordModalLayoutModel.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/SalesOrderView.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/layoutComponents/SalesOrderSummaryGrid.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/getDetailSections.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/sections/SalesOrderNotesSection.tsx, toga25-supply/src/pages/SalesOrders/helpers/cleanOrder.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/index.ts, toga25-supply/src/surface/evaluateSurfaceRule.ts, toga25-supply/src/surface/resolveElementState.ts, toga25-supply/src/pages/SalesOrders/helpers/evaluateEnableRule.ts, toga25-supply/src/pages/SalesOrders/hooks/useSalesOrderRowRecordState.ts, toga25-supply/src/surface/actionRegistry.ts, toga25-supply/src/surface/componentRegistry.tsx, toga25-supply/src/surface/SurfaceActionBar.tsx, toga25-supply/src/surface/SurfaceSection.tsx, toga25-supply/src/surface/resolve.ts, toga25-supply/src/surface/types.ts, toga25-supply/src/surface/index.ts, toga25-supply/src/pages/Login/LoginPage.tsx, toga25-supply/src/pages/SalesOrders/SalesOrders.tsx, toga25-supply/src/pages/SalesOrders/view/SurfaceRowActions.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/sections/SalesOrderTopBar.tsx, toga25-supply/src/pages/Items/ItemsPage.tsx, toga25-supply/src/pages/Items/viewModel/useItemsPageViewModel.tsx, toga25-supply/src/pages/VendorItems/VendorItemsPage.tsx, toga25-supply/src/pages/VendorItems/viewModel/useVendorItemsPageViewModel.tsx, toga25-supply/src/pages/Inventory/Inventory.tsx, toga25-supply/src/pages/Inventory/viewModel/useInventoryPageViewModel.tsx, toga25-supply/src/pages/Inventory/viewModel/FIELDS/index.ts, toga25-supply/src/fieldsConfig/index.ts, toga25-supply/src/layout/ItemRecordModalLayout/helpers/surfaceBundleToItemFields.ts, toga25-supply/src/layout/ItemRecordModalLayout/helpers/index.ts, toga25-supply/src/layout/ItemRecordModalLayout/viewModel/useItemRecordModalViewModel.tsx, toga25-supply/src/layout/ItemRecordModalLayout/ItemRecordModalLayout.tsx, toga25-supply/src/layout/ItemRecordModalLayout/components/ItemRecordView.tsx, toga25-supply/src/surface/useStatusColors.ts, toga25-supply/src/surface/SurfaceHeader.tsx |
|
|
13
|
+
| [Surface Frontend (DB-driven UI consumption, src/surface/)](features/surface-frontend.md) | The frontend consumer of the platform-wide Surface layer — DB-driven UI config fetched from `GET /v2/surfaces/meta?slug=<slug>` instead of statically-imported J | toga25-supply/src/surface/useFetchSurfaceMeta.ts, toga25-supply/src/pages/SalesOrders/helpers/surfaceBundleToTenantFields.ts, toga25-supply/src/pages/SalesOrders/helpers/buildPatchedTenantFields.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/viewModel/useSalesOrderRecordModalLayoutModel.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/SalesOrderView.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/layoutComponents/SalesOrderSummaryGrid.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/getDetailSections.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/sections/SalesOrderNotesSection.tsx, toga25-supply/src/pages/SalesOrders/helpers/cleanOrder.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/index.ts, toga25-supply/src/surface/evaluateSurfaceRule.ts, toga25-supply/src/surface/resolveElementState.ts, toga25-supply/src/pages/SalesOrders/helpers/evaluateEnableRule.ts, toga25-supply/src/pages/SalesOrders/hooks/useSalesOrderRowRecordState.ts, toga25-supply/src/surface/actionRegistry.ts, toga25-supply/src/surface/componentRegistry.tsx, toga25-supply/src/surface/SurfaceActionBar.tsx, toga25-supply/src/surface/SurfaceSection.tsx, toga25-supply/src/surface/resolve.ts, toga25-supply/src/surface/types.ts, toga25-supply/src/surface/index.ts, toga25-supply/src/pages/Login/LoginPage.tsx, toga25-supply/src/pages/SalesOrders/SalesOrders.tsx, toga25-supply/src/pages/SalesOrders/view/SurfaceRowActions.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/sections/SalesOrderTopBar.tsx, toga25-supply/src/pages/Items/ItemsPage.tsx, toga25-supply/src/pages/Items/viewModel/useItemsPageViewModel.tsx, toga25-supply/src/pages/VendorItems/VendorItemsPage.tsx, toga25-supply/src/pages/VendorItems/viewModel/useVendorItemsPageViewModel.tsx, toga25-supply/src/pages/Inventory/Inventory.tsx, toga25-supply/src/pages/Inventory/viewModel/useInventoryPageViewModel.tsx, toga25-supply/src/pages/Inventory/viewModel/FIELDS/index.ts, toga25-supply/src/fieldsConfig/index.ts, toga25-supply/src/layout/ItemRecordModalLayout/helpers/surfaceBundleToItemFields.ts, toga25-supply/src/layout/ItemRecordModalLayout/helpers/index.ts, toga25-supply/src/layout/ItemRecordModalLayout/viewModel/useItemRecordModalViewModel.tsx, toga25-supply/src/layout/ItemRecordModalLayout/ItemRecordModalLayout.tsx, toga25-supply/src/layout/ItemRecordModalLayout/components/ItemRecordView.tsx, toga25-supply/src/surface/useStatusColors.ts, toga25-supply/src/surface/SurfaceHeader.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderApprovalModalsLayout/helpers/surfaceBundlesToDecisionFields.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderApprovalModalsLayout/viewModel/useApprovalModalViewModel.tsx |
|
|
14
14
|
| [AWS Amplify Multi-Environment Deployment](workflows/amplify-deployment.md) | How `toga25-supply` deploys to **all** of its environments on AWS Amplify from a **single shared `amplify.yml`**. | toga25-supply/amplify.yml, toga25-supply/src/api/api.ts, toga25-supply/src/hooks/useAuthenticationFlow.ts, toga25-supply/vite.config.ts, toga25-supply/package.json |
|
|
15
15
|
| [Cypress Testing Harness (component + e2e)](workflows/cypress-testing.md) | The Cypress test harness for the `toga25-supply` frontend, bootstrapped from scratch (`cypress` was already a dependency but there was no config, no `cypress/` | toga25-supply/cypress.config.ts, toga25-supply/cypress/tsconfig.json, toga25-supply/cypress/support/component.tsx, toga25-supply/cypress/support/component-index.html, toga25-supply/cypress/support/e2e.ts, toga25-supply/cypress/support/commands.ts, toga25-supply/cypress/support/fixtures.ts, toga25-supply/cypress/support/mocks/useApprovalModalViewModel.ts, toga25-supply/cypress/component/SalesOrderApprovalModalsLayout.cy.tsx, toga25-supply/cypress/component/RecordApprovalModalLayout.cy.tsx, toga25-supply/cypress/component/EnterPoNumberModal.cy.tsx, toga25-supply/cypress/e2e/salesOrderApproval.cy.ts |
|
|
@@ -49,6 +49,8 @@ files:
|
|
|
49
49
|
- toga25-supply/src/layout/ItemRecordModalLayout/components/ItemRecordView.tsx
|
|
50
50
|
- toga25-supply/src/surface/useStatusColors.ts
|
|
51
51
|
- toga25-supply/src/surface/SurfaceHeader.tsx
|
|
52
|
+
- toga25-supply/src/pages/SalesOrders/view/SalesOrderApprovalModalsLayout/helpers/surfaceBundlesToDecisionFields.ts
|
|
53
|
+
- toga25-supply/src/pages/SalesOrders/view/SalesOrderApprovalModalsLayout/viewModel/useApprovalModalViewModel.tsx
|
|
52
54
|
related:
|
|
53
55
|
- ../../_underscore/features/surface-resolver.md
|
|
54
56
|
- meta-driven-table-data.md
|
|
@@ -262,6 +264,40 @@ in [surface-layer-schema](../../dbchanges2/features/surface-layer-schema.md):
|
|
|
262
264
|
> shows **`leasePrice`** for all clients, whereas the old DEFAULT JSON showed only unit price. Confirm
|
|
263
265
|
> that is the intended seed shape.
|
|
264
266
|
|
|
267
|
+
## SalesOrders approval-decision modal (approve + deny) — migrated via an OVERLAY adapter seam
|
|
268
|
+
|
|
269
|
+
The SalesOrder approve/deny decision modal's config now sources its display fields from Surface,
|
|
270
|
+
overlaid onto the existing per-client `approvalActionFields.json` — the same adapter-seam pattern as
|
|
271
|
+
`surfaceBundleToTenantFields` / `surfaceBundleToItemViewFields`, but with a **merge (overlay), not a
|
|
272
|
+
full replacement**, because the surfaces cover only part of `recordActionFields`.
|
|
273
|
+
|
|
274
|
+
- **`surfaceBundlesToDecisionFields.ts`** (new, `SalesOrderApprovalModalsLayout/helpers/`) adapts the
|
|
275
|
+
**3** resolved surface bundles into the decision-modal shape `{ orderContentDetails, approve, deny }`.
|
|
276
|
+
Exports `DECISION_SURFACE_SLUGS`, `surfaceBundlesToDecisionFields()`, `isDecisionSurfaceEnabled()`,
|
|
277
|
+
and `overlayDecisionSurfaceFields(jsonRecordActionFields, decision)`. Elements are found by
|
|
278
|
+
**`config.role`** — no ADMIN/MANAGER branching, since surfaces resolve per-role server-side. Labels
|
|
279
|
+
via `resolveMessage`; icon/color/weight from `el.tokens`.
|
|
280
|
+
- **`useApprovalModalViewModel.tsx`** fetches the 3 surfaces via
|
|
281
|
+
`useFetchSurfaceMetaGroup(DECISION_SURFACE_SLUGS)`, computes `decisionSurfacesEnabled` /
|
|
282
|
+
`decisionSurfaceFields`, and builds `resolvedTenantFields` that **overlays** the 3 Surface-migrated
|
|
283
|
+
`recordActionFields` keys (`orderContentDetails`, `approve`, `deny`) onto the patched JSON. Unseeded
|
|
284
|
+
clients fall back to pure JSON (no roster; enablement is detected from the resolved bundles).
|
|
285
|
+
|
|
286
|
+
**Overlay, not replacement (decision).** The 3 surfaces cover only 3 of the 7 `recordActionFields`
|
|
287
|
+
keys; keys NOT yet migrated stay JSON-sourced (`guardrailCopy`, `actionOptions` [the approve
|
|
288
|
+
step-two enable rule], `approvalWorkflow`, `orderContentDetailsWorkflow`). The JSON approve/deny
|
|
289
|
+
blocks also carry **functional** attributes the surface does not emit (`characterLimit 255`,
|
|
290
|
+
`inputContainerWidth`, submit `valueKeys`). An `overlayDefined()` helper copies only *defined* surface
|
|
291
|
+
values, so JSON-only functional fields survive: **Surface owns all display attributes** (labels,
|
|
292
|
+
visibility, icons, `isRequired`, placeholder, `textAreaHeight`); JSON fills gaps and functional
|
|
293
|
+
wiring. The per-client `approvalActionFields.json` files are kept on disk as reference (not deleted).
|
|
294
|
+
|
|
295
|
+
**Shared summary, separate per-action chrome (decision).** The 8 order-summary rows are identical for
|
|
296
|
+
approve and deny, so they come from **one** shared surface (`sales-order-decision-summary`); the action
|
|
297
|
+
chrome (title, reason-input required-ness, confirm button, icons, toasts) diverges, so it is **two**
|
|
298
|
+
surfaces (`sales-order-approve-action`, `sales-order-deny-action`). Seed side:
|
|
299
|
+
[surface-layer-schema](../../dbchanges2/features/surface-layer-schema.md).
|
|
300
|
+
|
|
265
301
|
## Two FE rule engines (surface Tier-1 vs legacy named-rule) — do not conflate
|
|
266
302
|
|
|
267
303
|
There are **two** rule evaluators in this app. As of 2026-07-21 the surface evaluator now has a
|
|
@@ -424,6 +460,20 @@ now carry it (2026-07-21):
|
|
|
424
460
|
treat type-checking as pending. Runtime `GET /v2/surfaces/{slug}/meta` also not yet exercised.
|
|
425
461
|
|
|
426
462
|
## Change history
|
|
463
|
+
- 2026-07-21 — Migrated the **SalesOrders approve/deny decision modal** display config onto Surface via
|
|
464
|
+
an **overlay** adapter seam. New `surfaceBundlesToDecisionFields.ts` adapts the 3 resolved bundles
|
|
465
|
+
(`DECISION_SURFACE_SLUGS`) into `{orderContentDetails, approve, deny}`, finding elements by
|
|
466
|
+
`config.role` (no ADMIN/MANAGER branch — surfaces resolve per-role server-side); exports
|
|
467
|
+
`isDecisionSurfaceEnabled()` + `overlayDecisionSurfaceFields()`. `useApprovalModalViewModel.tsx`
|
|
468
|
+
fetches via `useFetchSurfaceMetaGroup` and OVERLAYS the 3 migrated `recordActionFields` keys onto the
|
|
469
|
+
patched JSON — merge, not replacement, because 4 keys (`guardrailCopy`/`actionOptions`/
|
|
470
|
+
`approvalWorkflow`/`orderContentDetailsWorkflow`) and functional attrs (`characterLimit`/
|
|
471
|
+
`inputContainerWidth`/submit `valueKeys`) stay JSON-sourced; `overlayDefined()` copies only defined
|
|
472
|
+
surface values so JSON functional fields survive (Surface owns display, JSON fills gaps). Summary rows
|
|
473
|
+
are one shared surface (`sales-order-decision-summary`); approve/deny chrome are two surfaces. Unseeded
|
|
474
|
+
clients fall back to pure JSON (enablement detected from bundles, no roster). tsc + eslint clean
|
|
475
|
+
(replaced `any` with `Record<string,unknown>` + casts at the JSON boundary in the overlay helpers).
|
|
476
|
+
(apeterson)
|
|
427
477
|
- 2026-07-21 — **Option B: moved the Approve enable-gate onto the surface FE path.** Added a
|
|
428
478
|
`SURFACE_NAMED_RULES` map + a `{type:SurfaceNamedRule}` branch to `evaluateSurfaceRule.ts`
|
|
429
479
|
(`SurfaceNamedRule` = `"stepTwoAssigned"|"poNumberEntered"` in `types.ts`) — the sanctioned FE-side
|
package/package.json
CHANGED