@vtex/faststore-plugin-buyer-portal 2.0.19 → 2.0.21
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 +14 -1
- package/docs/i18n/locales.json +39 -0
- package/docs/i18n/migration-inventory.md +78 -0
- package/package.json +1 -1
- package/specs/analytics-actor-type.md +243 -0
- package/src/features/contracts/components/AddContractsDrawer/AddContractsDrawer.tsx +28 -15
- package/src/features/contracts/components/ConfirmRemoveDrawer/ConfirmRemoveDrawer.tsx +15 -12
- package/src/features/contracts/components/ContractListItem/ContractListItem.tsx +6 -4
- package/src/features/contracts/components/ContractSelectAllRow/ContractSelectAllRow.tsx +5 -1
- package/src/features/contracts/components/ContractSelectionBar/ContractSelectionBar.tsx +5 -2
- package/src/features/contracts/components/ContractSelectionList/ContractSelectionList.tsx +4 -1
- package/src/features/contracts/components/ContractSwitchOverlay/ContractSwitchOverlay.tsx +5 -2
- package/src/features/contracts/components/ContractsListHeader/ContractsListHeader.tsx +4 -1
- package/src/features/contracts/components/ErrorRemoveDrawer/ErrorRemoveDrawer.tsx +12 -15
- package/src/features/contracts/components/UnableToRemoveContractsDrawer/UnableToRemoveContractsDrawer.tsx +11 -8
- package/src/features/contracts/layouts/ContractInformationLayout/ContractInformationLayout.tsx +27 -20
- package/src/features/contracts/layouts/ContractListingLayout/ContractListingLayout.tsx +28 -26
- package/src/features/contracts/layouts/ContractListingLayout/ContractSettingsNav.tsx +9 -6
- package/src/features/shared/hooks/analytics/useAnalytics.ts +1 -1
- package/src/features/shared/services/logger/analytics/__tests__/deriveActorType.test.ts +30 -0
- package/src/features/shared/services/logger/analytics/__tests__/mergeActorTypeIntoEvent.test.ts +83 -0
- package/src/features/shared/services/logger/analytics/analytics.ts +2 -24
- package/src/features/shared/services/logger/analytics/deriveActorType.ts +24 -0
- package/src/features/shared/services/logger/analytics/mergeActorTypeIntoEvent.ts +29 -0
- package/src/features/shared/services/logger/analytics/types.ts +5 -0
- package/src/features/shared/services/logger/analytics/useDataIngestionApi.ts +32 -0
- package/src/features/shared/utils/constants.ts +1 -1
- package/src/features/users/components/RolesMultiSelect/RolesMultiSelect.tsx +9 -10
|
@@ -2,6 +2,7 @@ import { Dropdown, DropdownItem, useUI } from "@faststore/ui";
|
|
|
2
2
|
|
|
3
3
|
import { BasicDropdownMenu, LetterHighlight } from "../../../shared/components";
|
|
4
4
|
import Icon from "../../../shared/components/Icon/Icon";
|
|
5
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
5
6
|
import { useSwitchContract } from "../../hooks";
|
|
6
7
|
import { ContractSwitchOverlay } from "../ContractSwitchOverlay/ContractSwitchOverlay";
|
|
7
8
|
|
|
@@ -24,6 +25,7 @@ export const ContractListItem = ({
|
|
|
24
25
|
onRemove,
|
|
25
26
|
onSetDefault,
|
|
26
27
|
}: ContractListItemProps) => {
|
|
28
|
+
const { t } = useLocalization();
|
|
27
29
|
const displayName = contract.name ?? contract.email;
|
|
28
30
|
const { pushToast } = useUI();
|
|
29
31
|
const { switchContract, loading } = useSwitchContract();
|
|
@@ -39,7 +41,7 @@ export const ContractListItem = ({
|
|
|
39
41
|
const switched = await switchContract(contract.id, { orgUnitId });
|
|
40
42
|
if (!switched) {
|
|
41
43
|
pushToast({
|
|
42
|
-
message: "
|
|
44
|
+
message: t("contracts.toasts.switchError"),
|
|
43
45
|
status: "ERROR",
|
|
44
46
|
});
|
|
45
47
|
}
|
|
@@ -92,12 +94,12 @@ export const ContractListItem = ({
|
|
|
92
94
|
{contract.isDefault ? (
|
|
93
95
|
<DropdownItem disabled>
|
|
94
96
|
<Icon name="Star" width={16} height={16} />
|
|
95
|
-
|
|
97
|
+
{t("contracts.actions.setAsDefault")}
|
|
96
98
|
</DropdownItem>
|
|
97
99
|
) : (
|
|
98
100
|
<DropdownItem onClick={onSetDefault}>
|
|
99
101
|
<Icon name="StarOutline" width={16} height={16} />
|
|
100
|
-
|
|
102
|
+
{t("contracts.actions.setAsDefault")}
|
|
101
103
|
</DropdownItem>
|
|
102
104
|
)}
|
|
103
105
|
<BasicDropdownMenu.Separator />
|
|
@@ -106,7 +108,7 @@ export const ContractListItem = ({
|
|
|
106
108
|
onClick={onRemove}
|
|
107
109
|
>
|
|
108
110
|
<Icon name="CircleRemove" width={16} height={16} />
|
|
109
|
-
|
|
111
|
+
{t("shared.buttons.remove")}
|
|
110
112
|
</DropdownItem>
|
|
111
113
|
</BasicDropdownMenu>
|
|
112
114
|
</Dropdown>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Icon from "../../../shared/components/Icon/Icon";
|
|
2
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
2
3
|
|
|
3
4
|
export type ContractSelectAllRowProps = {
|
|
4
5
|
total: number;
|
|
@@ -11,6 +12,7 @@ export const ContractSelectAllRow = ({
|
|
|
11
12
|
selectedCount,
|
|
12
13
|
onToggle,
|
|
13
14
|
}: ContractSelectAllRowProps) => {
|
|
15
|
+
const { t } = useLocalization();
|
|
14
16
|
const allSelected = total > 0 && selectedCount >= total;
|
|
15
17
|
const indeterminate = selectedCount > 0 && !allSelected;
|
|
16
18
|
|
|
@@ -31,7 +33,9 @@ export const ContractSelectAllRow = ({
|
|
|
31
33
|
>
|
|
32
34
|
{allSelected && <Icon name="Check" width={12} height={12} />}
|
|
33
35
|
</div>
|
|
34
|
-
<span data-fs-bp-contract-select-all-label>
|
|
36
|
+
<span data-fs-bp-contract-select-all-label>
|
|
37
|
+
{t("contracts.labels.selectAllCount", [total])}
|
|
38
|
+
</span>
|
|
35
39
|
</div>
|
|
36
40
|
);
|
|
37
41
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Icon as UIIcon } from "@faststore/ui";
|
|
2
2
|
|
|
3
3
|
import Icon from "../../../shared/components/Icon/Icon";
|
|
4
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
4
5
|
|
|
5
6
|
export type ContractSelectionBarProps = {
|
|
6
7
|
selectedCount: number;
|
|
@@ -15,6 +16,8 @@ export const ContractSelectionBar = ({
|
|
|
15
16
|
onRemove,
|
|
16
17
|
canRemove = true,
|
|
17
18
|
}: ContractSelectionBarProps) => {
|
|
19
|
+
const { t } = useLocalization();
|
|
20
|
+
|
|
18
21
|
if (selectedCount === 0) return null;
|
|
19
22
|
|
|
20
23
|
return (
|
|
@@ -29,7 +32,7 @@ export const ContractSelectionBar = ({
|
|
|
29
32
|
</button>
|
|
30
33
|
|
|
31
34
|
<span data-fs-bp-contract-selection-bar-count>
|
|
32
|
-
{selectedCount}
|
|
35
|
+
{t("contracts.labels.selectedCount", [selectedCount])}
|
|
33
36
|
</span>
|
|
34
37
|
|
|
35
38
|
{canRemove && (
|
|
@@ -39,7 +42,7 @@ export const ContractSelectionBar = ({
|
|
|
39
42
|
onClick={onRemove}
|
|
40
43
|
>
|
|
41
44
|
<Icon name="MinusCircle" width={20} height={20} />
|
|
42
|
-
|
|
45
|
+
{t("shared.buttons.remove")}
|
|
43
46
|
</button>
|
|
44
47
|
)}
|
|
45
48
|
</div>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
1
2
|
import { ContractListItem } from "../ContractListItem/ContractListItem";
|
|
2
3
|
|
|
3
4
|
import type { ContractData } from "../../types";
|
|
@@ -21,10 +22,12 @@ export const ContractSelectionList = ({
|
|
|
21
22
|
onItemRemove,
|
|
22
23
|
onSetDefault,
|
|
23
24
|
}: ContractSelectionListProps) => {
|
|
25
|
+
const { t } = useLocalization();
|
|
26
|
+
|
|
24
27
|
if (contracts.length === 0) {
|
|
25
28
|
return (
|
|
26
29
|
<div data-fs-bp-contract-selection-list-empty>
|
|
27
|
-
<p>
|
|
30
|
+
<p>{t("contracts.listing.emptyState")}</p>
|
|
28
31
|
</div>
|
|
29
32
|
);
|
|
30
33
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ContractTabsLayout } from "../../../shared/layouts/ContractTabsLayout/ContractTabsLayout";
|
|
2
2
|
import { LoadingTabsLayoutContent } from "../../../shared/layouts/LoadingTabsLayout/LoadingTabsLayout";
|
|
3
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
3
4
|
|
|
4
5
|
export type ContractSwitchOverlayProps = {
|
|
5
6
|
orgUnitId: string;
|
|
@@ -19,6 +20,8 @@ export const ContractSwitchOverlay = ({
|
|
|
19
20
|
orgUnitId,
|
|
20
21
|
contractId,
|
|
21
22
|
}: ContractSwitchOverlayProps) => {
|
|
23
|
+
const { t } = useLocalization();
|
|
24
|
+
|
|
22
25
|
return (
|
|
23
26
|
<div data-fs-bp-contract-switch-overlay role="alert" aria-busy="true">
|
|
24
27
|
<ContractTabsLayout
|
|
@@ -26,10 +29,10 @@ export const ContractSwitchOverlay = ({
|
|
|
26
29
|
orgUnitId={orgUnitId}
|
|
27
30
|
contractName=""
|
|
28
31
|
contractId={contractId}
|
|
29
|
-
pageName="
|
|
32
|
+
pageName={t("layouts.tabs.contract")}
|
|
30
33
|
loading
|
|
31
34
|
>
|
|
32
|
-
<LoadingTabsLayoutContent title="
|
|
35
|
+
<LoadingTabsLayoutContent title={t("layouts.titles.profile")} />
|
|
33
36
|
</ContractTabsLayout>
|
|
34
37
|
</div>
|
|
35
38
|
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { InternalSearch } from "../../../shared/components";
|
|
2
2
|
import Icon from "../../../shared/components/Icon/Icon";
|
|
3
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
3
4
|
|
|
4
5
|
export type ContractsListHeaderProps = {
|
|
5
6
|
searchTerm: string;
|
|
@@ -24,6 +25,8 @@ export const ContractsListHeader = ({
|
|
|
24
25
|
onPrev,
|
|
25
26
|
onNext,
|
|
26
27
|
}: ContractsListHeaderProps) => {
|
|
28
|
+
const { t } = useLocalization();
|
|
29
|
+
|
|
27
30
|
return (
|
|
28
31
|
<div data-fs-bp-contracts-list-header>
|
|
29
32
|
<div data-fs-bp-contracts-list-header-search>
|
|
@@ -32,7 +35,7 @@ export const ContractsListHeader = ({
|
|
|
32
35
|
|
|
33
36
|
<div data-fs-bp-contracts-list-header-pagination>
|
|
34
37
|
<span data-fs-bp-contracts-list-header-interval>
|
|
35
|
-
{from
|
|
38
|
+
{t("contracts.listing.interval", [from, to, total])}
|
|
36
39
|
</span>
|
|
37
40
|
<button
|
|
38
41
|
type="button"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BasicDrawer, type BasicDrawerProps } from "../../../shared/components";
|
|
2
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
2
3
|
|
|
3
4
|
export type ErrorRemoveDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
4
5
|
orgUnitName: string;
|
|
@@ -10,29 +11,25 @@ export const ErrorRemoveDrawer = ({
|
|
|
10
11
|
onRetry,
|
|
11
12
|
...drawerProps
|
|
12
13
|
}: ErrorRemoveDrawerProps) => {
|
|
14
|
+
const { t } = useLocalization();
|
|
15
|
+
|
|
13
16
|
return (
|
|
14
17
|
<BasicDrawer {...drawerProps}>
|
|
15
18
|
<BasicDrawer.Heading
|
|
16
|
-
title="
|
|
19
|
+
title={t("contracts.removeDrawer.unableTitle")}
|
|
17
20
|
onClose={drawerProps.onDismiss}
|
|
18
21
|
/>
|
|
19
22
|
<BasicDrawer.Body data-fs-bp-error-remove-drawer-body>
|
|
20
23
|
{onRetry ? (
|
|
21
|
-
<p>
|
|
22
|
-
An error occurred while removing the contract. Please try again.
|
|
23
|
-
</p>
|
|
24
|
+
<p>{t("contracts.removeDrawer.error")}</p>
|
|
24
25
|
) : (
|
|
25
26
|
<>
|
|
26
27
|
<p>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
like navigation and checkout.
|
|
31
|
-
</p>
|
|
32
|
-
<p>
|
|
33
|
-
To proceed, deselect at least one contract to keep it in this
|
|
34
|
-
organizational unit.
|
|
28
|
+
{t("contracts.removeDrawer.minimumContractWarning", [
|
|
29
|
+
<strong key="orgUnitName">{orgUnitName}</strong>,
|
|
30
|
+
])}
|
|
35
31
|
</p>
|
|
32
|
+
<p>{t("contracts.removeDrawer.deselectHint")}</p>
|
|
36
33
|
</>
|
|
37
34
|
)}
|
|
38
35
|
</BasicDrawer.Body>
|
|
@@ -44,14 +41,14 @@ export const ErrorRemoveDrawer = ({
|
|
|
44
41
|
onClick={drawerProps.onDismiss}
|
|
45
42
|
type="button"
|
|
46
43
|
>
|
|
47
|
-
|
|
44
|
+
{t("shared.buttons.cancel")}
|
|
48
45
|
</BasicDrawer.Button>
|
|
49
46
|
<BasicDrawer.Button
|
|
50
47
|
variant="confirm"
|
|
51
48
|
onClick={onRetry}
|
|
52
49
|
type="button"
|
|
53
50
|
>
|
|
54
|
-
|
|
51
|
+
{t("shared.buttons.tryAgain")}
|
|
55
52
|
</BasicDrawer.Button>
|
|
56
53
|
</>
|
|
57
54
|
) : (
|
|
@@ -60,7 +57,7 @@ export const ErrorRemoveDrawer = ({
|
|
|
60
57
|
onClick={drawerProps.onDismiss}
|
|
61
58
|
type="button"
|
|
62
59
|
>
|
|
63
|
-
|
|
60
|
+
{t("shared.buttons.gotIt")}
|
|
64
61
|
</BasicDrawer.Button>
|
|
65
62
|
)}
|
|
66
63
|
</BasicDrawer.Footer>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BasicDrawer, type BasicDrawerProps } from "../../../shared/components";
|
|
2
2
|
import Icon from "../../../shared/components/Icon/Icon";
|
|
3
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
3
4
|
|
|
4
5
|
export type UnableToRemoveContractsDrawerProps = Omit<
|
|
5
6
|
BasicDrawerProps,
|
|
@@ -17,10 +18,12 @@ export const UnableToRemoveContractsDrawer = ({
|
|
|
17
18
|
orgUnitName,
|
|
18
19
|
...drawerProps
|
|
19
20
|
}: UnableToRemoveContractsDrawerProps) => {
|
|
21
|
+
const { t } = useLocalization();
|
|
22
|
+
|
|
20
23
|
return (
|
|
21
24
|
<BasicDrawer {...drawerProps}>
|
|
22
25
|
<BasicDrawer.Heading
|
|
23
|
-
title="
|
|
26
|
+
title={t("contracts.removeDrawer.unableTitle")}
|
|
24
27
|
onClose={drawerProps.onDismiss}
|
|
25
28
|
/>
|
|
26
29
|
<BasicDrawer.Body data-fs-bp-unable-to-remove-contracts-drawer-body>
|
|
@@ -28,14 +31,14 @@ export const UnableToRemoveContractsDrawer = ({
|
|
|
28
31
|
<Icon name="InfoSolid" width={28} height={28} />
|
|
29
32
|
</span>
|
|
30
33
|
<p>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
{t("contracts.removeDrawer.minimumContractWarning", [
|
|
35
|
+
<strong key="orgUnitName">{orgUnitName}</strong>,
|
|
36
|
+
])}
|
|
34
37
|
</p>
|
|
35
38
|
<p>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
{t("contracts.removeDrawer.unableDeselectHint", [
|
|
40
|
+
<strong key="organizationalUnit">organizational unit</strong>,
|
|
41
|
+
])}
|
|
39
42
|
</p>
|
|
40
43
|
</BasicDrawer.Body>
|
|
41
44
|
<BasicDrawer.Footer>
|
|
@@ -44,7 +47,7 @@ export const UnableToRemoveContractsDrawer = ({
|
|
|
44
47
|
onClick={drawerProps.onDismiss}
|
|
45
48
|
type="button"
|
|
46
49
|
>
|
|
47
|
-
|
|
50
|
+
{t("shared.buttons.gotIt")}
|
|
48
51
|
</BasicDrawer.Button>
|
|
49
52
|
</BasicDrawer.Footer>
|
|
50
53
|
</BasicDrawer>
|
package/src/features/contracts/layouts/ContractInformationLayout/ContractInformationLayout.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import { useBuyerPortal, useDrawerProps } from "../../../shared/hooks";
|
|
16
16
|
import { useMutation } from "../../../shared/hooks/useMutation";
|
|
17
17
|
import { GlobalLayout } from "../../../shared/layouts";
|
|
18
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
18
19
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
19
20
|
import { ConfirmRemoveDrawer } from "../../components/ConfirmRemoveDrawer/ConfirmRemoveDrawer";
|
|
20
21
|
import { ErrorRemoveDrawer } from "../../components/ErrorRemoveDrawer/ErrorRemoveDrawer";
|
|
@@ -39,37 +40,39 @@ const ContractInformationNav = ({
|
|
|
39
40
|
orgUnitId: string;
|
|
40
41
|
contractId: string;
|
|
41
42
|
}) => {
|
|
43
|
+
const { t } = useLocalization();
|
|
44
|
+
|
|
42
45
|
return (
|
|
43
46
|
<nav data-fs-bp-contract-information-nav>
|
|
44
47
|
<ul data-fs-bp-contract-information-nav-list>
|
|
45
48
|
<li data-fs-bp-contract-information-nav-item-active>
|
|
46
|
-
<span>
|
|
49
|
+
<span>{t("contracts.nav.basicInformation")}</span>
|
|
47
50
|
</li>
|
|
48
51
|
<VerticalNav.Link
|
|
49
52
|
link={buyerPortalRoutes.addresses({ orgUnitId, contractId })}
|
|
50
53
|
>
|
|
51
|
-
|
|
54
|
+
{t("layouts.navigation.addresses")}
|
|
52
55
|
</VerticalNav.Link>
|
|
53
56
|
<VerticalNav.Link
|
|
54
57
|
link={buyerPortalRoutes.paymentMethods({ orgUnitId, contractId })}
|
|
55
58
|
>
|
|
56
|
-
|
|
59
|
+
{t("layouts.navigation.paymentMethods")}
|
|
57
60
|
</VerticalNav.Link>
|
|
58
61
|
<VerticalNav.Link
|
|
59
62
|
link={buyerPortalRoutes.creditCards({ orgUnitId, contractId })}
|
|
60
63
|
>
|
|
61
|
-
|
|
64
|
+
{t("layouts.navigation.creditCards")}
|
|
62
65
|
</VerticalNav.Link>
|
|
63
66
|
<VerticalNav.Link
|
|
64
67
|
link={buyerPortalRoutes.productAssortment({ orgUnitId, contractId })}
|
|
65
68
|
>
|
|
66
|
-
|
|
69
|
+
{t("contracts.nav.assortment")}
|
|
67
70
|
</VerticalNav.Link>
|
|
68
71
|
</ul>
|
|
69
72
|
|
|
70
73
|
<div data-fs-bp-contract-information-nav-section>
|
|
71
74
|
<span data-fs-bp-contract-information-nav-section-title>
|
|
72
|
-
|
|
75
|
+
{t("layouts.navigation.accountingFields")}
|
|
73
76
|
</span>
|
|
74
77
|
<ul data-fs-bp-contract-information-nav-list>
|
|
75
78
|
<VerticalNav.Link
|
|
@@ -79,7 +82,7 @@ const ContractInformationNav = ({
|
|
|
79
82
|
accountingFieldId: "cost-centers",
|
|
80
83
|
})}
|
|
81
84
|
>
|
|
82
|
-
|
|
85
|
+
{t("contracts.nav.costCenters")}
|
|
83
86
|
</VerticalNav.Link>
|
|
84
87
|
<VerticalNav.Link
|
|
85
88
|
link={buyerPortalRoutes.accountingFields({
|
|
@@ -88,7 +91,7 @@ const ContractInformationNav = ({
|
|
|
88
91
|
accountingFieldId: "departments",
|
|
89
92
|
})}
|
|
90
93
|
>
|
|
91
|
-
|
|
94
|
+
{t("contracts.nav.departments")}
|
|
92
95
|
</VerticalNav.Link>
|
|
93
96
|
<VerticalNav.Link
|
|
94
97
|
link={buyerPortalRoutes.accountingFields({
|
|
@@ -97,7 +100,7 @@ const ContractInformationNav = ({
|
|
|
97
100
|
accountingFieldId: "po-numbers",
|
|
98
101
|
})}
|
|
99
102
|
>
|
|
100
|
-
|
|
103
|
+
{t("contracts.nav.poNumbers")}
|
|
101
104
|
</VerticalNav.Link>
|
|
102
105
|
</ul>
|
|
103
106
|
</div>
|
|
@@ -108,6 +111,7 @@ const ContractInformationNav = ({
|
|
|
108
111
|
export const ContractInformationLayout = ({
|
|
109
112
|
data: { orgUnit, contracts, contractId },
|
|
110
113
|
}: ContractInformationLayoutProps) => {
|
|
114
|
+
const { t } = useLocalization();
|
|
111
115
|
const router = useRouter();
|
|
112
116
|
const { broadcast } = useContractSwitchChannel();
|
|
113
117
|
const { featureFlags } = useBuyerPortal();
|
|
@@ -165,7 +169,7 @@ export const ContractInformationLayout = ({
|
|
|
165
169
|
onSuccess: () => {
|
|
166
170
|
router.replace(router.asPath);
|
|
167
171
|
pushToast({
|
|
168
|
-
message: "
|
|
172
|
+
message: t("contracts.toasts.setDefaultSuccess"),
|
|
169
173
|
status: "INFO",
|
|
170
174
|
});
|
|
171
175
|
},
|
|
@@ -178,8 +182,7 @@ export const ContractInformationLayout = ({
|
|
|
178
182
|
// message is not JSON
|
|
179
183
|
}
|
|
180
184
|
pushToast({
|
|
181
|
-
message:
|
|
182
|
-
apiMessage ?? "Failed to set default contract. Please try again.",
|
|
185
|
+
message: apiMessage ?? t("contracts.toasts.setDefaultError"),
|
|
183
186
|
status: "ERROR",
|
|
184
187
|
});
|
|
185
188
|
},
|
|
@@ -214,7 +217,7 @@ export const ContractInformationLayout = ({
|
|
|
214
217
|
aria-label="Back to contracts"
|
|
215
218
|
>
|
|
216
219
|
<Icon name="ArrowPointLeft" width={16} height={16} />
|
|
217
|
-
|
|
220
|
+
{t("layouts.navigation.contracts")}
|
|
218
221
|
</Link>
|
|
219
222
|
)}
|
|
220
223
|
|
|
@@ -232,7 +235,7 @@ export const ContractInformationLayout = ({
|
|
|
232
235
|
disabled
|
|
233
236
|
>
|
|
234
237
|
<Icon name="Star" width={16} height={16} />
|
|
235
|
-
|
|
238
|
+
{t("contracts.actions.setAsDefault")}
|
|
236
239
|
</DropdownItem>
|
|
237
240
|
) : (
|
|
238
241
|
<DropdownItem
|
|
@@ -241,14 +244,14 @@ export const ContractInformationLayout = ({
|
|
|
241
244
|
disabled={isSetDefaultContractLoading}
|
|
242
245
|
>
|
|
243
246
|
<Icon name="StarOutline" width={16} height={16} />
|
|
244
|
-
|
|
247
|
+
{t("contracts.actions.setAsDefault")}
|
|
245
248
|
</DropdownItem>
|
|
246
249
|
)}
|
|
247
250
|
<DropdownItem
|
|
248
251
|
data-fs-bp-contract-information-more-menu-remove
|
|
249
252
|
onClick={openConfirmDrawer}
|
|
250
253
|
>
|
|
251
|
-
|
|
254
|
+
{t("shared.buttons.remove")}
|
|
252
255
|
</DropdownItem>
|
|
253
256
|
</BasicDropdownMenu>
|
|
254
257
|
</Dropdown>
|
|
@@ -264,24 +267,28 @@ export const ContractInformationLayout = ({
|
|
|
264
267
|
<main data-fs-bp-contract-information-content>
|
|
265
268
|
<section data-fs-bp-contract-information-basic-info>
|
|
266
269
|
<h2 data-fs-bp-contract-information-section-title>
|
|
267
|
-
|
|
270
|
+
{t("contracts.nav.basicInformation")}
|
|
268
271
|
</h2>
|
|
269
272
|
<div data-fs-bp-contract-information-fields>
|
|
270
273
|
<div data-fs-bp-contract-information-field>
|
|
271
|
-
<span data-fs-bp-contract-information-field-label>
|
|
274
|
+
<span data-fs-bp-contract-information-field-label>
|
|
275
|
+
{t("shared.labels.name")}
|
|
276
|
+
</span>
|
|
272
277
|
<span data-fs-bp-contract-information-field-value>
|
|
273
278
|
{contract?.name ?? "—"}
|
|
274
279
|
</span>
|
|
275
280
|
</div>
|
|
276
281
|
<div data-fs-bp-contract-information-field>
|
|
277
|
-
<span data-fs-bp-contract-information-field-label>
|
|
282
|
+
<span data-fs-bp-contract-information-field-label>
|
|
283
|
+
{t("shared.labels.email")}
|
|
284
|
+
</span>
|
|
278
285
|
<span data-fs-bp-contract-information-field-value>
|
|
279
286
|
{contract?.email ?? "—"}
|
|
280
287
|
</span>
|
|
281
288
|
</div>
|
|
282
289
|
<div data-fs-bp-contract-information-field>
|
|
283
290
|
<span data-fs-bp-contract-information-field-label>
|
|
284
|
-
|
|
291
|
+
{t("contracts.details.createdDate")}
|
|
285
292
|
</span>
|
|
286
293
|
<span data-fs-bp-contract-information-field-value>
|
|
287
294
|
{contract?.creationDate ?? "—"}
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from "../../../shared/hooks";
|
|
22
22
|
import { GlobalLayout } from "../../../shared/layouts";
|
|
23
23
|
import { SumaSidebar } from "../../../shared/layouts/SumaPageLayout/SumaSidebar";
|
|
24
|
+
import { useLocalization } from "../../../shared/localization/LocalizationContext";
|
|
24
25
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
25
26
|
import { AddContractsDrawer } from "../../components/AddContractsDrawer/AddContractsDrawer";
|
|
26
27
|
import { ConfirmRemoveDrawer } from "../../components/ConfirmRemoveDrawer/ConfirmRemoveDrawer";
|
|
@@ -54,24 +55,11 @@ export type ContractListingLayoutProps = {
|
|
|
54
55
|
loading?: boolean;
|
|
55
56
|
};
|
|
56
57
|
|
|
57
|
-
const headerInfo = (
|
|
58
|
-
<Tooltip
|
|
59
|
-
content="Contracts define the commercial rules applied during purchasing, such as addresses, payment methods, credit cards and other checkout settings."
|
|
60
|
-
placement="right-center"
|
|
61
|
-
>
|
|
62
|
-
<Icon
|
|
63
|
-
name="InfoFilled"
|
|
64
|
-
width={20}
|
|
65
|
-
height={20}
|
|
66
|
-
data-fs-bp-contract-listing-info-icon
|
|
67
|
-
/>
|
|
68
|
-
</Tooltip>
|
|
69
|
-
);
|
|
70
|
-
|
|
71
58
|
export const ContractListingLayout = ({
|
|
72
59
|
data: { orgUnit, contracts, user },
|
|
73
60
|
loading = false,
|
|
74
61
|
}: ContractListingLayoutProps) => {
|
|
62
|
+
const { t } = useLocalization();
|
|
75
63
|
const isSingleContract = contracts.length <= 1;
|
|
76
64
|
const router = useRouter();
|
|
77
65
|
const { pushToast } = useUI();
|
|
@@ -145,8 +133,7 @@ export const ContractListingLayout = ({
|
|
|
145
133
|
(switched) => {
|
|
146
134
|
if (!switched) {
|
|
147
135
|
pushToast({
|
|
148
|
-
message:
|
|
149
|
-
"Contracts removed, but we couldn't refresh your active contract. Please reload the page.",
|
|
136
|
+
message: t("contracts.toasts.refreshError"),
|
|
150
137
|
status: "ERROR",
|
|
151
138
|
});
|
|
152
139
|
router.replace(router.asPath);
|
|
@@ -159,9 +146,10 @@ export const ContractListingLayout = ({
|
|
|
159
146
|
|
|
160
147
|
router.replace(router.asPath);
|
|
161
148
|
pushToast({
|
|
162
|
-
message:
|
|
163
|
-
pendingRemoveIds.size
|
|
164
|
-
|
|
149
|
+
message: t("contracts.toasts.removeSuccess", [
|
|
150
|
+
pendingRemoveIds.size,
|
|
151
|
+
pendingRemoveIds.size === 1 ? "" : "s",
|
|
152
|
+
]),
|
|
165
153
|
status: "INFO",
|
|
166
154
|
});
|
|
167
155
|
},
|
|
@@ -175,7 +163,7 @@ export const ContractListingLayout = ({
|
|
|
175
163
|
}
|
|
176
164
|
confirmRemoveDrawer.close();
|
|
177
165
|
pushToast({
|
|
178
|
-
message: apiMessage ?? "
|
|
166
|
+
message: apiMessage ?? t("contracts.toasts.removeError"),
|
|
179
167
|
status: "ERROR",
|
|
180
168
|
});
|
|
181
169
|
},
|
|
@@ -206,7 +194,7 @@ export const ContractListingLayout = ({
|
|
|
206
194
|
onSuccess: () => {
|
|
207
195
|
router.replace(router.asPath);
|
|
208
196
|
pushToast({
|
|
209
|
-
message: "
|
|
197
|
+
message: t("contracts.toasts.setDefaultSuccess"),
|
|
210
198
|
status: "INFO",
|
|
211
199
|
});
|
|
212
200
|
},
|
|
@@ -220,8 +208,7 @@ export const ContractListingLayout = ({
|
|
|
220
208
|
}
|
|
221
209
|
void router.replace(router.asPath).catch(() => {});
|
|
222
210
|
pushToast({
|
|
223
|
-
message:
|
|
224
|
-
apiMessage ?? "Failed to set default contract. Please try again.",
|
|
211
|
+
message: apiMessage ?? t("contracts.toasts.setDefaultError"),
|
|
225
212
|
status: "ERROR",
|
|
226
213
|
});
|
|
227
214
|
},
|
|
@@ -243,7 +230,7 @@ export const ContractListingLayout = ({
|
|
|
243
230
|
useEffect(() => {
|
|
244
231
|
if (router.query.error === "contract-load-failed") {
|
|
245
232
|
pushToast({
|
|
246
|
-
message: "
|
|
233
|
+
message: t("contracts.toasts.loadError"),
|
|
247
234
|
status: "ERROR",
|
|
248
235
|
});
|
|
249
236
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -303,6 +290,20 @@ export const ContractListingLayout = ({
|
|
|
303
290
|
}
|
|
304
291
|
};
|
|
305
292
|
|
|
293
|
+
const headerInfo = (
|
|
294
|
+
<Tooltip
|
|
295
|
+
content={t("contracts.listing.infoTooltip")}
|
|
296
|
+
placement="right-center"
|
|
297
|
+
>
|
|
298
|
+
<Icon
|
|
299
|
+
name="InfoFilled"
|
|
300
|
+
width={20}
|
|
301
|
+
height={20}
|
|
302
|
+
data-fs-bp-contract-listing-info-icon
|
|
303
|
+
/>
|
|
304
|
+
</Tooltip>
|
|
305
|
+
);
|
|
306
|
+
|
|
306
307
|
return (
|
|
307
308
|
<GlobalLayout>
|
|
308
309
|
<OrgUnitDetailsNavbar
|
|
@@ -325,7 +326,7 @@ export const ContractListingLayout = ({
|
|
|
325
326
|
|
|
326
327
|
<section data-fs-bp-contract-listing-section>
|
|
327
328
|
<HeaderInside
|
|
328
|
-
title="
|
|
329
|
+
title={t("contracts.titles.contracts")}
|
|
329
330
|
info={headerInfo}
|
|
330
331
|
data-fs-bp-contract-listing-header
|
|
331
332
|
>
|
|
@@ -340,7 +341,7 @@ export const ContractListingLayout = ({
|
|
|
340
341
|
{isSingleContract ? (
|
|
341
342
|
<BasicCard
|
|
342
343
|
data-fs-bp-contracts-settings-card
|
|
343
|
-
footerMessage="
|
|
344
|
+
footerMessage={t("orgUnitDetails.links.manageContractSettings")}
|
|
344
345
|
footerLink={buyerPortalRoutes.profileDetails({
|
|
345
346
|
orgUnitId: orgUnit.id,
|
|
346
347
|
contractId: defaultContractId,
|
|
@@ -369,6 +370,7 @@ export const ContractListingLayout = ({
|
|
|
369
370
|
accountingFieldsLoading: listAccountingFieldLoading,
|
|
370
371
|
onAddAccountingField: openAccountingFieldDrawer,
|
|
371
372
|
onAccountingFieldChange: listAccountingFieldRefresh,
|
|
373
|
+
t,
|
|
372
374
|
})}
|
|
373
375
|
/>
|
|
374
376
|
)}
|
|
@@ -6,6 +6,7 @@ import { Icon } from "../../../shared/components";
|
|
|
6
6
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
7
7
|
|
|
8
8
|
import type { AccountingField } from "../../../accounting-fields/types";
|
|
9
|
+
import type { LocalizeFn } from "../../../shared/localization/types";
|
|
9
10
|
import type { VerticalNavTreeItemProps } from "../../../shared/types";
|
|
10
11
|
|
|
11
12
|
export const ICON_SIZE = 20;
|
|
@@ -17,6 +18,7 @@ export type BuildContractSettingsNavItemsParams = {
|
|
|
17
18
|
accountingFieldsLoading?: boolean;
|
|
18
19
|
onAddAccountingField: () => void;
|
|
19
20
|
onAccountingFieldChange: () => void;
|
|
21
|
+
t: LocalizeFn;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
export const buildContractSettingsNavItems = ({
|
|
@@ -26,32 +28,33 @@ export const buildContractSettingsNavItems = ({
|
|
|
26
28
|
accountingFieldsLoading = false,
|
|
27
29
|
onAddAccountingField,
|
|
28
30
|
onAccountingFieldChange,
|
|
31
|
+
t,
|
|
29
32
|
}: BuildContractSettingsNavItemsParams): VerticalNavTreeItemProps[] => {
|
|
30
33
|
const linkParams = { orgUnitId, contractId };
|
|
31
34
|
|
|
32
35
|
return [
|
|
33
36
|
{
|
|
34
|
-
name: "
|
|
37
|
+
name: t("contracts.nav.basicInformation"),
|
|
35
38
|
link: buyerPortalRoutes.profileDetails(linkParams),
|
|
36
39
|
},
|
|
37
40
|
{
|
|
38
|
-
name: "
|
|
41
|
+
name: t("layouts.navigation.addresses"),
|
|
39
42
|
link: buyerPortalRoutes.addresses(linkParams),
|
|
40
43
|
},
|
|
41
44
|
{
|
|
42
|
-
name: "
|
|
45
|
+
name: t("layouts.navigation.paymentMethods"),
|
|
43
46
|
link: buyerPortalRoutes.paymentMethods(linkParams),
|
|
44
47
|
},
|
|
45
48
|
{
|
|
46
|
-
name: "
|
|
49
|
+
name: t("layouts.navigation.creditCards"),
|
|
47
50
|
link: buyerPortalRoutes.creditCards(linkParams),
|
|
48
51
|
},
|
|
49
52
|
{
|
|
50
|
-
name: "
|
|
53
|
+
name: t("contracts.nav.assortment"),
|
|
51
54
|
link: buyerPortalRoutes.productAssortment(linkParams),
|
|
52
55
|
},
|
|
53
56
|
{
|
|
54
|
-
name: "
|
|
57
|
+
name: t("layouts.navigation.accountingFields"),
|
|
55
58
|
loading: accountingFieldsLoading,
|
|
56
59
|
submenu: {
|
|
57
60
|
items: accountingFields.map((field) => ({
|