@vtex/faststore-plugin-buyer-portal 1.3.86 → 1.3.88
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.
- package/CHANGELOG.md +25 -1
- package/cypress/constants.ts +0 -8
- package/cypress/integration/product-assortment.test.ts +2 -2
- package/package.json +1 -1
- package/plugin.config.js +0 -12
- package/specs/assortments-page-fixes.md +222 -0
- package/specs/deprecate-address-locations.md +497 -0
- package/specs/deprecate-custom-fields.md +473 -0
- package/src/features/addresses/components/AddressDropdownMenu/AddressDropdownMenu.tsx +1 -15
- package/src/features/addresses/components/CreateAddressDrawer/CreateAddressDrawer.tsx +4 -13
- package/src/features/addresses/components/CreateAddressDrawer/create-address-drawer.scss +0 -1
- package/src/features/addresses/components/CreateAddressSettingsDrawer/create-address-settings-drawer.scss +0 -1
- package/src/features/addresses/components/RemoveAddressDrawer/remove-address-drawer.scss +0 -1
- package/src/features/addresses/components/index.ts +0 -3
- package/src/features/addresses/hooks/index.ts +0 -4
- package/src/features/addresses/layouts/AddressDetailsLayout/AddressDetailsLayout.tsx +14 -55
- package/src/features/addresses/layouts/AddressDetailsLayout/address-details-layout.scss +0 -49
- package/src/features/addresses/layouts/AddressesLayout/addresses-layout.scss +0 -2
- package/src/features/addresses/services/default-values/get-default-address.service.ts +0 -1
- package/src/features/addresses/types/AddressData.ts +0 -50
- package/src/features/budgets/hooks/useGetAllocations.ts +1 -34
- package/src/features/buying-policies/components/BasicBuyingPolicyDrawer/BasicBuyingPolicyDrawer.tsx +0 -43
- package/src/features/buying-policies/components/BasicBuyingPolicyDrawer/basic-buying-policy-drawer.scss +0 -1
- package/src/features/buying-policies/utils/__tests__/orderFieldsCriteriaOptions.test.ts +41 -0
- package/src/features/buying-policies/utils/index.ts +0 -2
- package/src/features/buying-policies/utils/orderFieldsCriteriaOptions.ts +0 -21
- package/src/features/org-units/components/AddAllToOrgUnitDropdown/AddAllToOrgUnitDropdown.tsx +3 -49
- package/src/features/org-units/layouts/OrgUnitDetailsLayout/OrgUnitDetailsLayout.tsx +14 -2
- package/src/features/org-units/layouts/OrgUnitDetailsLayout/org-units-details.scss +1 -0
- package/src/features/product-assortment/layouts/ProductAssortmentLayout/ProductAssortmentLayout.tsx +10 -10
- package/src/features/product-assortment/layouts/ProductAssortmentLayout/product-assortment-layout.scss +0 -46
- package/src/features/shared/components/BasicDropdownMenu/basic-dropdown-menu.scss +5 -0
- package/src/features/shared/components/CustomFieldsDeprecationAlert/CustomFieldsDeprecationAlert.tsx +27 -0
- package/src/features/shared/components/CustomFieldsDeprecationAlert/custom-fields-deprecation-alert.scss +33 -0
- package/src/features/shared/components/Tab/TabOption.tsx +8 -1
- package/src/features/shared/components/Tab/tab.scss +5 -0
- package/src/features/shared/components/VerticalNav/VerticalNavLink.tsx +30 -4
- package/src/features/shared/components/VerticalNav/vertical-nav.scss +9 -0
- package/src/features/shared/components/index.ts +4 -0
- package/src/features/shared/hooks/usePageItems.ts +0 -2
- package/src/features/shared/layouts/BaseTabsLayout/SidebarMenu.tsx +9 -2
- package/src/features/shared/layouts/index.ts +0 -4
- package/src/features/shared/services/logger/analytics/constants.ts +0 -16
- package/src/features/shared/utils/__tests__/getContractSettingsLinks.test.ts +47 -0
- package/src/features/shared/utils/__tests__/getKeyByValue.test.ts +28 -0
- package/src/features/shared/utils/buyerPortalRoutes.ts +0 -9
- package/src/features/shared/utils/constants.ts +4 -3
- package/src/features/shared/utils/getContractSettingsLinks.ts +15 -4
- package/src/features/shared/utils/getKeyByValue.ts +0 -3
- package/src/features/shared/utils/routeLayoutMapping.ts +1 -17
- package/src/pages/address-details.tsx +1 -29
- package/src/themes/layouts.scss +0 -3
- package/cypress/integration/locations.test.ts +0 -196
- package/src/features/addresses/clients/LocationsClient.ts +0 -98
- package/src/features/addresses/components/AddressLocationsList/AddressLocationsList.tsx +0 -219
- package/src/features/addresses/components/DeleteAddressLocationDrawer/DeleteAddressLocationDrawer.tsx +0 -126
- package/src/features/addresses/components/DeleteAddressLocationDrawer/delete-address-location-drawer.scss +0 -20
- package/src/features/addresses/components/EditAddressLocationDrawer/EditAddressLocationDrawer.tsx +0 -151
- package/src/features/addresses/components/EditAddressLocationDrawer/edit-address-location-drawer.scss +0 -14
- package/src/features/addresses/components/LocationForm/LocationField/LocationField.tsx +0 -43
- package/src/features/addresses/components/LocationForm/LocationField/location-field.scss +0 -34
- package/src/features/addresses/components/LocationForm/LocationForm.tsx +0 -54
- package/src/features/addresses/components/LocationForm/location-form.scss +0 -41
- package/src/features/addresses/components/LocationsDrawer/LocationsDrawer.tsx +0 -146
- package/src/features/addresses/hooks/useAddLocationsToAddress.ts +0 -25
- package/src/features/addresses/hooks/useAddressLocationDelete.ts +0 -26
- package/src/features/addresses/hooks/useAddressLocationEdit.ts +0 -27
- package/src/features/addresses/hooks/useAddressLocationList.ts +0 -35
- package/src/features/addresses/services/locations/add-address-locations.service.ts +0 -6
- package/src/features/addresses/services/locations/delete-address-location.service.ts +0 -7
- package/src/features/addresses/services/locations/edit-address-location.service.ts +0 -6
- package/src/features/addresses/services/locations/get-address-locations.service.ts +0 -28
- package/src/features/buying-policies/components/CustomFieldCriteriaSelector/CustomFieldCriteriaSelector.tsx +0 -154
- package/src/features/buying-policies/components/CustomFieldCriteriaSelector/custom-field-criteria-selector.scss +0 -139
- package/src/features/custom-fields/components/CreateCustomFieldValueDrawer/CreateCustomFieldValueDrawer.tsx +0 -208
- package/src/features/custom-fields/components/CustomFieldSettingsDrawer/CustomFieldSettingsDrawer.tsx +0 -379
- package/src/features/custom-fields/components/DeleteCustomFieldValueDrawer/DeleteCustomFieldValueDrawer.tsx +0 -183
- package/src/features/custom-fields/components/UpdateCustomFieldValueDrawer/UpdateCustomFieldValueDrawer.tsx +0 -108
- package/src/features/custom-fields/components/index.ts +0 -4
- package/src/features/custom-fields/layouts/CustomFieldsLayout/CustomFieldsLayout.tsx +0 -325
- package/src/features/custom-fields/layouts/CustomFieldsLayout/custom-fields-layout.scss +0 -37
- package/src/features/custom-fields/layouts/index.ts +0 -1
- package/src/features/custom-fields/types/index.ts +0 -5
- package/src/features/shared/clients/CustomField.ts +0 -204
- package/src/features/shared/clients/DefaultValueClient.ts +0 -62
- package/src/features/shared/components/CustomField/create-custom-field/CreateCustomFieldDrawer.tsx +0 -155
- package/src/features/shared/components/CustomField/create-custom-field/create-custom-field-drawer.scss +0 -30
- package/src/features/shared/components/CustomField/delete-custom-field/DeleteCustomFieldDrawer.tsx +0 -127
- package/src/features/shared/components/CustomField/delete-custom-field/delete-custom-field-drawer.scss +0 -34
- package/src/features/shared/components/CustomField/index.ts +0 -6
- package/src/features/shared/components/CustomField/selected-card-item/CustomFieldSelectedCardItem.tsx +0 -31
- package/src/features/shared/components/CustomField/selected-card-item/custom-field-selected-card-item.scss +0 -53
- package/src/features/shared/components/CustomField/settings-drawer/CustomFieldSettingsDrawer.tsx +0 -159
- package/src/features/shared/components/CustomField/settings-drawer/custom-field-settings-drawer.scss +0 -98
- package/src/features/shared/components/CustomField/table/CustomFieldTable.tsx +0 -151
- package/src/features/shared/components/CustomField/table/custom-field-table.scss +0 -41
- package/src/features/shared/components/CustomField/update-custom-field/UpdateCustomFieldDrawer.tsx +0 -184
- package/src/features/shared/components/CustomField/update-custom-field/update-custom-field-drawer.scss +0 -46
- package/src/features/shared/hooks/custom-field/index.ts +0 -11
- package/src/features/shared/hooks/custom-field/useAddCustomFieldValueToScope.ts +0 -25
- package/src/features/shared/hooks/custom-field/useAddDefaultValue.ts +0 -25
- package/src/features/shared/hooks/custom-field/useCreateCustomFieldValue.ts +0 -25
- package/src/features/shared/hooks/custom-field/useCustomFieldSettings.ts +0 -18
- package/src/features/shared/hooks/custom-field/useDeleteCustomFieldValue.ts +0 -25
- package/src/features/shared/hooks/custom-field/useDeleteCustomFieldValueAndUpdateUnitScope.ts +0 -27
- package/src/features/shared/hooks/custom-field/useDeleteCustomFieldValueToScope.ts +0 -27
- package/src/features/shared/hooks/custom-field/useGetCustomFieldValues.ts +0 -20
- package/src/features/shared/hooks/custom-field/useGetDefaultValue.ts +0 -18
- package/src/features/shared/hooks/custom-field/useRemoveDefaultValue.ts +0 -25
- package/src/features/shared/hooks/custom-field/useUpdateCustomFieldSettings.ts +0 -27
- package/src/features/shared/hooks/custom-field/useUpdateCustomFieldValue.ts +0 -25
- package/src/features/shared/layouts/CustomFieldLayout/CustomFieldLayout.tsx +0 -108
- package/src/features/shared/layouts/CustomFieldLayout/custom-field-layout.scss +0 -67
- package/src/features/shared/services/custom-field/add-custom-field-value-to-scope.service.ts +0 -26
- package/src/features/shared/services/custom-field/add-default-value.service.ts +0 -27
- package/src/features/shared/services/custom-field/create-custom-field-value.service.ts +0 -26
- package/src/features/shared/services/custom-field/delete-custom-field-value-and-update-unit-scope.service.ts +0 -26
- package/src/features/shared/services/custom-field/delete-custom-field-value-to-unit-scope.service.ts +0 -26
- package/src/features/shared/services/custom-field/delete-custom-field-value.service.ts +0 -26
- package/src/features/shared/services/custom-field/get-custom-field-settings.service.ts +0 -22
- package/src/features/shared/services/custom-field/get-custom-fields-values.service.ts +0 -30
- package/src/features/shared/services/custom-field/get-default-value.service.ts +0 -20
- package/src/features/shared/services/custom-field/index.ts +0 -59
- package/src/features/shared/services/custom-field/remove-default-value.service.ts +0 -25
- package/src/features/shared/services/custom-field/update-custom-field-settings.service.ts +0 -28
- package/src/features/shared/services/custom-field/update-custom-field-value.service.ts +0 -34
- package/src/features/shared/types/CustomFields.ts +0 -6
- package/src/pages/cost-centers.tsx +0 -104
- package/src/pages/po-numbers.tsx +0 -98
- package/src/pages/releases.tsx +0 -98
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.3.88] - 2026-07-23
|
|
11
|
+
|
|
12
|
+
### Removed
|
|
13
|
+
|
|
14
|
+
- PO Numbers, Cost Centers, and Releases pages, routes, and every dedicated client/hook/service/component (the `custom-fields` feature and the shared `custom-field` building blocks) — the underlying BFF service is discontinued on 2026-07-30
|
|
15
|
+
- Address Locations client, hooks, services, and dedicated components/drawers, and the "Locations" tab from the "Add address" drawer (same discontinued BFF service)
|
|
16
|
+
- PO Number/Cost Center/Release as selectable allocation types in "Add budget allocations" and as criteria presets in "Set order field criteria" (existing budget allocations and buying policy criteria created before this change keep displaying normally)
|
|
17
|
+
- "Add cost center"/"Add PO number"/"Add release" shortcuts in the Org Unit "Add" dropdown (now disabled, no action)
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- A persistent deprecation alert on the Org Unit Details page, explaining that PO Numbers, Cost Centers, and Releases were replaced by Accounting Fields and pointing to the upgrade path (buyer-portal plugin `v2.0.1+`, FastStore `v4`)
|
|
22
|
+
- A persistent deprecation alert on the Address Details page, explaining that Address Locations was replaced by Accounting Fields and pointing to the same upgrade path
|
|
23
|
+
- Support for a disabled, tooltip-carrying state on `VerticalNav.Link`, used to keep the "PO numbers"/"Cost centers"/"Releases" navigation entries visible (but disabled) in the Org Unit Details cards and the Contract-settings sidebar
|
|
24
|
+
- Support for a disabled state on `TabOption`, used to keep the "Locations" tab visible (but disabled) on the Address Details page; the "Add Locations" shortcut in the address actions dropdown is disabled the same way
|
|
25
|
+
|
|
26
|
+
## [1.3.87] - 2026-05-21
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Assortments page: use consistent "Assortments" title during loading and after page load by updating `routeLayoutMapping` and replacing the custom header with `HeaderInside`, aligning title position with other Contract settings pages
|
|
31
|
+
|
|
10
32
|
## [1.3.86] - 2026-05-19
|
|
11
33
|
|
|
12
34
|
### Added
|
|
@@ -640,7 +662,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
640
662
|
- Add CHANGELOG file
|
|
641
663
|
- Add README file
|
|
642
664
|
|
|
643
|
-
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/
|
|
665
|
+
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.87...HEAD
|
|
644
666
|
[1.3.55]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.54...v1.3.55
|
|
645
667
|
[1.3.54]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.53...v1.3.54
|
|
646
668
|
[1.3.53]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.52...v1.3.53
|
|
@@ -725,4 +747,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
725
747
|
[1.3.70]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.69...v1.3.70
|
|
726
748
|
[1.3.85]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.85
|
|
727
749
|
|
|
750
|
+
[1.3.88]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.87...v1.3.88
|
|
751
|
+
[1.3.87]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.86...v1.3.87
|
|
728
752
|
[1.3.86]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.86
|
package/cypress/constants.ts
CHANGED
|
@@ -89,14 +89,6 @@ export const TEST_DATA = {
|
|
|
89
89
|
NEW_ADDRESS_STATE: "RJ",
|
|
90
90
|
NEW_ADDRESS_POSTAL_CODE: "22250-905",
|
|
91
91
|
},
|
|
92
|
-
LOCATIONS: {
|
|
93
|
-
LOCATION_ADDRESS_NAME: "LOCATIONS",
|
|
94
|
-
FIRST_LOCATION: "Location 1",
|
|
95
|
-
SECOND_LOCATION: "Location 2",
|
|
96
|
-
THIRD_LOCATION: "Location 3",
|
|
97
|
-
FOURTH_LOCATION: "Location 4",
|
|
98
|
-
EDITED_LOCATION: "Edited Location",
|
|
99
|
-
},
|
|
100
92
|
RECIPIENTS: {
|
|
101
93
|
RECIPIENTS_ADDRESS_NAME: "RECIPIENTS",
|
|
102
94
|
FIRST_RECIPIENT_NAME: "First Recipient",
|
|
@@ -6,7 +6,7 @@ function visitProductAssortmentPage() {
|
|
|
6
6
|
|
|
7
7
|
// Navigate to product assortment page
|
|
8
8
|
cy.get("[data-fs-vertical-nav-menu-item]")
|
|
9
|
-
.contains("
|
|
9
|
+
.contains("Assortments")
|
|
10
10
|
.click({ timeout: TEST_CONFIG.TIMEOUTS.PAGE_LOAD });
|
|
11
11
|
|
|
12
12
|
cy.wait(1000);
|
|
@@ -58,7 +58,7 @@ describe(
|
|
|
58
58
|
|
|
59
59
|
// Wait for product assortment section to be visible
|
|
60
60
|
cy.get("[data-fs-bp-header-inside-title]")
|
|
61
|
-
.contains("
|
|
61
|
+
.contains("Assortments")
|
|
62
62
|
.should("be.visible");
|
|
63
63
|
|
|
64
64
|
// Wait for product assortment table to be loaded
|
package/package.json
CHANGED
package/plugin.config.js
CHANGED
|
@@ -40,18 +40,6 @@ module.exports = {
|
|
|
40
40
|
path: "/pvt/organization-account/product-assortment/[orgUnitId]/[contractId]",
|
|
41
41
|
appLayout: false,
|
|
42
42
|
},
|
|
43
|
-
"po-numbers": {
|
|
44
|
-
path: "/pvt/organization-account/po-numbers/[orgUnitId]/[contractId]",
|
|
45
|
-
appLayout: false,
|
|
46
|
-
},
|
|
47
|
-
"cost-centers": {
|
|
48
|
-
path: "/pvt/organization-account/cost-centers/[orgUnitId]/[contractId]",
|
|
49
|
-
appLayout: false,
|
|
50
|
-
},
|
|
51
|
-
releases: {
|
|
52
|
-
path: "/pvt/organization-account/releases/[orgUnitId]/[contractId]",
|
|
53
|
-
appLayout: false,
|
|
54
|
-
},
|
|
55
43
|
roles: {
|
|
56
44
|
path: "/pvt/organization-account/roles/[orgUnitId]",
|
|
57
45
|
appLayout: false,
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Assortments Page Fixes
|
|
2
|
+
|
|
3
|
+
> **Status**: Approved
|
|
4
|
+
> **Created**: 2026-05-19
|
|
5
|
+
|
|
6
|
+
## 1. Business Context
|
|
7
|
+
|
|
8
|
+
### Problem Statement
|
|
9
|
+
|
|
10
|
+
The **Assortments** page was recently released in the Buyer Portal (Contract settings), but manual testing revealed two UX inconsistencies compared to sibling pages in the same group (Profile, Addresses, Payment methods, Credit cards):
|
|
11
|
+
|
|
12
|
+
1. **Unstable title during loading** — when navigating via the sidebar, users temporarily see "Product Assortment", and after the page finishes loading the title changes to "Assortments".
|
|
13
|
+
2. **Incorrect title vertical position** — the "Assortments" title appears higher on the page than on sibling pages.
|
|
14
|
+
|
|
15
|
+
These issues affect B2B administrators who manage organizational units and need to select the correct product assortment for each unit.
|
|
16
|
+
|
|
17
|
+
### Goals
|
|
18
|
+
|
|
19
|
+
- Ensure the title "Assortments" is displayed consistently during and after page load.
|
|
20
|
+
- Align the page header positioning and typography with other Contract settings pages.
|
|
21
|
+
|
|
22
|
+
### User Stories
|
|
23
|
+
|
|
24
|
+
#### US-1: Consistent title during navigation
|
|
25
|
+
|
|
26
|
+
- **Story**: As a contract administrator, I want the page title to remain "Assortments" while the page loads, so that I am not confused by a temporary, incorrect label.
|
|
27
|
+
- **Acceptance Criteria**:
|
|
28
|
+
- **Given** I am on any Contract settings page, **when** I click "Assortments" in the sidebar, **then** the loading state shows the title "Assortments" (not "Product Assortment" or "Product assortment").
|
|
29
|
+
- **Given** the Assortments page finishes loading, **when** the content is rendered, **then** the title remains "Assortments" with no visible title swap.
|
|
30
|
+
|
|
31
|
+
#### US-2: Header aligned with sibling pages
|
|
32
|
+
|
|
33
|
+
- **Story**: As a contract administrator, I want the Assortments page header to match Profile, Addresses, and Payment methods, so that the portal feels cohesive.
|
|
34
|
+
- **Acceptance Criteria**:
|
|
35
|
+
- **Given** I open Assortments and any other Contract settings page (e.g. Addresses), **when** I compare the page title position, **then** both titles share the same vertical offset from the top of the content area.
|
|
36
|
+
- **Given** the Assortments page is loaded, **when** I view the header, **then** it uses the shared `HeaderInside` component and styling used by sibling pages.
|
|
37
|
+
- **Given** the Assortments page is loaded, **when** I read the descriptive text below the title, **then** the subtitle "Select the product assortment that users in this organizational unit should access" is still visible.
|
|
38
|
+
|
|
39
|
+
### Key Scenarios
|
|
40
|
+
|
|
41
|
+
| Scenario | Pre-conditions | Steps | Expected Result |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| Happy path — list and selection | Contract with assortments; one assortment enabled | Open Assortments → select a different assortment | Title stays "Assortments"; all assortments listed; selection saves with success toast |
|
|
44
|
+
| Error case — failed selection save | User on Assortments page; API PUT fails | Select a different assortment | Radio reverts to previous selection; error toast "Failed to save assortment" |
|
|
45
|
+
| Edge case — loading transition | User on Profile page | Click "Assortments" in sidebar | Loading skeleton shows `HeaderInside` with title "Assortments"; no flicker to a different label after load |
|
|
46
|
+
|
|
47
|
+
### Functional Requirements
|
|
48
|
+
|
|
49
|
+
- FR-1: The assortments route `pageTitle` in `routeLayoutMapping.ts` must be `"Assortments"`.
|
|
50
|
+
- FR-2: `ProductAssortmentLayout` must use `HeaderInside title="Assortments"` instead of the custom header (`h1` + custom styles).
|
|
51
|
+
- FR-3: The descriptive subtitle must remain below `HeaderInside`, with scoped styles in the page section.
|
|
52
|
+
- FR-4: Radio selection behavior and persistence via `useSetAssortment` remain unchanged.
|
|
53
|
+
- FR-5: The listing must display all assortments returned by the API in a single request (maximum of 20 per contract — pagination is not required).
|
|
54
|
+
|
|
55
|
+
### Non-Functional Requirements
|
|
56
|
+
|
|
57
|
+
- Maintain plugin boundary compatibility — changes limited to `src/features/product-assortment/` and existing shared utilities.
|
|
58
|
+
- Pass `make lint`, `make typecheck`, and `make test`.
|
|
59
|
+
- Update Cypress tests only where the title or navigation label changed to "Assortments".
|
|
60
|
+
|
|
61
|
+
### Out of Scope
|
|
62
|
+
|
|
63
|
+
- **Pagination** — a contract supports at most 20 assortments; the API returns all of them in a single response, making pagination controls unnecessary.
|
|
64
|
+
- Add/remove assortment drawer functionality (present in legacy Cypress tests, absent from the current implementation).
|
|
65
|
+
- Name search/filter (the hook already accepts `search`, but it is not part of this fix).
|
|
66
|
+
- Changes to the API logic that places the enabled assortment at the top.
|
|
67
|
+
- Renaming routes or paths (`/product-assortment/...` remains unchanged).
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 2. Arch Decisions
|
|
72
|
+
|
|
73
|
+
### Proposed Solution
|
|
74
|
+
|
|
75
|
+
Fix the two UX bugs by aligning the Assortments page header with other Contract settings pages, reusing `HeaderInside` and unifying the title via `routeLayoutMapping`.
|
|
76
|
+
|
|
77
|
+
### Architecture Overview
|
|
78
|
+
|
|
79
|
+
```mermaid
|
|
80
|
+
sequenceDiagram
|
|
81
|
+
participant User
|
|
82
|
+
participant LoadingTabsLayout
|
|
83
|
+
participant ProductAssortmentLayout
|
|
84
|
+
participant useGetProductAssortment
|
|
85
|
+
participant API
|
|
86
|
+
|
|
87
|
+
User->>LoadingTabsLayout: Click "Assortments"
|
|
88
|
+
LoadingTabsLayout->>User: HeaderInside title="Assortments" (from routeLayoutMapping)
|
|
89
|
+
LoadingTabsLayout->>ProductAssortmentLayout: Route loaded
|
|
90
|
+
ProductAssortmentLayout->>useGetProductAssortment: orgUnitId, contractId
|
|
91
|
+
useGetProductAssortment->>API: GET .../assortments/available
|
|
92
|
+
API-->>ProductAssortmentLayout: items (up to 20)
|
|
93
|
+
ProductAssortmentLayout->>User: HeaderInside + table
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Root Cause Analysis
|
|
97
|
+
|
|
98
|
+
| Bug | Root cause (original code) |
|
|
99
|
+
|---|---|
|
|
100
|
+
| Title flicker | `LoadingTabsLayout` reads `pageTitle: "Product assortment"` from `routeLayoutMapping.ts` and renders it via `HeaderInside` (with `text-transform: capitalize` → "Product Assortment"). After load, `ProductAssortmentLayout` renders a custom `h1` with text "Assortments". |
|
|
101
|
+
| Title position | `ProductAssortmentLayout` does not use `HeaderInside`; it uses `[data-fs-bp-assortments-header]` with `padding: var(--fs-spacing-3) 0` and custom typography, unlike `[data-fs-bp-header-inside]` (`padding: var(--fs-bp-padding-4/8/9) 0`). |
|
|
102
|
+
|
|
103
|
+
### Alternatives Considered
|
|
104
|
+
|
|
105
|
+
| Alternative | Pros | Cons | Verdict |
|
|
106
|
+
|---|---|---|---|
|
|
107
|
+
| A. Unified `HeaderInside` + `routeLayoutMapping` | Consistent with sibling pages; fixes flicker and position | Requires subtitle adjustment below the header | **Accepted** |
|
|
108
|
+
| B. Keep custom header and only adjust padding | Minimal diff | Still diverges from `HeaderInside` typography/responsiveness; does not fix flicker alone | Rejected |
|
|
109
|
+
| C. Server-side pagination | Supports large lists | Unnecessary — maximum of 20 assortments per contract | Rejected |
|
|
110
|
+
| D. Remove subtitle to match Profile | Less markup | Loses useful context for the user; subtitle is a product requirement | Rejected |
|
|
111
|
+
|
|
112
|
+
### Risks & Mitigations
|
|
113
|
+
|
|
114
|
+
| Risk | Impact | Likelihood | Mitigation |
|
|
115
|
+
|---|---|---|---|
|
|
116
|
+
| Legacy Cypress tests fail | Med | High | Update only title and navigation label expectations; leave legacy drawer/filter scenarios unchanged |
|
|
117
|
+
| Contract assortment limit increases in the future | Low | Low | Re-evaluate pagination if the business limit changes |
|
|
118
|
+
|
|
119
|
+
### Key Decisions
|
|
120
|
+
|
|
121
|
+
#### Decision 1: Unify title via `routeLayoutMapping` + `HeaderInside`
|
|
122
|
+
|
|
123
|
+
- **Status**: Accepted
|
|
124
|
+
- **Context**: Loading and loaded states use different title mechanisms.
|
|
125
|
+
- **Decision**: Change `pageTitle` to `"Assortments"` and migrate the loaded layout to `HeaderInside title="Assortments"`.
|
|
126
|
+
- **Consequences**: `LoadingTabsLayout`, `ErrorTabsLayout`, and the loaded page all display the same title. Removes the custom `[data-fs-bp-assortments-title]`.
|
|
127
|
+
|
|
128
|
+
#### Decision 2: No pagination
|
|
129
|
+
|
|
130
|
+
- **Status**: Accepted
|
|
131
|
+
- **Context**: Contracts support at most 20 assortments; the API returns all of them in a single response.
|
|
132
|
+
- **Decision**: Do not implement pagination, `useUrlPaginatedSearch`, or a `page` query param.
|
|
133
|
+
- **Consequences**: Simpler layout; single fetch via `useGetProductAssortment` without lazy/router sync.
|
|
134
|
+
|
|
135
|
+
#### Decision 3: Keep subtitle as a separate element
|
|
136
|
+
|
|
137
|
+
- **Status**: Accepted
|
|
138
|
+
- **Context**: No sibling page has a subtitle, but Assortments needs explanatory text.
|
|
139
|
+
- **Decision**: Render `<p data-fs-bp-assortments-subtitle>` immediately below `HeaderInside`, keeping existing scoped styles.
|
|
140
|
+
- **Consequences**: Title position aligns with sibling pages; subtitle sits below without affecting the `h1` offset.
|
|
141
|
+
|
|
142
|
+
### Implementation Plan
|
|
143
|
+
|
|
144
|
+
1. **Consistent title**
|
|
145
|
+
- Edit `src/features/shared/utils/routeLayoutMapping.ts`: `pageTitle: "Assortments"`.
|
|
146
|
+
|
|
147
|
+
2. **Aligned header**
|
|
148
|
+
- Refactor `ProductAssortmentLayout.tsx`:
|
|
149
|
+
- Import and use `HeaderInside title="Assortments"`.
|
|
150
|
+
- Remove `div[data-fs-bp-assortments-header]` and the custom `h1`.
|
|
151
|
+
- Keep the subtitle below the header.
|
|
152
|
+
- Remove obsolete `[data-fs-bp-assortments-title]` and header styles from `product-assortment-layout.scss`; preserve subtitle styles.
|
|
153
|
+
|
|
154
|
+
3. **Tests**
|
|
155
|
+
- Update `cypress/integration/product-assortment.test.ts` only where the title or navigation label changed to "Assortments".
|
|
156
|
+
|
|
157
|
+
4. **Verification**
|
|
158
|
+
- Run `make check`.
|
|
159
|
+
- Manual test against a linked host store: navigate to Assortments, confirm stable title, visual alignment vs Addresses, and full assortment listing.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 3. Technical Contract
|
|
164
|
+
|
|
165
|
+
### Data Models
|
|
166
|
+
|
|
167
|
+
No changes to existing types in `src/features/product-assortment/types/index.ts`. The API response may include `paging`, but the frontend does not consume pagination in this scope.
|
|
168
|
+
|
|
169
|
+
### Interfaces
|
|
170
|
+
|
|
171
|
+
#### API — GET assortments (consumed by the plugin)
|
|
172
|
+
|
|
173
|
+
| Field | Type | Notes |
|
|
174
|
+
|---|---|---|
|
|
175
|
+
| Path | `GET /customers/{contractId}/units/{unitId}/assortments/available` | Existing |
|
|
176
|
+
| Query `name` | `string` (optional) | Existing, out of scope |
|
|
177
|
+
| Response `items[]` | `{ id, name, enabled }` | Rendered in full (up to 20) |
|
|
178
|
+
|
|
179
|
+
#### `useGetProductAssortment`
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
useGetProductAssortment({
|
|
183
|
+
contractId: string;
|
|
184
|
+
orgUnitId: string;
|
|
185
|
+
search?: string;
|
|
186
|
+
options?: QueryOptions<...>;
|
|
187
|
+
})
|
|
188
|
+
// Returns: { data: { items, paging }, isProductAssortmentLoading, ... }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Single fetch on mount — no `page`, no `lazy`, no URL sync.
|
|
192
|
+
|
|
193
|
+
#### Component boundaries
|
|
194
|
+
|
|
195
|
+
| Module | Responsibility |
|
|
196
|
+
|---|---|
|
|
197
|
+
| `routeLayoutMapping.ts` | Loading/error title: `"Assortments"` |
|
|
198
|
+
| `ProductAssortmentLayout` | Header, data fetch, empty state |
|
|
199
|
+
| `ProductAssortmentTable` | Table rendering + radio selection |
|
|
200
|
+
| `useSetAssortment` | PUT selection (unchanged) |
|
|
201
|
+
|
|
202
|
+
### Integration Points
|
|
203
|
+
|
|
204
|
+
- **LoadingTabsLayout / ErrorTabsLayout** — read `pageTitle` via `getTabsLayoutConfigFromRoute`; fixed indirectly by the `routeLayoutMapping` change.
|
|
205
|
+
- **BFF/API** — `assortments/available` endpoint returns all contract assortments (max. 20).
|
|
206
|
+
- **Host store** — no changes to `plugin.config.js` (route already registered).
|
|
207
|
+
|
|
208
|
+
### Invariants & Constraints
|
|
209
|
+
|
|
210
|
+
- The sidebar menu continues to display **"Assortments"** (`getContractSettingsLinks.ts` — already correct).
|
|
211
|
+
- The loaded, loading, and error page title must always be **"Assortments"**.
|
|
212
|
+
- The assortment with `enabled: true` remains selected via radio; the API is responsible for placing it at the top when applicable.
|
|
213
|
+
- No new cross-domain dependencies — only `shared` (`HeaderInside`).
|
|
214
|
+
|
|
215
|
+
### Files to Change
|
|
216
|
+
|
|
217
|
+
| File | Change |
|
|
218
|
+
|---|---|
|
|
219
|
+
| `src/features/shared/utils/routeLayoutMapping.ts` | `pageTitle` → `"Assortments"` |
|
|
220
|
+
| `src/features/product-assortment/layouts/ProductAssortmentLayout/ProductAssortmentLayout.tsx` | `HeaderInside`, simple fetch |
|
|
221
|
+
| `src/features/product-assortment/layouts/ProductAssortmentLayout/product-assortment-layout.scss` | Remove custom title styles; keep subtitle |
|
|
222
|
+
| `cypress/integration/product-assortment.test.ts` | Update title and navigation label to "Assortments" |
|