@vtex/faststore-plugin-buyer-portal 2.0.12 → 2.0.13
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 +9 -1
- package/package.json +1 -1
- package/src/features/accounting-fields/components/CreateAccountingValueDrawer/CreateAccountingValueDrawer.tsx +1 -0
- package/src/features/accounting-fields/hooks/useDetailsAccountingField.ts +5 -4
- package/src/features/accounting-fields/hooks/useDetailsAccountingValue.ts +5 -4
- package/src/features/accounting-fields/hooks/useListAccountingFields.ts +4 -4
- package/src/features/accounting-fields/hooks/useListAccountingValues.ts +5 -3
- package/src/features/accounting-fields/layouts/AccountingFieldLayout/AccountingFieldLayout.tsx +1 -0
- package/src/features/budgets/components/CreateBudgetAllocationDrawer/CreateBudgetAllocationDrawer.tsx +1 -1
- package/src/features/budgets/components/CreateBudgetDrawer/CreateBudgetDrawer.tsx +1 -1
- package/src/features/budgets/hooks/useGetAllocations.ts +1 -0
- package/src/features/buying-policies/components/AccountingFieldCriteriaSelector/AccountingFieldCriteriaSelector.tsx +5 -2
- package/src/features/buying-policies/components/AccountingFieldCriteriaSelector/AccountingValueCriteriaSelector.tsx +7 -2
- package/src/features/buying-policies/layouts/BuyingPolicyDetailsLayout/BuyingPolicyDetailsLayout.tsx +2 -0
- package/src/features/contracts/layouts/ContractListingLayout/ContractListingLayout.tsx +9 -3
- package/src/features/contracts/layouts/ContractListingLayout/__tests__/utils.test.ts +40 -0
- package/src/features/contracts/layouts/ContractListingLayout/utils.ts +13 -0
- package/src/features/org-units/components/CreateOrgUnitDrawer/CreateOrgUnitDrawer.tsx +9 -1
- package/src/features/org-units/components/DeleteOrgUnitDrawer/DeleteOrgUnitDrawer.tsx +8 -1
- package/src/features/org-units/components/OrgUnitBreadcrumb/OrgUnitBreadcrumb.tsx +13 -3
- package/src/features/org-units/components/OrgUnitsHierarchyTree/OrgUnitsHierarchyTree.tsx +14 -1
- package/src/features/org-units/components/UpdateOrgUnitDrawer/UpdateOrgUnitDrawer.tsx +9 -1
- package/src/features/org-units/layouts/OrgUnitDetailsLayout/OrgUnitDetailsLayout.tsx +4 -1
- package/src/features/shared/layouts/SumaPageLayout/FullSidebarNav.tsx +1 -1
- package/src/features/shared/utils/buyerPortalRoutes.ts +14 -4
- package/src/features/shared/utils/constants.ts +1 -1
- package/src/pages/org-unit-details.tsx +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.13] - 2026-07-21
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Navigating between organizational units (hierarchy tree, breadcrumbs, and the "View" links after creating/editing/deleting a unit) now carries the currently viewed contract's id through, instead of dropping it — this previously caused the `suma`-flag redirect on `/org-unit/[orgUnitId]` to land on the target org unit's default contract instead of the one being viewed. The Contract Listing page now also honors a `contractId` carried in the URL when it belongs to the org unit's attached contracts, falling back to the org unit's default contract otherwise
|
|
15
|
+
- Accounting Fields data (sidebar list, Buying Policy criteria selectors, the Accounting Field details page, and Budget allocation drawers) was fetched using the session's active contract instead of the contract actually being viewed — noticeable when navigating straight to a page for a non-active contract (e.g. from Contract Listing) without first "switching" to it. All accounting-fields read hooks now take an explicit `contractId` instead of silently substituting the session's customerId
|
|
16
|
+
|
|
10
17
|
## [2.0.12] - 2026-07-17
|
|
11
18
|
|
|
12
19
|
### Fixed
|
|
@@ -763,7 +770,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
763
770
|
- Add CHANGELOG file
|
|
764
771
|
- Add README file
|
|
765
772
|
|
|
766
|
-
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v2.0.
|
|
773
|
+
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v2.0.13...HEAD
|
|
767
774
|
[1.3.55]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.54...v1.3.55
|
|
768
775
|
[1.3.54]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.53...v1.3.54
|
|
769
776
|
[1.3.53]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.52...v1.3.53
|
|
@@ -861,5 +868,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
861
868
|
[2.0.10]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v2.0.9...v2.0.10
|
|
862
869
|
[2.0.9]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/2.0.9
|
|
863
870
|
|
|
871
|
+
[2.0.13]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v2.0.12...v2.0.13
|
|
864
872
|
[2.0.12]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v2.0.11...v2.0.12
|
|
865
873
|
[2.0.11]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/2.0.11
|
package/package.json
CHANGED
|
@@ -133,6 +133,7 @@ export const CreateAccountingValueDrawer = ({
|
|
|
133
133
|
const { listAccountingValuesData } = useListAccountingValues({
|
|
134
134
|
accountingFieldId: accountingField.id,
|
|
135
135
|
orgUnitId,
|
|
136
|
+
contractId: contract?.id ?? "",
|
|
136
137
|
page: 1,
|
|
137
138
|
search,
|
|
138
139
|
filterByUnit: false,
|
|
@@ -6,17 +6,18 @@ export const useDetailsAccountingField = (
|
|
|
6
6
|
{
|
|
7
7
|
accountingFieldId,
|
|
8
8
|
orgUnitId,
|
|
9
|
-
|
|
9
|
+
contractId,
|
|
10
|
+
}: Omit<DetailsAccountingFieldParams, "cookie">,
|
|
10
11
|
options?: QueryOptions<AwaitedType<typeof detailsAccoutingFieldService>>
|
|
11
12
|
) => {
|
|
12
13
|
const { data, error, isLoading, refetch } = useQuery(
|
|
13
|
-
`accounting-fields/${accountingFieldId}/details`,
|
|
14
|
-
({ cookie
|
|
14
|
+
`accounting-fields/${accountingFieldId}/details/${contractId}`,
|
|
15
|
+
({ cookie }) =>
|
|
15
16
|
detailsAccoutingFieldService({
|
|
16
17
|
orgUnitId,
|
|
17
18
|
accountingFieldId,
|
|
18
19
|
cookie,
|
|
19
|
-
contractId
|
|
20
|
+
contractId,
|
|
20
21
|
}),
|
|
21
22
|
options
|
|
22
23
|
);
|
|
@@ -8,18 +8,19 @@ export const useDetailsAccountingValue = (
|
|
|
8
8
|
accountingFieldId,
|
|
9
9
|
accountingValueId,
|
|
10
10
|
orgUnitId,
|
|
11
|
-
|
|
11
|
+
contractId,
|
|
12
|
+
}: Omit<DetailsAccountingValueParams, "cookie">,
|
|
12
13
|
options?: QueryOptions<AwaitedType<typeof detailsAccountingValueService>>
|
|
13
14
|
) => {
|
|
14
15
|
const { data, error, isLoading, refetch } = useQuery(
|
|
15
|
-
`accounting-values/${accountingValueId}/details`,
|
|
16
|
-
({ cookie
|
|
16
|
+
`accounting-values/${accountingValueId}/details/${contractId}`,
|
|
17
|
+
({ cookie }) =>
|
|
17
18
|
detailsAccountingValueService({
|
|
18
19
|
orgUnitId,
|
|
19
20
|
accountingFieldId,
|
|
20
21
|
accountingValueId,
|
|
21
22
|
cookie,
|
|
22
|
-
contractId
|
|
23
|
+
contractId,
|
|
23
24
|
}),
|
|
24
25
|
options
|
|
25
26
|
);
|
|
@@ -3,14 +3,14 @@ import { listAccountingFielsdService } from "../services";
|
|
|
3
3
|
import { AccountingFieldsParams } from "../types";
|
|
4
4
|
|
|
5
5
|
export const useListAccountingFields = (
|
|
6
|
-
{ orgUnitId }: Omit<AccountingFieldsParams, "cookie"
|
|
6
|
+
{ orgUnitId, contractId }: Omit<AccountingFieldsParams, "cookie">,
|
|
7
7
|
options?: QueryOptions<AwaitedType<typeof listAccountingFielsdService>>
|
|
8
8
|
) => {
|
|
9
9
|
const { data, error, isLoading, refetch } = useQuery(
|
|
10
|
-
["api", "accounting-fields", orgUnitId].join("/"),
|
|
11
|
-
({ cookie
|
|
10
|
+
["api", "accounting-fields", orgUnitId, contractId].join("/"),
|
|
11
|
+
({ cookie }) =>
|
|
12
12
|
listAccountingFielsdService({
|
|
13
|
-
contractId
|
|
13
|
+
contractId,
|
|
14
14
|
orgUnitId,
|
|
15
15
|
cookie,
|
|
16
16
|
}),
|
|
@@ -6,12 +6,13 @@ import type { ListAccountingValuesParams } from "../types";
|
|
|
6
6
|
export const useListAccountingValues = (
|
|
7
7
|
{
|
|
8
8
|
orgUnitId,
|
|
9
|
+
contractId,
|
|
9
10
|
accountingFieldId,
|
|
10
11
|
page,
|
|
11
12
|
search,
|
|
12
13
|
budgetId,
|
|
13
14
|
filterByUnit,
|
|
14
|
-
}: Omit<ListAccountingValuesParams, "cookie"
|
|
15
|
+
}: Omit<ListAccountingValuesParams, "cookie">,
|
|
15
16
|
options?: QueryOptions<AwaitedType<typeof listAccountingValuesdService>>,
|
|
16
17
|
key?: string
|
|
17
18
|
) => {
|
|
@@ -21,13 +22,14 @@ export const useListAccountingValues = (
|
|
|
21
22
|
"api",
|
|
22
23
|
"accounting-field-values",
|
|
23
24
|
orgUnitId,
|
|
25
|
+
contractId,
|
|
24
26
|
accountingFieldId,
|
|
25
27
|
`page=${page}`,
|
|
26
28
|
`search=${search}`,
|
|
27
29
|
].join("/"),
|
|
28
|
-
({ cookie
|
|
30
|
+
({ cookie }) =>
|
|
29
31
|
listAccountingValuesdService({
|
|
30
|
-
contractId
|
|
32
|
+
contractId,
|
|
31
33
|
cookie,
|
|
32
34
|
orgUnitId,
|
|
33
35
|
accountingFieldId,
|
|
@@ -42,7 +42,7 @@ export const CreateBudgetAllocationDrawer = ({
|
|
|
42
42
|
const { pushToast } = useUI();
|
|
43
43
|
|
|
44
44
|
const { listAccountingFieldData, listAccountingFieldLoading } =
|
|
45
|
-
useListAccountingFields({ orgUnitId });
|
|
45
|
+
useListAccountingFields({ orgUnitId, contractId });
|
|
46
46
|
|
|
47
47
|
const dynamicSortingOptions = useMemo<Dictionary<string>>(() => {
|
|
48
48
|
const accountingFieldsOptions =
|
|
@@ -92,7 +92,7 @@ export const CreateBudgetDrawer = ({
|
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
const { listAccountingFieldData, listAccountingFieldLoading } =
|
|
95
|
-
useListAccountingFields({ orgUnitId: unitId });
|
|
95
|
+
useListAccountingFields({ orgUnitId: unitId, contractId });
|
|
96
96
|
|
|
97
97
|
const dynamicSortingOptions = useMemo<Dictionary<string>>(() => {
|
|
98
98
|
const accountingFieldsOptions =
|
|
@@ -29,10 +29,13 @@ export const AccountingFieldCriteriaSelector = ({
|
|
|
29
29
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
30
30
|
|
|
31
31
|
const { pushToast } = useUI();
|
|
32
|
-
const { currentOrgUnit } = useBuyerPortal();
|
|
32
|
+
const { currentOrgUnit, currentContract } = useBuyerPortal();
|
|
33
33
|
const { listAccountingFieldData, listAccountingFieldLoading } =
|
|
34
34
|
useListAccountingFields(
|
|
35
|
-
{
|
|
35
|
+
{
|
|
36
|
+
orgUnitId: currentOrgUnit?.id ?? "",
|
|
37
|
+
contractId: currentContract?.id ?? "",
|
|
38
|
+
},
|
|
36
39
|
{
|
|
37
40
|
onError: () => {
|
|
38
41
|
pushToast({
|
|
@@ -44,10 +44,13 @@ export const AccountingValueCriteriaSelector = ({
|
|
|
44
44
|
|
|
45
45
|
const debouncedSearch = useDebounce(search, 300);
|
|
46
46
|
const { pushToast } = useUI();
|
|
47
|
-
const { currentOrgUnit } = useBuyerPortal();
|
|
47
|
+
const { currentOrgUnit, currentContract } = useBuyerPortal();
|
|
48
48
|
const { listAccountingFieldData, listAccountingFieldLoading } =
|
|
49
49
|
useListAccountingFields(
|
|
50
|
-
{
|
|
50
|
+
{
|
|
51
|
+
orgUnitId: currentOrgUnit?.id ?? "",
|
|
52
|
+
contractId: currentContract?.id ?? "",
|
|
53
|
+
},
|
|
51
54
|
{
|
|
52
55
|
onError: () => {
|
|
53
56
|
pushToast({
|
|
@@ -66,6 +69,7 @@ export const AccountingValueCriteriaSelector = ({
|
|
|
66
69
|
{
|
|
67
70
|
accountingFieldId: fieldId ?? "",
|
|
68
71
|
orgUnitId: currentOrgUnit?.id ?? "",
|
|
72
|
+
contractId: currentContract?.id ?? "",
|
|
69
73
|
search: debouncedSearch,
|
|
70
74
|
},
|
|
71
75
|
{
|
|
@@ -85,6 +89,7 @@ export const AccountingValueCriteriaSelector = ({
|
|
|
85
89
|
accountingFieldId: initialFieldIdRef.current,
|
|
86
90
|
accountingValueId: initialValueIdRef.current,
|
|
87
91
|
orgUnitId: currentOrgUnit?.id ?? "",
|
|
92
|
+
contractId: currentContract?.id ?? "",
|
|
88
93
|
},
|
|
89
94
|
{
|
|
90
95
|
lazy:
|
package/src/features/buying-policies/layouts/BuyingPolicyDetailsLayout/BuyingPolicyDetailsLayout.tsx
CHANGED
|
@@ -43,6 +43,7 @@ export const BuyingPolicyDetailsLayout = ({
|
|
|
43
43
|
{
|
|
44
44
|
accountingFieldId,
|
|
45
45
|
orgUnitId: currentOrgUnit?.id ?? "",
|
|
46
|
+
contractId: currentContract?.id ?? "",
|
|
46
47
|
},
|
|
47
48
|
{
|
|
48
49
|
lazy: !accountFieldCriteria,
|
|
@@ -55,6 +56,7 @@ export const BuyingPolicyDetailsLayout = ({
|
|
|
55
56
|
accountingFieldId,
|
|
56
57
|
accountingValueId,
|
|
57
58
|
orgUnitId: currentOrgUnit?.id ?? "",
|
|
59
|
+
contractId: currentContract?.id ?? "",
|
|
58
60
|
},
|
|
59
61
|
{
|
|
60
62
|
lazy: !accountFieldCriteria || !accountingValueId,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
} from "../../hooks";
|
|
40
40
|
|
|
41
41
|
import { buildContractSettingsNavItems } from "./ContractSettingsNav";
|
|
42
|
-
import { getDefaultContractId } from "./utils";
|
|
42
|
+
import { getDefaultContractId, resolveViewedContractId } from "./utils";
|
|
43
43
|
|
|
44
44
|
import type { OrgUnitBasicData } from "../../../org-units/types";
|
|
45
45
|
import type { UserData } from "../../../users/types";
|
|
@@ -77,7 +77,10 @@ export const ContractListingLayout = ({
|
|
|
77
77
|
const { pushToast } = useUI();
|
|
78
78
|
const { subscribe } = useContractSwitchChannel();
|
|
79
79
|
|
|
80
|
-
const
|
|
80
|
+
const queryContractId = Array.isArray(router.query.contractId)
|
|
81
|
+
? router.query.contractId[0]
|
|
82
|
+
: router.query.contractId;
|
|
83
|
+
const defaultContractId = resolveViewedContractId(contracts, queryContractId);
|
|
81
84
|
const singleContract = contracts[0];
|
|
82
85
|
const displayName =
|
|
83
86
|
singleContract?.name ?? singleContract?.email ?? orgUnit.name;
|
|
@@ -86,7 +89,10 @@ export const ContractListingLayout = ({
|
|
|
86
89
|
listAccountingFieldData,
|
|
87
90
|
listAccountingFieldLoading,
|
|
88
91
|
listAccountingFieldRefresh,
|
|
89
|
-
} = useListAccountingFields({
|
|
92
|
+
} = useListAccountingFields({
|
|
93
|
+
orgUnitId: orgUnit.id,
|
|
94
|
+
contractId: defaultContractId,
|
|
95
|
+
});
|
|
90
96
|
|
|
91
97
|
const {
|
|
92
98
|
open: openAccountingFieldDrawer,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { getDefaultContractId, resolveViewedContractId } from "../utils";
|
|
4
|
+
|
|
5
|
+
import type { ContractData } from "../../../types";
|
|
6
|
+
|
|
7
|
+
const contracts = [
|
|
8
|
+
{ id: "contract-a", isDefault: false },
|
|
9
|
+
{ id: "contract-b", isDefault: true },
|
|
10
|
+
] as ContractData[];
|
|
11
|
+
|
|
12
|
+
describe("getDefaultContractId", () => {
|
|
13
|
+
it("prefers the contract flagged as default", () => {
|
|
14
|
+
expect(getDefaultContractId(contracts)).toBe("contract-b");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("falls back to the first contract when none is flagged as default", () => {
|
|
18
|
+
expect(getDefaultContractId([contracts[0]])).toBe("contract-a");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("returns an empty string when there are no contracts", () => {
|
|
22
|
+
expect(getDefaultContractId([])).toBe("");
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("resolveViewedContractId", () => {
|
|
27
|
+
it("uses the query contractId when it belongs to this org unit's contracts", () => {
|
|
28
|
+
expect(resolveViewedContractId(contracts, "contract-a")).toBe("contract-a");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("falls back to the default contract when the query contractId isn't attached here", () => {
|
|
32
|
+
expect(resolveViewedContractId(contracts, "contract-from-elsewhere")).toBe(
|
|
33
|
+
"contract-b"
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("falls back to the default contract when no query contractId is given", () => {
|
|
38
|
+
expect(resolveViewedContractId(contracts, undefined)).toBe("contract-b");
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -2,3 +2,16 @@ import type { ContractData } from "../../types";
|
|
|
2
2
|
|
|
3
3
|
export const getDefaultContractId = (contracts: ContractData[]) =>
|
|
4
4
|
contracts.find((c) => c.isDefault)?.id ?? contracts[0]?.id ?? "";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Contracts aren't attached uniformly across the org unit hierarchy, so a
|
|
8
|
+
* contractId carried over from another org unit (e.g. via URL) may not apply
|
|
9
|
+
* here — fall back to this org unit's own default contract when that happens.
|
|
10
|
+
*/
|
|
11
|
+
export const resolveViewedContractId = (
|
|
12
|
+
contracts: ContractData[],
|
|
13
|
+
queryContractId?: string
|
|
14
|
+
) =>
|
|
15
|
+
contracts.some((c) => c.id === queryContractId)
|
|
16
|
+
? (queryContractId as string)
|
|
17
|
+
: getDefaultContractId(contracts);
|
|
@@ -12,10 +12,11 @@ import {
|
|
|
12
12
|
InputText,
|
|
13
13
|
Icon,
|
|
14
14
|
} from "../../../shared/components";
|
|
15
|
-
import { useAnalytics } from "../../../shared/hooks";
|
|
15
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
16
16
|
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
17
17
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
18
18
|
import { CHANGES_TIMEOUT_MESSAGE } from "../../../shared/utils/constants";
|
|
19
|
+
import { resolveContractId } from "../../../shared/utils/resolveContractId";
|
|
19
20
|
import { useCreateNewOrgUnit } from "../../hooks";
|
|
20
21
|
|
|
21
22
|
import type { createNewOrgUnitService } from "../../services";
|
|
@@ -37,6 +38,12 @@ export const CreateOrgUnitDrawer = ({
|
|
|
37
38
|
}: CreateOrgUnitDrawerProps) => {
|
|
38
39
|
const { pushToast } = useUI();
|
|
39
40
|
const router = useRouter();
|
|
41
|
+
const { currentContract, currentOrgUnit } = useBuyerPortal();
|
|
42
|
+
const contractId = resolveContractId({
|
|
43
|
+
queryContractId: router.query.contractId,
|
|
44
|
+
currentContract,
|
|
45
|
+
currentOrgUnit,
|
|
46
|
+
});
|
|
40
47
|
const { trackEntityCreated, trackEntityCreateError } = useAnalytics({
|
|
41
48
|
entityType: "org_unit",
|
|
42
49
|
defaultTimerName: "org_unit_creation",
|
|
@@ -70,6 +77,7 @@ export const CreateOrgUnitDrawer = ({
|
|
|
70
77
|
router.push(
|
|
71
78
|
buyerPortalRoutes.orgUnitDetails({
|
|
72
79
|
orgUnitId: data.id,
|
|
80
|
+
contractId,
|
|
73
81
|
})
|
|
74
82
|
)
|
|
75
83
|
}
|
|
@@ -15,6 +15,7 @@ import { useBuyerPortal, useAnalytics } from "../../../shared/hooks";
|
|
|
15
15
|
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
16
16
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
17
17
|
import { CHANGES_TIMEOUT_MESSAGE } from "../../../shared/utils/constants";
|
|
18
|
+
import { resolveContractId } from "../../../shared/utils/resolveContractId";
|
|
18
19
|
import { useGetUserByOrgUnitId } from "../../../users/hooks/useGetUserByOrgUnitId";
|
|
19
20
|
import { useChildrenOrgUnits } from "../../hooks";
|
|
20
21
|
import { useDeleteOrgUnit } from "../../hooks/useDeleteOrgUnit";
|
|
@@ -34,7 +35,12 @@ export const DeleteOrgUnitDrawer = ({
|
|
|
34
35
|
...props
|
|
35
36
|
}: DeleteOrgUnitDrawerProps) => {
|
|
36
37
|
const router = useRouter();
|
|
37
|
-
const { currentOrgUnit } = useBuyerPortal();
|
|
38
|
+
const { currentOrgUnit, currentContract } = useBuyerPortal();
|
|
39
|
+
const contractId = resolveContractId({
|
|
40
|
+
queryContractId: router.query.contractId,
|
|
41
|
+
currentContract,
|
|
42
|
+
currentOrgUnit,
|
|
43
|
+
});
|
|
38
44
|
const { childrenOrgUnits } = useChildrenOrgUnits(id, name);
|
|
39
45
|
const { users } = useGetUserByOrgUnitId(id);
|
|
40
46
|
const { pushToast } = useUI();
|
|
@@ -80,6 +86,7 @@ export const DeleteOrgUnitDrawer = ({
|
|
|
80
86
|
const parentId = ids[ids.length - 2];
|
|
81
87
|
const redirectUrl = buyerPortalRoutes.orgUnitDetails({
|
|
82
88
|
orgUnitId: parentId,
|
|
89
|
+
contractId,
|
|
83
90
|
});
|
|
84
91
|
router.replace(redirectUrl);
|
|
85
92
|
} else {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { useRouter } from "next/router";
|
|
2
|
+
|
|
1
3
|
import { Icon } from "../../../shared/components";
|
|
2
4
|
import { useBuyerPortal } from "../../../shared/hooks";
|
|
3
5
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
6
|
+
import { resolveContractId } from "../../../shared/utils/resolveContractId";
|
|
4
7
|
import { USER_ROLES } from "../../../users/types";
|
|
5
8
|
import { useOrgUnitByUser } from "../../hooks";
|
|
6
9
|
|
|
@@ -19,8 +22,15 @@ export const OrgUnitBreadcrumb = ({
|
|
|
19
22
|
userId,
|
|
20
23
|
userRoles,
|
|
21
24
|
}: OrgUnitBreadcrumbProps) => {
|
|
22
|
-
const { currentContract } = useBuyerPortal();
|
|
25
|
+
const { currentContract, currentOrgUnit } = useBuyerPortal();
|
|
23
26
|
const { orgUnit: userUnit } = useOrgUnitByUser(userId);
|
|
27
|
+
const router = useRouter();
|
|
28
|
+
|
|
29
|
+
const contractId = resolveContractId({
|
|
30
|
+
queryContractId: router.query.contractId,
|
|
31
|
+
currentContract,
|
|
32
|
+
currentOrgUnit,
|
|
33
|
+
});
|
|
24
34
|
|
|
25
35
|
const orgUnitList = orgUnit?.path.ids.split("/").slice(1) ?? [];
|
|
26
36
|
|
|
@@ -36,7 +46,7 @@ export const OrgUnitBreadcrumb = ({
|
|
|
36
46
|
) {
|
|
37
47
|
acc.push({
|
|
38
48
|
unitId: orgUnitId,
|
|
39
|
-
item: buyerPortalRoutes.orgUnitDetails({ orgUnitId }),
|
|
49
|
+
item: buyerPortalRoutes.orgUnitDetails({ orgUnitId, contractId }),
|
|
40
50
|
name: orgUnit?.path.names.split("/")[index] ?? "",
|
|
41
51
|
position: index + 1,
|
|
42
52
|
enabled: true,
|
|
@@ -68,7 +78,7 @@ export const OrgUnitBreadcrumb = ({
|
|
|
68
78
|
{Boolean(inBreadcrumb.length) && divider}
|
|
69
79
|
|
|
70
80
|
<OrgUnitBreadcrumbPath
|
|
71
|
-
contractId={
|
|
81
|
+
contractId={contractId}
|
|
72
82
|
items={sortedByPosition.slice(offset)}
|
|
73
83
|
divider={divider}
|
|
74
84
|
hasDropdown={hasDropdown}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Link from "next/link";
|
|
2
|
+
import { useRouter } from "next/router";
|
|
2
3
|
|
|
3
4
|
import { Dropdown } from "@faststore/ui";
|
|
4
5
|
|
|
@@ -8,7 +9,9 @@ import {
|
|
|
8
9
|
HierarchyTree,
|
|
9
10
|
Icon,
|
|
10
11
|
} from "../../../shared/components";
|
|
12
|
+
import { useBuyerPortal } from "../../../shared/hooks";
|
|
11
13
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
14
|
+
import { resolveContractId } from "../../../shared/utils/resolveContractId";
|
|
12
15
|
import { useChildrenOrgUnits, useOrgUnitStructure } from "../../hooks";
|
|
13
16
|
|
|
14
17
|
import type { OrgUnitHierarchyData } from "../../types";
|
|
@@ -25,6 +28,13 @@ export const OrgUnitsHierarchyTree = ({
|
|
|
25
28
|
enableChildren = true,
|
|
26
29
|
}: OrgUnitsHierarchyTreeProps) => {
|
|
27
30
|
const { structure, setNode } = useOrgUnitStructure(orgUnitHierarchyData);
|
|
31
|
+
const router = useRouter();
|
|
32
|
+
const { currentContract, currentOrgUnit } = useBuyerPortal();
|
|
33
|
+
const contractId = resolveContractId({
|
|
34
|
+
queryContractId: router.query.contractId,
|
|
35
|
+
currentContract,
|
|
36
|
+
currentOrgUnit,
|
|
37
|
+
});
|
|
28
38
|
|
|
29
39
|
return (
|
|
30
40
|
<HierarchyTree
|
|
@@ -48,7 +58,10 @@ export const OrgUnitsHierarchyTree = ({
|
|
|
48
58
|
{!readonly && (
|
|
49
59
|
<Link
|
|
50
60
|
data-fs-org-unit-item-click-area
|
|
51
|
-
href={buyerPortalRoutes.orgUnitDetails({
|
|
61
|
+
href={buyerPortalRoutes.orgUnitDetails({
|
|
62
|
+
orgUnitId: id,
|
|
63
|
+
contractId,
|
|
64
|
+
})}
|
|
52
65
|
/>
|
|
53
66
|
)}
|
|
54
67
|
{enableChildren && (
|
|
@@ -10,10 +10,11 @@ import {
|
|
|
10
10
|
ErrorMessage,
|
|
11
11
|
InputText,
|
|
12
12
|
} from "../../../shared/components";
|
|
13
|
-
import { useAnalytics } from "../../../shared/hooks";
|
|
13
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
14
14
|
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
15
15
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
16
16
|
import { CHANGES_TIMEOUT_MESSAGE } from "../../../shared/utils/constants";
|
|
17
|
+
import { resolveContractId } from "../../../shared/utils/resolveContractId";
|
|
17
18
|
import { useUpdateOrgUnit } from "../../hooks";
|
|
18
19
|
|
|
19
20
|
export type UpdateOrgUnitDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
@@ -33,6 +34,12 @@ export const UpdateOrgUnitDrawer = ({
|
|
|
33
34
|
}: UpdateOrgUnitDrawerProps) => {
|
|
34
35
|
const router = useRouter();
|
|
35
36
|
const { pushToast } = useUI();
|
|
37
|
+
const { currentContract, currentOrgUnit } = useBuyerPortal();
|
|
38
|
+
const contractId = resolveContractId({
|
|
39
|
+
queryContractId: router.query.contractId,
|
|
40
|
+
currentContract,
|
|
41
|
+
currentOrgUnit,
|
|
42
|
+
});
|
|
36
43
|
const { trackEntityEdited, trackEntityEditError } = useAnalytics({
|
|
37
44
|
entityType: "org_unit",
|
|
38
45
|
entityId: id,
|
|
@@ -61,6 +68,7 @@ export const UpdateOrgUnitDrawer = ({
|
|
|
61
68
|
router.push(
|
|
62
69
|
buyerPortalRoutes.orgUnitDetails({
|
|
63
70
|
orgUnitId: id,
|
|
71
|
+
contractId,
|
|
64
72
|
})
|
|
65
73
|
)
|
|
66
74
|
}
|
|
@@ -102,7 +102,10 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
102
102
|
listAccountingFieldData,
|
|
103
103
|
listAccountingFieldLoading,
|
|
104
104
|
listAccountingFieldRefresh,
|
|
105
|
-
} = useListAccountingFields({
|
|
105
|
+
} = useListAccountingFields({
|
|
106
|
+
orgUnitId: orgUnit.id,
|
|
107
|
+
contractId: linkParams.contractId,
|
|
108
|
+
});
|
|
106
109
|
|
|
107
110
|
const organizationMenu = getOrganizationSettingsLinks({
|
|
108
111
|
orgUnitId: orgUnit.id,
|
|
@@ -105,8 +105,13 @@ export const buyerPortalRoutes = {
|
|
|
105
105
|
userDetails: (params: { orgUnitId: string; userId: string }) =>
|
|
106
106
|
replaceParams(`${base}/user/[orgUnitId]/[userId]`, params),
|
|
107
107
|
|
|
108
|
-
orgUnitDetails: (params: { orgUnitId: string }) =>
|
|
109
|
-
|
|
108
|
+
orgUnitDetails: (params: { orgUnitId: string; contractId?: string }) =>
|
|
109
|
+
appendContractIdParam(
|
|
110
|
+
replaceParams(`${base}/org-unit/[orgUnitId]`, {
|
|
111
|
+
orgUnitId: params.orgUnitId,
|
|
112
|
+
}),
|
|
113
|
+
params.contractId
|
|
114
|
+
),
|
|
110
115
|
|
|
111
116
|
accountingFields: (params: {
|
|
112
117
|
orgUnitId: string;
|
|
@@ -118,8 +123,13 @@ export const buyerPortalRoutes = {
|
|
|
118
123
|
params
|
|
119
124
|
),
|
|
120
125
|
|
|
121
|
-
contracts: (params: { orgUnitId: string }) =>
|
|
122
|
-
|
|
126
|
+
contracts: (params: { orgUnitId: string; contractId?: string }) =>
|
|
127
|
+
appendContractIdParam(
|
|
128
|
+
replaceParams(`${base}/contracts/[orgUnitId]`, {
|
|
129
|
+
orgUnitId: params.orgUnitId,
|
|
130
|
+
}),
|
|
131
|
+
params.contractId
|
|
132
|
+
),
|
|
123
133
|
|
|
124
134
|
contractInformation: (params: { orgUnitId: string; contractId: string }) =>
|
|
125
135
|
replaceParams(
|
|
@@ -22,7 +22,7 @@ export const SCOPE_KEYS = {
|
|
|
22
22
|
CREDIT_CARDS: "creditCards",
|
|
23
23
|
} as const;
|
|
24
24
|
|
|
25
|
-
export const CURRENT_VERSION = "2.0.
|
|
25
|
+
export const CURRENT_VERSION = "2.0.13";
|
|
26
26
|
|
|
27
27
|
export const CHANGES_TIMEOUT_MESSAGE =
|
|
28
28
|
"Changes may take up to 10 minutes to apply.";
|
|
@@ -51,12 +51,13 @@ export type OrgUnitDetailsPageData = {
|
|
|
51
51
|
|
|
52
52
|
type OrgUnitDetailsPageQuery = {
|
|
53
53
|
orgUnitId: string;
|
|
54
|
+
contractId?: string;
|
|
54
55
|
};
|
|
55
56
|
|
|
56
57
|
const loaderFunction = async (
|
|
57
58
|
data: LoaderData<OrgUnitDetailsPageQuery>
|
|
58
59
|
): Promise<AuthRouteProps<OrgUnitDetailsPageData>> => {
|
|
59
|
-
const { orgUnitId } = data.query;
|
|
60
|
+
const { orgUnitId, contractId } = data.query;
|
|
60
61
|
|
|
61
62
|
if (!orgUnitId) {
|
|
62
63
|
throw new Error(`Missing required query param: orgUnitId=${orgUnitId}`);
|
|
@@ -66,7 +67,7 @@ const loaderFunction = async (
|
|
|
66
67
|
const featureFlags = await getBuyerPortalFeatureFlags(cookie);
|
|
67
68
|
|
|
68
69
|
if (featureFlags?.suma) {
|
|
69
|
-
const location = buyerPortalRoutes.contracts({ orgUnitId });
|
|
70
|
+
const location = buyerPortalRoutes.contracts({ orgUnitId, contractId });
|
|
70
71
|
|
|
71
72
|
data.res?.writeHead(302, { Location: location });
|
|
72
73
|
data.res?.end();
|