@vtex/faststore-plugin-buyer-portal 1.3.27 → 1.3.28
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 +8 -2
- package/package.json +1 -1
- package/src/features/addresses/components/AddRecipientsDrawer/AddRecipientsDrawer.tsx +20 -2
- package/src/features/addresses/components/CreateAddressDrawer/CreateAddressDrawer.tsx +50 -4
- package/src/features/addresses/components/DeleteAddressDrawer/DeleteAddressDrawer.tsx +26 -2
- package/src/features/addresses/components/DeleteAddressLocationDrawer/DeleteAddressLocationDrawer.tsx +29 -3
- package/src/features/addresses/components/DeleteRecipientAddressDrawer/DeleteRecipientAddressDrawer.tsx +24 -2
- package/src/features/addresses/components/EditAddressDrawer/EditAddressDrawer.tsx +28 -2
- package/src/features/addresses/components/EditAddressLocationDrawer/EditAddressLocationDrawer.tsx +30 -4
- package/src/features/addresses/components/EditRecipientAddressDrawer/EditRecipientAddressDrawer.tsx +30 -2
- package/src/features/addresses/components/LocationsDrawer/LocationsDrawer.tsx +29 -2
- package/src/features/budgets/components/BudgetDeleteDrawer/BudgetDeleteDrawer.tsx +32 -4
- package/src/features/budgets/components/CreateBudgetDrawer/CreateBudgetDrawer.tsx +59 -4
- package/src/features/budgets/components/EditBudgetDrawer/EditBudgetDrawer.tsx +28 -1
- package/src/features/buying-policies/components/AddBuyingPolicyDrawer/AddBuyingPolicyDrawer.tsx +48 -5
- package/src/features/buying-policies/components/DeleteBuyingPolicyDrawer/DeleteBuyingPolicyDrawer.tsx +28 -2
- package/src/features/buying-policies/components/UpdateBuyingPolicyDrawer/UpdateBuyingPolicyDrawer.tsx +49 -5
- package/src/features/custom-fields/components/CreateCustomFieldValueDrawer/CreateCustomFieldValueDrawer.tsx +60 -5
- package/src/features/custom-fields/components/DeleteCustomFieldValueDrawer/DeleteCustomFieldValueDrawer.tsx +61 -5
- package/src/features/custom-fields/components/UpdateCustomFieldValueDrawer/UpdateCustomFieldValueDrawer.tsx +32 -3
- package/src/features/org-units/components/CreateOrgUnitDrawer/CreateOrgUnitDrawer.tsx +18 -0
- package/src/features/org-units/components/DeleteOrgUnitDrawer/DeleteOrgUnitDrawer.tsx +28 -0
- package/src/features/org-units/components/UpdateOrgUnitDrawer/UpdateOrgUnitDrawer.tsx +28 -0
- package/src/features/shared/hooks/analytics/types.ts +14 -0
- package/src/features/shared/hooks/analytics/useAnalytics.ts +249 -0
- package/src/features/shared/hooks/index.ts +1 -0
- package/src/features/shared/services/logger/analytics/analytics.ts +101 -0
- package/src/features/shared/services/logger/analytics/constants.ts +83 -0
- package/src/features/shared/services/logger/analytics/types.ts +108 -0
- package/src/features/shared/services/logger/index.ts +1 -0
- package/src/features/shared/utils/constants.ts +1 -1
- package/src/features/users/components/CreateUserDrawer/CreateUserDrawer.tsx +24 -0
- package/src/features/users/components/DeleteUserDrawer/DeleteUserDrawer.tsx +23 -2
- package/src/features/users/components/UpdateUserDrawer/UpdateUserDrawer.tsx +45 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useState } from "react";
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
2
|
|
|
3
3
|
import { useRouter } from "next/router";
|
|
4
4
|
|
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
Icon,
|
|
10
10
|
type BasicDrawerProps,
|
|
11
11
|
} from "../../../shared/components";
|
|
12
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
12
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
13
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
13
14
|
import { sortingOptionsAllocations } from "../../../shared/utils";
|
|
14
15
|
import { parseAmount } from "../../../shared/utils/budgetAmountParse";
|
|
15
16
|
import { getKeyByValue } from "../../../shared/utils/getKeyByValue";
|
|
@@ -65,6 +66,12 @@ export const CreateBudgetDrawer = ({
|
|
|
65
66
|
} = useBuyerPortal();
|
|
66
67
|
const router = useRouter();
|
|
67
68
|
const { pushToast } = useUI();
|
|
69
|
+
const { trackEvent, trackEntityCreated, trackEntityCreateError } =
|
|
70
|
+
useAnalytics({
|
|
71
|
+
entityType: "budget",
|
|
72
|
+
defaultTimerName: "budget_creation",
|
|
73
|
+
shouldTrackDefaultTimer: true,
|
|
74
|
+
});
|
|
68
75
|
|
|
69
76
|
const {
|
|
70
77
|
filter,
|
|
@@ -86,6 +93,21 @@ export const CreateBudgetDrawer = ({
|
|
|
86
93
|
|
|
87
94
|
type DrawerStep = "form" | "allocations" | "confirmation";
|
|
88
95
|
const [step, setStep] = useState<DrawerStep>("form");
|
|
96
|
+
const [previousStep, setPreviousStep] = useState<DrawerStep | null>(null);
|
|
97
|
+
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (previousStep !== null && previousStep !== step) {
|
|
100
|
+
trackEvent(ANALYTICS_EVENTS.BUDGET_STEP_TIMING, {
|
|
101
|
+
flow_name: "budget_creation",
|
|
102
|
+
from_step: previousStep,
|
|
103
|
+
to_step: step,
|
|
104
|
+
step_name: step,
|
|
105
|
+
org_unit_id: unitId,
|
|
106
|
+
contract_id: contractId,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
setPreviousStep(step);
|
|
110
|
+
}, [step, previousStep, trackEvent, unitId, contractId]);
|
|
89
111
|
|
|
90
112
|
const [budget, setBudget] = useState<BudgetInput>({
|
|
91
113
|
name: "",
|
|
@@ -132,6 +154,16 @@ export const CreateBudgetDrawer = ({
|
|
|
132
154
|
return;
|
|
133
155
|
}
|
|
134
156
|
|
|
157
|
+
// Track successful budget creation
|
|
158
|
+
trackEntityCreated(ANALYTICS_EVENTS.BUDGET_CREATED, "budget", {
|
|
159
|
+
budget_name: budget.name,
|
|
160
|
+
amount: budget.amount,
|
|
161
|
+
has_notifications: Boolean(budget.notifications?.hasNotification),
|
|
162
|
+
allocations_count: selectedAllocations.length,
|
|
163
|
+
org_unit_id: unitId,
|
|
164
|
+
contract_id: contractId,
|
|
165
|
+
});
|
|
166
|
+
|
|
135
167
|
pushToast({
|
|
136
168
|
message: "Budget added successfully.",
|
|
137
169
|
status: "INFO",
|
|
@@ -139,8 +171,14 @@ export const CreateBudgetDrawer = ({
|
|
|
139
171
|
close();
|
|
140
172
|
router.reload();
|
|
141
173
|
},
|
|
142
|
-
onError: (error: Error) =>
|
|
143
|
-
|
|
174
|
+
onError: (error: Error) => {
|
|
175
|
+
trackEntityCreateError(ANALYTICS_EVENTS.BUDGET_CREATE_ERROR, error, {
|
|
176
|
+
org_unit_id: unitId,
|
|
177
|
+
contract_id: contractId,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
pushToast({ message: error.message, status: "ERROR" });
|
|
181
|
+
},
|
|
144
182
|
},
|
|
145
183
|
}
|
|
146
184
|
);
|
|
@@ -149,6 +187,18 @@ export const CreateBudgetDrawer = ({
|
|
|
149
187
|
useUpdateBudget({
|
|
150
188
|
options: {
|
|
151
189
|
onSuccess: () => {
|
|
190
|
+
// Track successful budget creation (with policy)
|
|
191
|
+
if (firstBudget) {
|
|
192
|
+
trackEntityCreated(ANALYTICS_EVENTS.BUDGET_CREATED, "budget", {
|
|
193
|
+
budget_name: budget.name,
|
|
194
|
+
amount: budget.amount,
|
|
195
|
+
has_notifications: Boolean(budget.notifications?.hasNotification),
|
|
196
|
+
has_policy: true,
|
|
197
|
+
org_unit_id: unitId,
|
|
198
|
+
contract_id: contractId,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
152
202
|
pushToast({
|
|
153
203
|
message: "Budget added successfully.",
|
|
154
204
|
status: "INFO",
|
|
@@ -167,6 +217,11 @@ export const CreateBudgetDrawer = ({
|
|
|
167
217
|
router.reload();
|
|
168
218
|
},
|
|
169
219
|
onError: (error: Error) => {
|
|
220
|
+
trackEntityCreateError(ANALYTICS_EVENTS.BUDGET_CREATE_ERROR, error, {
|
|
221
|
+
org_unit_id: unitId,
|
|
222
|
+
contract_id: contractId,
|
|
223
|
+
});
|
|
224
|
+
|
|
170
225
|
pushToast({
|
|
171
226
|
message: error?.message || "An error occurred. Please try again.",
|
|
172
227
|
status: "ERROR",
|
|
@@ -5,7 +5,8 @@ import { useRouter } from "next/router";
|
|
|
5
5
|
import { useUI } from "@faststore/ui";
|
|
6
6
|
|
|
7
7
|
import { BasicDrawer, type BasicDrawerProps } from "../../../shared/components";
|
|
8
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
8
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
9
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
9
10
|
import { parseAmount } from "../../../shared/utils/budgetAmountParse";
|
|
10
11
|
import { useUpdateBudget } from "../../hooks";
|
|
11
12
|
import { BudgetAddForm } from "../BudgetAddForm/BudgetAddForm";
|
|
@@ -75,6 +76,12 @@ export const EditBudgetDrawer = ({
|
|
|
75
76
|
const { clientContext } = useBuyerPortal();
|
|
76
77
|
const { pushToast } = useUI();
|
|
77
78
|
const router = useRouter();
|
|
79
|
+
const { trackEntityEdited, trackEntityEditError } = useAnalytics({
|
|
80
|
+
entityType: "budget",
|
|
81
|
+
entityId: budgetId,
|
|
82
|
+
defaultTimerName: "budget_edit",
|
|
83
|
+
shouldTrackDefaultTimer: true,
|
|
84
|
+
});
|
|
78
85
|
|
|
79
86
|
const [budget, setBudget] = useState<BudgetInput>(() =>
|
|
80
87
|
getInitialBudget(initialBudget)
|
|
@@ -86,12 +93,32 @@ export const EditBudgetDrawer = ({
|
|
|
86
93
|
const { mutate: updateBudget, isLoading } = useUpdateBudget({
|
|
87
94
|
options: {
|
|
88
95
|
onSuccess: () => {
|
|
96
|
+
trackEntityEdited(ANALYTICS_EVENTS.BUDGET_EDITED, {
|
|
97
|
+
budget_id: budgetId,
|
|
98
|
+
budget_name: budget.name,
|
|
99
|
+
amount: budget.amount,
|
|
100
|
+
has_notifications: Boolean(budget.notifications?.hasNotification),
|
|
101
|
+
org_unit_id: orgUnitId,
|
|
102
|
+
contract_id: contractId,
|
|
103
|
+
});
|
|
104
|
+
|
|
89
105
|
pushToast({ message: "Budget updated successfully.", status: "INFO" });
|
|
90
106
|
onSubmit?.(budget);
|
|
91
107
|
close();
|
|
92
108
|
router.reload();
|
|
93
109
|
},
|
|
94
110
|
onError: (error: Error) => {
|
|
111
|
+
trackEntityEditError(
|
|
112
|
+
ANALYTICS_EVENTS.BUDGET_EDIT_ERROR,
|
|
113
|
+
"budget",
|
|
114
|
+
budgetId,
|
|
115
|
+
error,
|
|
116
|
+
{
|
|
117
|
+
org_unit_id: orgUnitId,
|
|
118
|
+
contract_id: contractId,
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
|
|
95
122
|
pushToast({
|
|
96
123
|
message: error?.message || "An error occurred. Please try again.",
|
|
97
124
|
status: "ERROR",
|
package/src/features/buying-policies/components/AddBuyingPolicyDrawer/AddBuyingPolicyDrawer.tsx
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
|
|
1
3
|
import { useRouter } from "next/router";
|
|
2
4
|
|
|
3
5
|
import { useUI } from "@faststore/ui";
|
|
4
6
|
|
|
5
7
|
import { BasicBuyingPolicyDrawer, type BasicBuyingPolicyDrawerProps } from "..";
|
|
8
|
+
import { useAnalytics } from "../../../shared/hooks";
|
|
9
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
6
10
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
7
11
|
import { useAddBuyingPolicy } from "../../hooks";
|
|
8
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
buyingPolicyDefault,
|
|
14
|
+
BUYING_POLICIES_WORKFLOW_TYPES,
|
|
15
|
+
} from "../../utils";
|
|
9
16
|
|
|
10
17
|
import type { BuyingPolicy } from "../../types";
|
|
18
|
+
import type { BuyingPolicyForm } from "../BasicBuyingPolicyDrawer/BasicBuyingPolicyDrawer";
|
|
11
19
|
|
|
12
20
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13
21
|
const { id, ...defaultBuyingPolicyValues } = buyingPolicyDefault;
|
|
@@ -30,8 +38,33 @@ export const AddBuyingPolicyDrawer = ({
|
|
|
30
38
|
}: AddBuyingPolicyDrawerProps) => {
|
|
31
39
|
const { pushToast } = useUI();
|
|
32
40
|
const router = useRouter();
|
|
41
|
+
const { trackEntityCreated, trackEntityCreateError } = useAnalytics({
|
|
42
|
+
entityType: "buying_policy",
|
|
43
|
+
defaultTimerName: "buying_policy_creation",
|
|
44
|
+
shouldTrackDefaultTimer: true,
|
|
45
|
+
});
|
|
46
|
+
const formDataRef = useRef<BuyingPolicyForm | null>(null);
|
|
33
47
|
|
|
34
48
|
const handleAddBuyingPolicySuccess = (data: BuyingPolicy) => {
|
|
49
|
+
const formData = formDataRef.current;
|
|
50
|
+
|
|
51
|
+
trackEntityCreated(
|
|
52
|
+
ANALYTICS_EVENTS.BUYING_POLICY_CREATED,
|
|
53
|
+
"buying_policy",
|
|
54
|
+
{
|
|
55
|
+
policy_name: formData?.name,
|
|
56
|
+
policy_description: formData?.description,
|
|
57
|
+
policy_criteria: formData?.criteria,
|
|
58
|
+
policy_type: formData?.action.type,
|
|
59
|
+
...(formData?.action.type ===
|
|
60
|
+
BUYING_POLICIES_WORKFLOW_TYPES.SEQUENTIAL_WORKFLOW && {
|
|
61
|
+
approval_levels_count: formData?.action.levels?.length,
|
|
62
|
+
}),
|
|
63
|
+
org_unit_id: orgUnitId,
|
|
64
|
+
contract_id: contractId,
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
35
68
|
pushToast({
|
|
36
69
|
message: "Buying policy added successfully",
|
|
37
70
|
status: "INFO",
|
|
@@ -60,7 +93,16 @@ export const AddBuyingPolicyDrawer = ({
|
|
|
60
93
|
|
|
61
94
|
const { addBuyingPolicy, isAddBuyingPolicyLoading } = useAddBuyingPolicy({
|
|
62
95
|
onSuccess: handleAddBuyingPolicySuccess,
|
|
63
|
-
onError: () => {
|
|
96
|
+
onError: (error) => {
|
|
97
|
+
trackEntityCreateError(
|
|
98
|
+
ANALYTICS_EVENTS.BUYING_POLICY_CREATE_ERROR,
|
|
99
|
+
error,
|
|
100
|
+
{
|
|
101
|
+
org_unit_id: orgUnitId,
|
|
102
|
+
contract_id: contractId,
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
|
|
64
106
|
pushToast({
|
|
65
107
|
message: "An error occurred. Please try again.",
|
|
66
108
|
title: "Error",
|
|
@@ -73,15 +115,16 @@ export const AddBuyingPolicyDrawer = ({
|
|
|
73
115
|
<BasicBuyingPolicyDrawer
|
|
74
116
|
close={close}
|
|
75
117
|
isLoading={isAddBuyingPolicyLoading}
|
|
76
|
-
onConfirm={(form) =>
|
|
118
|
+
onConfirm={(form) => {
|
|
119
|
+
formDataRef.current = form;
|
|
77
120
|
addBuyingPolicy({
|
|
78
121
|
buyingPolicy: {
|
|
79
122
|
...form,
|
|
80
123
|
},
|
|
81
124
|
orgUnitId,
|
|
82
125
|
contractId,
|
|
83
|
-
})
|
|
84
|
-
}
|
|
126
|
+
});
|
|
127
|
+
}}
|
|
85
128
|
orgUnitId={orgUnitId}
|
|
86
129
|
contractId={contractId}
|
|
87
130
|
initialValues={defaultBuyingPolicyValues}
|
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
InputText,
|
|
8
8
|
type BasicDrawerProps,
|
|
9
9
|
} from "../../../shared/components";
|
|
10
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
10
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
11
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
11
12
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
12
13
|
import { useRemoveBuyingPolicy } from "../../hooks";
|
|
13
14
|
|
|
@@ -32,8 +33,22 @@ export const DeleteBuyingPolicyDrawer = ({
|
|
|
32
33
|
const { currentContract, currentOrgUnit } = useBuyerPortal();
|
|
33
34
|
|
|
34
35
|
const { pushToast } = useUI();
|
|
36
|
+
const { trackEvent } = useAnalytics({
|
|
37
|
+
entityType: "buying_policy",
|
|
38
|
+
entityId: buyingPolicy.id,
|
|
39
|
+
defaultTimerName: "buying_policy_delete",
|
|
40
|
+
shouldTrackDefaultTimer: true,
|
|
41
|
+
});
|
|
35
42
|
|
|
36
43
|
const handleRemoveSuccess = () => {
|
|
44
|
+
trackEvent(ANALYTICS_EVENTS.BUYING_POLICY_DELETED, {
|
|
45
|
+
policy_id: buyingPolicy.id,
|
|
46
|
+
policy_name: buyingPolicy.name,
|
|
47
|
+
org_unit_id: currentOrgUnit?.id,
|
|
48
|
+
contract_id: currentContract?.id,
|
|
49
|
+
entity_type: "buying_policy",
|
|
50
|
+
});
|
|
51
|
+
|
|
37
52
|
pushToast({
|
|
38
53
|
message: "Buying policy deleted successfully",
|
|
39
54
|
status: "INFO",
|
|
@@ -57,7 +72,18 @@ export const DeleteBuyingPolicyDrawer = ({
|
|
|
57
72
|
const { removeBuyingPolicy, isRemoveBuyingPolicyLoading } =
|
|
58
73
|
useRemoveBuyingPolicy({
|
|
59
74
|
onSuccess: handleRemoveSuccess,
|
|
60
|
-
onError: () => {
|
|
75
|
+
onError: (error) => {
|
|
76
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
77
|
+
|
|
78
|
+
trackEvent(ANALYTICS_EVENTS.BUYING_POLICY_DELETE_ERROR, {
|
|
79
|
+
entity_type: "buying_policy",
|
|
80
|
+
entity_id: buyingPolicy.id,
|
|
81
|
+
policy_name: buyingPolicy.name,
|
|
82
|
+
org_unit_id: currentOrgUnit?.id,
|
|
83
|
+
contract_id: currentContract?.id,
|
|
84
|
+
error_message: errorMessage,
|
|
85
|
+
});
|
|
86
|
+
|
|
61
87
|
pushToast({
|
|
62
88
|
message: "An error occurred. Please try again.",
|
|
63
89
|
title: "Error",
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
|
|
1
3
|
import { useRouter } from "next/router";
|
|
2
4
|
|
|
3
5
|
import { useUI } from "@faststore/ui";
|
|
4
6
|
|
|
5
7
|
import { BasicBuyingPolicyDrawer, type BasicBuyingPolicyDrawerProps } from "..";
|
|
8
|
+
import { useAnalytics } from "../../../shared/hooks";
|
|
9
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
6
10
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
7
11
|
import { useGetBuyingPolicy, useUpdateBuyingPolicy } from "../../hooks";
|
|
8
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
buyingPolicyDefault,
|
|
14
|
+
BUYING_POLICIES_WORKFLOW_TYPES,
|
|
15
|
+
} from "../../utils";
|
|
16
|
+
|
|
17
|
+
import type { BuyingPolicyForm } from "../BasicBuyingPolicyDrawer/BasicBuyingPolicyDrawer";
|
|
9
18
|
|
|
10
19
|
export type UpdateBuyingPolicyDrawerProps = Omit<
|
|
11
20
|
BasicBuyingPolicyDrawerProps,
|
|
@@ -33,8 +42,31 @@ export const UpdateBuyingPolicyDrawer = ({
|
|
|
33
42
|
|
|
34
43
|
const { pushToast } = useUI();
|
|
35
44
|
const router = useRouter();
|
|
45
|
+
const { trackEntityEdited, trackEntityEditError } = useAnalytics({
|
|
46
|
+
entityType: "buying_policy",
|
|
47
|
+
entityId: buyingPolicyId,
|
|
48
|
+
defaultTimerName: "buying_policy_edit",
|
|
49
|
+
shouldTrackDefaultTimer: true,
|
|
50
|
+
});
|
|
51
|
+
const formDataRef = useRef<BuyingPolicyForm | null>(null);
|
|
36
52
|
|
|
37
53
|
const handleUpdateBuyingPolicySuccess = () => {
|
|
54
|
+
const formData = formDataRef.current;
|
|
55
|
+
|
|
56
|
+
trackEntityEdited(ANALYTICS_EVENTS.BUYING_POLICY_EDITED, {
|
|
57
|
+
policy_id: buyingPolicyId,
|
|
58
|
+
policy_name: formData?.name,
|
|
59
|
+
policy_type: formData?.action.type,
|
|
60
|
+
policy_description: formData?.description,
|
|
61
|
+
policy_criteria: formData?.criteria,
|
|
62
|
+
...(formData?.action.type ===
|
|
63
|
+
BUYING_POLICIES_WORKFLOW_TYPES.SEQUENTIAL_WORKFLOW && {
|
|
64
|
+
approval_levels_count: formData?.action.levels?.length,
|
|
65
|
+
}),
|
|
66
|
+
org_unit_id: orgUnitId,
|
|
67
|
+
contract_id: contractId,
|
|
68
|
+
});
|
|
69
|
+
|
|
38
70
|
pushToast({
|
|
39
71
|
message: "Buying policy updated successfully",
|
|
40
72
|
status: "INFO",
|
|
@@ -64,7 +96,18 @@ export const UpdateBuyingPolicyDrawer = ({
|
|
|
64
96
|
const { updateBuyingPolicy, isUpdateBuyingPolicyLoading } =
|
|
65
97
|
useUpdateBuyingPolicy({
|
|
66
98
|
onSuccess: handleUpdateBuyingPolicySuccess,
|
|
67
|
-
onError: () => {
|
|
99
|
+
onError: (error) => {
|
|
100
|
+
trackEntityEditError(
|
|
101
|
+
ANALYTICS_EVENTS.BUYING_POLICY_EDIT_ERROR,
|
|
102
|
+
"buying_policy",
|
|
103
|
+
buyingPolicyId,
|
|
104
|
+
error,
|
|
105
|
+
{
|
|
106
|
+
org_unit_id: orgUnitId,
|
|
107
|
+
contract_id: contractId,
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
|
|
68
111
|
pushToast({
|
|
69
112
|
message: "An error occurred. Please try again.",
|
|
70
113
|
title: "Error",
|
|
@@ -80,7 +123,8 @@ export const UpdateBuyingPolicyDrawer = ({
|
|
|
80
123
|
close={close}
|
|
81
124
|
isLoading={isUpdateBuyingPolicyLoading}
|
|
82
125
|
isDrawerLoading={isBuyingPolicyLoading}
|
|
83
|
-
onConfirm={(form) =>
|
|
126
|
+
onConfirm={(form) => {
|
|
127
|
+
formDataRef.current = form;
|
|
84
128
|
updateBuyingPolicy({
|
|
85
129
|
buyingPolicyId,
|
|
86
130
|
buyingPolicy: {
|
|
@@ -88,8 +132,8 @@ export const UpdateBuyingPolicyDrawer = ({
|
|
|
88
132
|
},
|
|
89
133
|
orgUnitId,
|
|
90
134
|
contractId,
|
|
91
|
-
})
|
|
92
|
-
}
|
|
135
|
+
});
|
|
136
|
+
}}
|
|
93
137
|
initialValues={{ ...buyingPolicyDefault, ...(buyingPolicy ?? {}) }}
|
|
94
138
|
orgUnitId={orgUnitId}
|
|
95
139
|
contractId={contractId}
|
|
@@ -4,12 +4,13 @@ import { useUI } from "@faststore/ui";
|
|
|
4
4
|
|
|
5
5
|
import { BasicDrawerProps } from "../../../shared/components";
|
|
6
6
|
import { CreateEntityDrawer } from "../../../shared/components/CustomField/create-custom-field/CreateCustomFieldDrawer";
|
|
7
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
7
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
8
8
|
import {
|
|
9
9
|
useCreateCustomFieldValue,
|
|
10
10
|
useCustomFieldValues,
|
|
11
11
|
useAddCustomFieldValueToUnitScope,
|
|
12
12
|
} from "../../../shared/hooks/custom-field";
|
|
13
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
13
14
|
|
|
14
15
|
export type CustomFieldType = "Cost Center" | "PO Number" | "Release";
|
|
15
16
|
|
|
@@ -35,8 +36,14 @@ export function CreateCustomFieldValueDrawer({
|
|
|
35
36
|
const {
|
|
36
37
|
clientContext: { cookie },
|
|
37
38
|
} = useBuyerPortal();
|
|
39
|
+
const { trackEntityCreated, trackEntityCreateError } = useAnalytics({
|
|
40
|
+
entityType: "custom_field",
|
|
41
|
+
defaultTimerName: "custom_field_creation",
|
|
42
|
+
shouldTrackDefaultTimer: isOpen,
|
|
43
|
+
});
|
|
38
44
|
|
|
39
45
|
const [search, setSearch] = useState<string | null>(null);
|
|
46
|
+
const [createdFieldName, setCreatedFieldName] = useState<string>("");
|
|
40
47
|
|
|
41
48
|
const {
|
|
42
49
|
mutate: createCustomFieldValueToUnitScope,
|
|
@@ -44,6 +51,18 @@ export function CreateCustomFieldValueDrawer({
|
|
|
44
51
|
} = useAddCustomFieldValueToUnitScope({
|
|
45
52
|
options: {
|
|
46
53
|
onSuccess: () => {
|
|
54
|
+
trackEntityCreated(
|
|
55
|
+
ANALYTICS_EVENTS.CUSTOM_FIELD_CREATED,
|
|
56
|
+
"custom_field",
|
|
57
|
+
{
|
|
58
|
+
custom_field_type: customField,
|
|
59
|
+
custom_field_name: createdFieldName,
|
|
60
|
+
is_shared: true,
|
|
61
|
+
org_unit_id: unitId,
|
|
62
|
+
contract_id: contractId,
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
47
66
|
pushToast({
|
|
48
67
|
message: `${customField} added successfully`,
|
|
49
68
|
status: "INFO",
|
|
@@ -52,11 +71,22 @@ export function CreateCustomFieldValueDrawer({
|
|
|
52
71
|
refetch();
|
|
53
72
|
close();
|
|
54
73
|
},
|
|
55
|
-
onError: (error) =>
|
|
74
|
+
onError: (error) => {
|
|
75
|
+
trackEntityCreateError(
|
|
76
|
+
ANALYTICS_EVENTS.CUSTOM_FIELD_CREATE_ERROR,
|
|
77
|
+
error,
|
|
78
|
+
{
|
|
79
|
+
custom_field_type: customField,
|
|
80
|
+
org_unit_id: unitId,
|
|
81
|
+
contract_id: contractId,
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
|
|
56
85
|
pushToast({
|
|
57
86
|
message: error.message,
|
|
58
87
|
status: "ERROR",
|
|
59
|
-
})
|
|
88
|
+
});
|
|
89
|
+
},
|
|
60
90
|
},
|
|
61
91
|
});
|
|
62
92
|
|
|
@@ -66,6 +96,18 @@ export function CreateCustomFieldValueDrawer({
|
|
|
66
96
|
} = useCreateCustomFieldValue({
|
|
67
97
|
options: {
|
|
68
98
|
onSuccess: () => {
|
|
99
|
+
trackEntityCreated(
|
|
100
|
+
ANALYTICS_EVENTS.CUSTOM_FIELD_CREATED,
|
|
101
|
+
"custom_field",
|
|
102
|
+
{
|
|
103
|
+
custom_field_type: customField,
|
|
104
|
+
custom_field_name: createdFieldName,
|
|
105
|
+
is_shared: false,
|
|
106
|
+
org_unit_id: unitId,
|
|
107
|
+
contract_id: contractId,
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
|
|
69
111
|
pushToast({
|
|
70
112
|
message: `${customField} added successfully`,
|
|
71
113
|
status: "INFO",
|
|
@@ -74,11 +116,22 @@ export function CreateCustomFieldValueDrawer({
|
|
|
74
116
|
refetch();
|
|
75
117
|
close();
|
|
76
118
|
},
|
|
77
|
-
onError: (error) =>
|
|
119
|
+
onError: (error) => {
|
|
120
|
+
trackEntityCreateError(
|
|
121
|
+
ANALYTICS_EVENTS.CUSTOM_FIELD_CREATE_ERROR,
|
|
122
|
+
error,
|
|
123
|
+
{
|
|
124
|
+
custom_field_type: customField,
|
|
125
|
+
org_unit_id: unitId,
|
|
126
|
+
contract_id: contractId,
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
|
|
78
130
|
pushToast({
|
|
79
131
|
message: error.message,
|
|
80
132
|
status: "ERROR",
|
|
81
|
-
})
|
|
133
|
+
});
|
|
134
|
+
},
|
|
82
135
|
},
|
|
83
136
|
});
|
|
84
137
|
|
|
@@ -104,6 +157,8 @@ export function CreateCustomFieldValueDrawer({
|
|
|
104
157
|
});
|
|
105
158
|
|
|
106
159
|
function create(name: string, customFieldValueId?: string) {
|
|
160
|
+
setCreatedFieldName(name);
|
|
161
|
+
|
|
107
162
|
if (customFieldValueId) {
|
|
108
163
|
return createCustomFieldValueToUnitScope({
|
|
109
164
|
data: {
|
|
@@ -2,11 +2,12 @@ import { useUI } from "@faststore/ui";
|
|
|
2
2
|
|
|
3
3
|
import { BasicDrawerProps } from "../../../shared/components";
|
|
4
4
|
import { DeleteEntityDrawer } from "../../../shared/components/CustomField/delete-custom-field/DeleteCustomFieldDrawer";
|
|
5
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
5
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
6
6
|
import {
|
|
7
7
|
useDeleteCustomFieldValue,
|
|
8
8
|
useDeleteCustomFieldValueToUnitScope,
|
|
9
9
|
} from "../../../shared/hooks/custom-field";
|
|
10
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
10
11
|
import { CustomFieldData } from "../../types";
|
|
11
12
|
|
|
12
13
|
export interface DeleteCustomFieldValueDrawerProps
|
|
@@ -36,12 +37,29 @@ export function DeleteCustomFieldValueDrawer({
|
|
|
36
37
|
const {
|
|
37
38
|
clientContext: { cookie },
|
|
38
39
|
} = useBuyerPortal();
|
|
40
|
+
const { trackEvent } = useAnalytics({
|
|
41
|
+
entityType: "custom_field",
|
|
42
|
+
entityId: currentData?.id,
|
|
43
|
+
defaultTimerName: "custom_field_delete",
|
|
44
|
+
shouldTrackDefaultTimer: !!currentData,
|
|
45
|
+
});
|
|
46
|
+
|
|
39
47
|
const {
|
|
40
48
|
mutate: deleteCustomFieldValueToUnitScope,
|
|
41
49
|
isLoading: isLoadingDeleteCustomFieldValueToUnitScope,
|
|
42
50
|
} = useDeleteCustomFieldValueToUnitScope({
|
|
43
51
|
options: {
|
|
44
52
|
onSuccess: () => {
|
|
53
|
+
trackEvent(ANALYTICS_EVENTS.CUSTOM_FIELD_DELETED, {
|
|
54
|
+
custom_field_type: customField,
|
|
55
|
+
custom_field_id: currentData?.id,
|
|
56
|
+
custom_field_name: currentData?.value,
|
|
57
|
+
delete_mode: "unitScope",
|
|
58
|
+
org_unit_id: unitId,
|
|
59
|
+
contract_id: contractId,
|
|
60
|
+
entity_type: "custom_field",
|
|
61
|
+
});
|
|
62
|
+
|
|
45
63
|
pushToast({
|
|
46
64
|
message: `${customField} removed successfully`,
|
|
47
65
|
status: "INFO",
|
|
@@ -50,11 +68,25 @@ export function DeleteCustomFieldValueDrawer({
|
|
|
50
68
|
close();
|
|
51
69
|
refetch();
|
|
52
70
|
},
|
|
53
|
-
onError: (error) =>
|
|
71
|
+
onError: (error) => {
|
|
72
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
73
|
+
|
|
74
|
+
trackEvent(ANALYTICS_EVENTS.CUSTOM_FIELD_DELETE_ERROR, {
|
|
75
|
+
entity_type: "custom_field",
|
|
76
|
+
entity_id: currentData?.id,
|
|
77
|
+
custom_field_type: customField,
|
|
78
|
+
custom_field_name: currentData?.value,
|
|
79
|
+
delete_mode: "unitScope",
|
|
80
|
+
org_unit_id: unitId,
|
|
81
|
+
contract_id: contractId,
|
|
82
|
+
error_message: errorMessage,
|
|
83
|
+
});
|
|
84
|
+
|
|
54
85
|
pushToast({
|
|
55
86
|
message: error.message,
|
|
56
87
|
status: "ERROR",
|
|
57
|
-
})
|
|
88
|
+
});
|
|
89
|
+
},
|
|
58
90
|
},
|
|
59
91
|
});
|
|
60
92
|
|
|
@@ -64,6 +96,16 @@ export function DeleteCustomFieldValueDrawer({
|
|
|
64
96
|
} = useDeleteCustomFieldValue({
|
|
65
97
|
options: {
|
|
66
98
|
onSuccess: () => {
|
|
99
|
+
trackEvent(ANALYTICS_EVENTS.CUSTOM_FIELD_DELETED, {
|
|
100
|
+
custom_field_type: customField,
|
|
101
|
+
custom_field_id: currentData?.id,
|
|
102
|
+
custom_field_name: currentData?.value,
|
|
103
|
+
delete_mode: "contract",
|
|
104
|
+
org_unit_id: unitId,
|
|
105
|
+
contract_id: contractId,
|
|
106
|
+
entity_type: "custom_field",
|
|
107
|
+
});
|
|
108
|
+
|
|
67
109
|
pushToast({
|
|
68
110
|
message: `${customField} deleted successfully`,
|
|
69
111
|
status: "INFO",
|
|
@@ -72,11 +114,25 @@ export function DeleteCustomFieldValueDrawer({
|
|
|
72
114
|
close();
|
|
73
115
|
refetch();
|
|
74
116
|
},
|
|
75
|
-
onError: (error) =>
|
|
117
|
+
onError: (error) => {
|
|
118
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
119
|
+
|
|
120
|
+
trackEvent(ANALYTICS_EVENTS.CUSTOM_FIELD_DELETE_ERROR, {
|
|
121
|
+
entity_type: "custom_field",
|
|
122
|
+
entity_id: currentData?.id,
|
|
123
|
+
custom_field_type: customField,
|
|
124
|
+
custom_field_name: currentData?.value,
|
|
125
|
+
delete_mode: "contract",
|
|
126
|
+
org_unit_id: unitId,
|
|
127
|
+
contract_id: contractId,
|
|
128
|
+
error_message: errorMessage,
|
|
129
|
+
});
|
|
130
|
+
|
|
76
131
|
pushToast({
|
|
77
132
|
message: error.message,
|
|
78
133
|
status: "ERROR",
|
|
79
|
-
})
|
|
134
|
+
});
|
|
135
|
+
},
|
|
80
136
|
},
|
|
81
137
|
});
|
|
82
138
|
|