toga-ai 1.0.516 → 1.0.517
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.
|
@@ -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, toga25-supply/src/pages/SalesOrders/view/SalesOrderApprovalModalsLayout/helpers/surfaceBundlesToDecisionFields.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderApprovalModalsLayout/viewModel/useApprovalModalViewModel.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/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/sectionRenderers.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/getVisibleSections.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/layoutComponents/SalesOrderApprovalSummaryGrid.tsx, 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 |
|
|
@@ -6,9 +6,12 @@ project: TOGa 2.5 Supply
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-
|
|
9
|
+
updated: 2026-08-04
|
|
10
10
|
owners: [jcardinal, apeterson]
|
|
11
11
|
files:
|
|
12
|
+
- toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/sectionRenderers.tsx
|
|
13
|
+
- toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/getVisibleSections.ts
|
|
14
|
+
- toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/layoutComponents/SalesOrderApprovalSummaryGrid.tsx
|
|
12
15
|
- toga25-supply/src/surface/useFetchSurfaceMeta.ts
|
|
13
16
|
- toga25-supply/src/pages/SalesOrders/helpers/surfaceBundleToTenantFields.ts
|
|
14
17
|
- toga25-supply/src/pages/SalesOrders/helpers/buildPatchedTenantFields.ts
|
|
@@ -384,6 +387,50 @@ now carry it (2026-07-21):
|
|
|
384
387
|
onto `record.order`, mirroring the record-modal view model. Both FE surfaces now carry
|
|
385
388
|
`order.currentStage`/`order.stages`/`order.purchaseOrderDetails`.
|
|
386
389
|
|
|
390
|
+
## SalesOrders record modal — conditional two-layout split (approval vs standard)
|
|
391
|
+
|
|
392
|
+
In approval stages the SO record modal needs a **materially different layout**, not just
|
|
393
|
+
different styling: the approval-details card leads and is wide, Order Details + Bill To
|
|
394
|
+
relocate *below* the Items table side-by-side, and Admin Notes moves to the top. This is a
|
|
395
|
+
placement difference **across the DOM tree**, so it is implemented as a **component split at
|
|
396
|
+
`SalesOrderView`** (branching on `isApprovalDetailsActive`), not prop-driven branching inside
|
|
397
|
+
one grid. Shared machinery was extracted so both layouts reuse it rather than duplicating:
|
|
398
|
+
|
|
399
|
+
- **`helpers/sectionRenderers.tsx`** (new) — `createSectionRenderers` factory exposes the
|
|
400
|
+
`detailSection`/`approvalDetails`/`locationCard`/`totalsCard` renderer map, extracted from the
|
|
401
|
+
grid so both the standard and approval grids share one renderer set.
|
|
402
|
+
- **`helpers/getVisibleSections.ts`** (new) — extracted the `isVisible` + `visibilityRule` +
|
|
403
|
+
approval-suppression filter into one place.
|
|
404
|
+
- **`layoutComponents/SalesOrderApprovalSummaryGrid.tsx`** (new, exported from the barrel) — the
|
|
405
|
+
approval-stage top grid: approval-details card spans 3 cols, order-summary totals 1 col
|
|
406
|
+
(`.approvalSummaryGrid` 4-col + `.approvalDetailsSpan` span-3, responsive).
|
|
407
|
+
- **`SalesOrderSummaryGrid.tsx`** slimmed to delegate to the two helpers; **`SalesOrderView.tsx`**
|
|
408
|
+
swaps grid + renders AdminNotes at top in the approval branch; **`getDetailSections.tsx`**
|
|
409
|
+
(approval-only) relocates Order Details + Bill To below the Items table and suppresses the
|
|
410
|
+
below-items adminNotes since it moves to top.
|
|
411
|
+
|
|
412
|
+
`isApprovalDetailsActive` drives **both** the grid swap and the section relocation, so the
|
|
413
|
+
approval condition lives in exactly one place.
|
|
414
|
+
|
|
415
|
+
### Boundary rule: grid geometry is FE presentation, NOT surface metadata
|
|
416
|
+
**Surface owns content / visibility / order / ACL only. Column count and per-field colSpan are
|
|
417
|
+
FE presentation and stay in code/CSS.** The approval-details card renders into a **fixed 2-col**
|
|
418
|
+
`.approvalFieldsGrid` (`repeat(2, minmax(0,1fr))`) that reflows automatically as the surface
|
|
419
|
+
hides/shows fields — `BaseDetailField` already spans via `--field-col-span`. If per-field colSpan
|
|
420
|
+
is ever needed it becomes **deterministic FE logic keyed on `valueType`** (address / long-text =
|
|
421
|
+
wide), identical for every client — never a surface attribute.
|
|
422
|
+
|
|
423
|
+
A first attempt to surface-drive the 2-col layout via surface `config.columns` + element
|
|
424
|
+
`config.colSpan` was **reverted**. The reason is durable and verifiable: the resolver's **CONFIG
|
|
425
|
+
override REPLACES an element's whole `config` blob rather than merging it**
|
|
426
|
+
(`_underscore/Model/Core/Surface.php` ~L827: `$config = $value`; see
|
|
427
|
+
[surface-resolver](../../_underscore/features/surface-resolver.md)). Making per-client colSpan
|
|
428
|
+
work would have required promoting it to a first-class `COL_SPAN` in the
|
|
429
|
+
`SurfaceOverrides.attribute` ENUM + resolver + schema + a framework deploy — far too much
|
|
430
|
+
machinery for "this box is two columns wide", which is exactly the signal that it belongs in the
|
|
431
|
+
FE. Use this as the config/logic line for surface geometry questions: **presentation geometry →
|
|
432
|
+
FE/CSS; content/visibility/order/ACL → Surface.**
|
|
433
|
+
|
|
387
434
|
## Gotchas
|
|
388
435
|
|
|
389
436
|
- **A named predicate that FAILS OPEN silently enables a button when its data isn't fetched.**
|
|
@@ -497,6 +544,21 @@ now carry it (2026-07-21):
|
|
|
497
544
|
treat type-checking as pending. Runtime `GET /v2/surfaces/{slug}/meta` also not yet exercised.
|
|
498
545
|
|
|
499
546
|
## Change history
|
|
547
|
+
- 2026-08-04 — **Built** a conditional two-layout split for the SalesOrders record modal
|
|
548
|
+
(approval vs standard), driven by `isApprovalDetailsActive` at `SalesOrderView`. In approval
|
|
549
|
+
stages the approval-details card leads (wide), Order Details + Bill To move below the Items
|
|
550
|
+
table side-by-side, and Admin Notes moves to the top — a placement difference across the DOM
|
|
551
|
+
tree, so a component split over prop branching. Extracted shared machinery: `sectionRenderers.tsx`
|
|
552
|
+
(`createSectionRenderers` factory: detail/approvalDetails/location/totals renderers),
|
|
553
|
+
`getVisibleSections.ts` (visibility + approval-suppression filter), and new
|
|
554
|
+
`SalesOrderApprovalSummaryGrid.tsx` (4-col grid, approval-details span-3). **DECISION/DISCOVERED:**
|
|
555
|
+
grid geometry (column count, per-field colSpan) is FE presentation, NOT surface metadata —
|
|
556
|
+
surface owns content/visibility/order/ACL only. The 2-col approval-details grid is fixed FE/CSS
|
|
557
|
+
that reflows as the surface hides/shows fields. A first attempt to surface-drive it via
|
|
558
|
+
`config.columns`/`config.colSpan` was reverted after finding the resolver's **CONFIG override
|
|
559
|
+
wholesale-REPLACES an element's `config` blob** (`_underscore/Model/Core/Surface.php` ~L827
|
|
560
|
+
`$config = $value`), so a first-class `COL_SPAN` ENUM + resolver + schema + deploy would be
|
|
561
|
+
needed — too much machinery, the signal it belongs in the FE. (apeterson)
|
|
500
562
|
- 2026-07-23 — **DECISION + FIX: surface on/off per client is now 100% backend-driven — removed the FE
|
|
501
563
|
roster entirely.** Deleted `SALES_ORDER_SURFACE_MIGRATED_CLIENTS = [COMPASS,COMPASSCANADA,QUAD]` from
|
|
502
564
|
`surfaceBundleToTenantFields.ts` + `helpers/index.ts`; `useSalesOrderRecordModalLayoutModel.tsx` now
|
package/package.json
CHANGED