@zeniai/client-epic-state 5.0.83-betaRR5 → 5.0.83
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/lib/entity/aiCfo/aiCfoPayload.d.ts +4 -1
- package/lib/entity/aiCfo/aiCfoReducer.js +17 -4
- package/lib/entity/aiCfo/aiCfoState.d.ts +19 -0
- package/lib/entity/aiCfo/aiCfoState.js +8 -1
- package/lib/entity/cardPolicy/cardPolicyReducer.js +99 -9
- package/lib/entity/cardPolicy/cardPolicySelector.js +4 -0
- package/lib/entity/cardPolicy/policyRecommendationFromUploadEpic.d.ts +2 -3
- package/lib/entity/cardPolicy/policyRecommendationFromUploadEpic.js +10 -4
- package/lib/epic.d.ts +12 -15
- package/lib/epic.js +12 -15
- package/lib/esm/entity/aiCfo/aiCfoReducer.js +18 -5
- package/lib/esm/entity/aiCfo/aiCfoState.js +7 -0
- package/lib/esm/entity/cardPolicy/cardPolicyReducer.js +99 -9
- package/lib/esm/entity/cardPolicy/cardPolicySelector.js +4 -0
- package/lib/esm/entity/cardPolicy/policyRecommendationFromUploadEpic.js +11 -5
- package/lib/esm/epic.js +12 -15
- package/lib/esm/index.js +6 -21
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +19 -138
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +0 -18
- package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.js +5 -38
- package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.js +0 -23
- package/lib/index.d.ts +7 -28
- package/lib/index.js +14 -68
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.d.ts +1 -40
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +20 -139
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.d.ts +0 -15
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +0 -20
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.d.ts +0 -28
- package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.d.ts +1 -7
- package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.js +6 -39
- package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.d.ts +0 -15
- package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.js +1 -26
- package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardState.d.ts +0 -16
- package/package.json +1 -1
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyAiCardPolicyFormDraftUpdate.js +0 -328
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToAiCardPolicyDraft.js +0 -120
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToDraftEpic.js +0 -60
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToManualCardPolicyDraft.js +0 -118
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyUploadPlanToAiCardPolicyDraft.js +0 -33
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildAiCardPolicyFormDraftSeed.js +0 -385
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildManualCardPolicyFormDraftSeed.js +0 -34
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyChipIds.js +0 -33
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyFormDraftTypes.js +0 -17
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyRequestParts.js +0 -144
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/deriveAiPolicyReviewRowsFromInputs.js +0 -148
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/seedAiCardPolicyFormDraftEpic.js +0 -112
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toBulkCardPolicyTemplateRequestsFromDraft.js +0 -101
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toCardPolicyTemplateRequestFromDraft.js +0 -71
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toManualCardPolicyTemplateRequestFromDraft.js +0 -34
- package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/aiCardCreationFormDraftTypes.js +0 -1
- package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/applyAiCardCreationFormDraftUpdate.js +0 -42
- package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/buildAiCardCreationFormDraftSeed.js +0 -69
- package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/deriveAiCardRowsFromTeams.js +0 -45
- package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/seedAiCardCreationFormDraftEpic.js +0 -65
- package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/toIssueChargeCardLocalDataFromDraft.js +0 -64
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyAiCardPolicyFormDraftUpdate.d.ts +0 -38
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyAiCardPolicyFormDraftUpdate.js +0 -333
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToAiCardPolicyDraft.d.ts +0 -25
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToAiCardPolicyDraft.js +0 -124
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToDraftEpic.d.ts +0 -28
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToDraftEpic.js +0 -64
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToManualCardPolicyDraft.d.ts +0 -17
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToManualCardPolicyDraft.js +0 -122
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyUploadPlanToAiCardPolicyDraft.d.ts +0 -23
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyUploadPlanToAiCardPolicyDraft.js +0 -37
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildAiCardPolicyFormDraftSeed.d.ts +0 -38
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildAiCardPolicyFormDraftSeed.js +0 -391
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildManualCardPolicyFormDraftSeed.d.ts +0 -11
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildManualCardPolicyFormDraftSeed.js +0 -38
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyChipIds.d.ts +0 -24
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyChipIds.js +0 -40
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyFormDraftTypes.d.ts +0 -253
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyFormDraftTypes.js +0 -21
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyRequestParts.d.ts +0 -66
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyRequestParts.js +0 -151
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/deriveAiPolicyReviewRowsFromInputs.d.ts +0 -30
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/deriveAiPolicyReviewRowsFromInputs.js +0 -152
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/seedAiCardPolicyFormDraftEpic.d.ts +0 -26
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/seedAiCardPolicyFormDraftEpic.js +0 -116
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toBulkCardPolicyTemplateRequestsFromDraft.d.ts +0 -35
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toBulkCardPolicyTemplateRequestsFromDraft.js +0 -105
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toCardPolicyTemplateRequestFromDraft.d.ts +0 -23
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toCardPolicyTemplateRequestFromDraft.js +0 -75
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toManualCardPolicyTemplateRequestFromDraft.d.ts +0 -15
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toManualCardPolicyTemplateRequestFromDraft.js +0 -38
- package/lib/view/spendManagement/chargeCards/issueChargeCard/aiCardCreationFormDraftTypes.d.ts +0 -76
- package/lib/view/spendManagement/chargeCards/issueChargeCard/aiCardCreationFormDraftTypes.js +0 -2
- package/lib/view/spendManagement/chargeCards/issueChargeCard/applyAiCardCreationFormDraftUpdate.d.ts +0 -7
- package/lib/view/spendManagement/chargeCards/issueChargeCard/applyAiCardCreationFormDraftUpdate.js +0 -46
- package/lib/view/spendManagement/chargeCards/issueChargeCard/buildAiCardCreationFormDraftSeed.d.ts +0 -28
- package/lib/view/spendManagement/chargeCards/issueChargeCard/buildAiCardCreationFormDraftSeed.js +0 -73
- package/lib/view/spendManagement/chargeCards/issueChargeCard/deriveAiCardRowsFromTeams.d.ts +0 -23
- package/lib/view/spendManagement/chargeCards/issueChargeCard/deriveAiCardRowsFromTeams.js +0 -49
- package/lib/view/spendManagement/chargeCards/issueChargeCard/seedAiCardCreationFormDraftEpic.d.ts +0 -11
- package/lib/view/spendManagement/chargeCards/issueChargeCard/seedAiCardCreationFormDraftEpic.js +0 -69
- package/lib/view/spendManagement/chargeCards/issueChargeCard/toIssueChargeCardLocalDataFromDraft.d.ts +0 -11
- package/lib/view/spendManagement/chargeCards/issueChargeCard/toIssueChargeCardLocalDataFromDraft.js +0 -68
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
import { ID } from '../../../../../commonStateTypes/common';
|
|
2
|
-
import { CardPolicyInitialData, CardPolicyUploadSource, CardPolicyWizardPlan } from '../../../../../entity/aiCfo/aiCfoState';
|
|
3
|
-
import { MccCategory } from '../../../../../entity/cardPolicy/cardPolicyState';
|
|
4
|
-
/**
|
|
5
|
-
* Canonical CES-side type aliases for the card-policy form primitives
|
|
6
|
-
* (both the AI CFO `CardPolicyInteractiveForm` and the manual
|
|
7
|
-
* `CardPolicyCreatePage`).
|
|
8
|
-
*
|
|
9
|
-
* The web-components form is a pure renderer that hydrates from
|
|
10
|
-
* `createCardPolicyState.aiCardPolicyFormDraft` (or
|
|
11
|
-
* `manualCardPolicyFormDraft`) and emits every change back via
|
|
12
|
-
* `onFormChange` → `updateAiCardPolicyFormDraft` /
|
|
13
|
-
* `updateManualCardPolicyFormDraft` (web-components rule #4).
|
|
14
|
-
*
|
|
15
|
-
* The AI-payload-side types (`CardPolicyInitialData`,
|
|
16
|
-
* `CardPolicyWizardPlan`, ...) live on `entity/aiCfo/aiCfoState.ts` and
|
|
17
|
-
* are consumed directly from there.
|
|
18
|
-
*/
|
|
19
|
-
export type ChipKind = 'positive' | 'negative' | 'avatar';
|
|
20
|
-
export type CardPolicyModeValue = 'strict' | 'flexible';
|
|
21
|
-
/**
|
|
22
|
-
* Stable id for the transaction-limit toggle row inside `limits`.
|
|
23
|
-
*/
|
|
24
|
-
export declare const CARD_POLICY_LIMIT_ROW_ID_TRANSACTION = "transactionLimit";
|
|
25
|
-
/**
|
|
26
|
-
* Stable id for the require-receipt toggle row inside `limits`.
|
|
27
|
-
*/
|
|
28
|
-
export declare const CARD_POLICY_LIMIT_ROW_ID_REQUIRE_RECEIPT = "requireReceipt";
|
|
29
|
-
/**
|
|
30
|
-
* Owner descriptor for the cards table row + the "Applied to Cards"
|
|
31
|
-
* avatar chip. Populated by the FE-fetched `cardsMasterList` (sourced
|
|
32
|
-
* from `chargeCardListState`), not by the AI payload.
|
|
33
|
-
*/
|
|
34
|
-
export interface CardPolicyOwnerSeed {
|
|
35
|
-
displayName: string;
|
|
36
|
-
userId: ID;
|
|
37
|
-
roleLabel?: string;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* RHF chip-cloud field value used by `AllowBlockChipPicker` for both
|
|
41
|
-
* vendors and categories. `isSelected === true` renders the item as a
|
|
42
|
-
* positive/negative tag (with `×` removal); `false` renders it as a
|
|
43
|
-
* `+ name` add chip.
|
|
44
|
-
*
|
|
45
|
-
* Category chips can map to multiple MCC codes; `optionalCodes` carries
|
|
46
|
-
* the full set, `optionalCode` keeps the singular fallback that the
|
|
47
|
-
* chip-label formatter (and AI-shipped `CardPolicyTagSeed`) reads.
|
|
48
|
-
*/
|
|
49
|
-
export interface CardPolicyChipFieldValue {
|
|
50
|
-
id: string;
|
|
51
|
-
isSelected: boolean;
|
|
52
|
-
label: string;
|
|
53
|
-
optionalCode?: string;
|
|
54
|
-
optionalCodes?: string[];
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Field value for a single `vendorPolicy` / `categoryPolicy` slice. The
|
|
58
|
-
* two `*Items` arrays hold the chip cloud for each side independently
|
|
59
|
-
* so toggling `mode` preserves per-side selections; the picker renders
|
|
60
|
-
* only the active side, and the wire mapping reads chips only from the
|
|
61
|
-
* side whose `mode` is currently active.
|
|
62
|
-
*/
|
|
63
|
-
export interface CardPolicyAllowBlockFieldValue {
|
|
64
|
-
allowItems: CardPolicyChipFieldValue[];
|
|
65
|
-
blockItems: CardPolicyChipFieldValue[];
|
|
66
|
-
mode: 'allow' | 'block';
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* RHF row for the cards table.
|
|
70
|
-
*/
|
|
71
|
-
export interface CardPolicyCardSelectionRow {
|
|
72
|
-
cardName: string;
|
|
73
|
-
id: ID;
|
|
74
|
-
isChecked: boolean;
|
|
75
|
-
last4: string;
|
|
76
|
-
limitAmount: number;
|
|
77
|
-
owner: CardPolicyOwnerSeed;
|
|
78
|
-
utilizationAmount: number;
|
|
79
|
-
limitCadence?: string;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Field value for a single limit row (transaction limit / require receipt).
|
|
83
|
-
*/
|
|
84
|
-
export interface CardPolicyLimitFieldValue {
|
|
85
|
-
id: string;
|
|
86
|
-
isEnabled: boolean;
|
|
87
|
-
amount?: number;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* RHF chip used by the review's expanded body. Same shape as the seed
|
|
91
|
-
* plus an `isSelected` flag so chips can flip into a deselected
|
|
92
|
-
* `+ name` add-back state without being removed from the row's chip
|
|
93
|
-
* group. `isSelected` defaults to `true` when undefined.
|
|
94
|
-
*
|
|
95
|
-
* - `cardIds` — set for avatar chips so submit can recover the
|
|
96
|
-
* underlying card ids (one avatar chip per owner; each owner may map
|
|
97
|
-
* to multiple cards).
|
|
98
|
-
* - `optionalCode` — set for category chips (raw MCC code) and for
|
|
99
|
-
* chips inside a `kind: "limits"` group (numeric amount as string).
|
|
100
|
-
* - `helperText` / `placeholder` — only consumed when the chip is
|
|
101
|
-
* rendered as a limits row.
|
|
102
|
-
*/
|
|
103
|
-
export interface CardPolicyReviewChip {
|
|
104
|
-
chipKind: ChipKind;
|
|
105
|
-
id: string;
|
|
106
|
-
label: string;
|
|
107
|
-
cardIds?: ID[];
|
|
108
|
-
helperText?: string;
|
|
109
|
-
isSelected?: boolean;
|
|
110
|
-
optionalCode?: string;
|
|
111
|
-
placeholder?: string;
|
|
112
|
-
}
|
|
113
|
-
export interface CardPolicyReviewChipGroup {
|
|
114
|
-
chips: CardPolicyReviewChip[];
|
|
115
|
-
id: string;
|
|
116
|
-
label: string;
|
|
117
|
-
/**
|
|
118
|
-
* Controls how the group's chips are rendered inside the review row's
|
|
119
|
-
* expanded body.
|
|
120
|
-
*
|
|
121
|
-
* - `"chips"` (default): chips render as tag / avatar pills with the
|
|
122
|
-
* `+N` width-based overflow indicator.
|
|
123
|
-
* - `"limits"`: each chip renders as its own row with a toggle (bound
|
|
124
|
-
* to `isSelected`), a currency input (bound to `optionalCode`).
|
|
125
|
-
*/
|
|
126
|
-
kind?: 'chips' | 'limits';
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* RHF row for the AI CFO Step 5 review (and the 1-step `auto` variant).
|
|
130
|
-
*/
|
|
131
|
-
export interface CardPolicyReviewRow {
|
|
132
|
-
chipGroups: CardPolicyReviewChipGroup[];
|
|
133
|
-
id: string;
|
|
134
|
-
isChecked: boolean;
|
|
135
|
-
name: string;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Single source-of-truth form draft for the AI CFO Card Policy
|
|
139
|
-
* interactive form. Mirrors RHF's `useForm` schema exactly so the
|
|
140
|
-
* component can `useForm({defaultValues: formDraft})` and emit every
|
|
141
|
-
* change back through `onFormChange`.
|
|
142
|
-
*
|
|
143
|
-
* Slice usage per `policyKind`:
|
|
144
|
-
* - `auto`: only `policiesReview` is meaningful — chip groups built
|
|
145
|
-
* directly from each `draftPolicies[i]` at seed time.
|
|
146
|
-
* - `guided`: every slice is meaningful; `policiesReview` is re-derived
|
|
147
|
-
* from source slices on every `updateAiCardPolicyFormDraft`.
|
|
148
|
-
* - `upload`: `cardSelections`, `limits`, `policiesReview` are
|
|
149
|
-
* meaningful; `vendorPolicy` / `categoryPolicy` stay empty (chips
|
|
150
|
-
* live in the review row's chip groups).
|
|
151
|
-
*/
|
|
152
|
-
export interface CardPolicyFormDraft {
|
|
153
|
-
cardSelections: CardPolicyCardSelectionRow[];
|
|
154
|
-
categoryPolicy: CardPolicyAllowBlockFieldValue;
|
|
155
|
-
limits: CardPolicyLimitFieldValue[];
|
|
156
|
-
policiesReview: CardPolicyReviewRow[];
|
|
157
|
-
policyKind: 'auto' | 'guided' | 'upload';
|
|
158
|
-
vendorPolicy: CardPolicyAllowBlockFieldValue;
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Single source-of-truth form draft for the manual
|
|
162
|
-
* `CardPolicyCreatePage`. Structural superset of the AI form draft
|
|
163
|
-
* minus `policyKind` and `policiesReview`, plus the manual-only
|
|
164
|
-
* `name` / `description` / `mode` fields.
|
|
165
|
-
*/
|
|
166
|
-
export interface CardPolicyCreateFormDraft {
|
|
167
|
-
cardSelections: CardPolicyCardSelectionRow[];
|
|
168
|
-
categoryPolicy: CardPolicyAllowBlockFieldValue;
|
|
169
|
-
description: string;
|
|
170
|
-
limits: CardPolicyLimitFieldValue[];
|
|
171
|
-
mode: CardPolicyModeValue;
|
|
172
|
-
name: string;
|
|
173
|
-
vendorPolicy: CardPolicyAllowBlockFieldValue;
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Identity-only descriptor for one policy in the Step 5 review list,
|
|
177
|
-
* derived from `CardPolicyWizardPlan.step5Review.draftPolicies`. Chip
|
|
178
|
-
* groups are NOT carried here — `deriveAiPolicyReviewRowsFromInputs`
|
|
179
|
-
* rebuilds them from live form state (guided) or
|
|
180
|
-
* `buildAiCardPolicyFormDraftSeed` pre-computes them (auto/upload).
|
|
181
|
-
*/
|
|
182
|
-
export interface CardPolicySuggestedPolicySeed {
|
|
183
|
-
id: string;
|
|
184
|
-
isChecked: boolean;
|
|
185
|
-
name: string;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Lookup row consumed by the seed/derive helpers when resolving MCC
|
|
189
|
-
* codes (`"6051"`) into category labels (`"Cryptocurrency"`). The
|
|
190
|
-
* `MccCategory` entity on `cardPolicyState` is structurally compatible.
|
|
191
|
-
*/
|
|
192
|
-
export interface MccCategoryLike {
|
|
193
|
-
mccCodes: string[];
|
|
194
|
-
name: string;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* BE-suggested chip seeds, sourced from the MCC categories endpoint.
|
|
198
|
-
* Used to pre-populate both sides of each `AllowBlock` field at seed
|
|
199
|
-
* time so the chip cloud renders with `isSelected: false` add-back
|
|
200
|
-
* affordances even before the user opens the search dropdown.
|
|
201
|
-
*/
|
|
202
|
-
export interface CardPolicyDefaultSeedSuggestions {
|
|
203
|
-
suggestedAllowCategories?: MccCategoryLike[];
|
|
204
|
-
suggestedAllowMerchants?: string[];
|
|
205
|
-
suggestedBlockCategories?: MccCategoryLike[];
|
|
206
|
-
suggestedBlockMerchants?: string[];
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Seed context retained on the slice so subsequent
|
|
210
|
-
* `updateAiCardPolicyFormDraft` dispatches can re-derive
|
|
211
|
-
* `policiesReview` chip groups (guided) or patch "Applied to Cards"
|
|
212
|
-
* (upload) without the component re-passing the full universe each tick.
|
|
213
|
-
*
|
|
214
|
-
* `suggestedPoliciesSeed` mirrors `wizardPlan.step5Review.draftPolicies`
|
|
215
|
-
* row identities (id + name + isChecked) for guided re-derivation.
|
|
216
|
-
* `wizardPlan` itself is kept so `applyUploadPlanToAiCardPolicyDraft`
|
|
217
|
-
* can re-seed `policiesReview` if a later
|
|
218
|
-
* `policy-recommendation-from-upload` response lands.
|
|
219
|
-
*/
|
|
220
|
-
export interface AiCardPolicyFormDraftSeedContext extends CardPolicyDefaultSeedSuggestions {
|
|
221
|
-
cardsMasterList: CardPolicyCardSelectionRow[];
|
|
222
|
-
categorySearchOptions: MccCategoryLike[];
|
|
223
|
-
policyKind: CardPolicyInitialData['policyKind'];
|
|
224
|
-
suggestedPoliciesSeed: CardPolicySuggestedPolicySeed[];
|
|
225
|
-
source?: CardPolicyUploadSource;
|
|
226
|
-
wizardPlan?: CardPolicyWizardPlan;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* FE-facing mirror of `ExtractedCardPolicyRules` on the cardPolicy
|
|
230
|
-
* entity slice. Re-declared here as the canonical view-side type so
|
|
231
|
-
* the AI and manual draft-apply helpers don't have to import from the
|
|
232
|
-
* entity module.
|
|
233
|
-
*/
|
|
234
|
-
export interface ExtractedCardPolicyDataView {
|
|
235
|
-
allowedEntity: {
|
|
236
|
-
categoryCodes: string[];
|
|
237
|
-
merchantNames: string[];
|
|
238
|
-
};
|
|
239
|
-
blockedEntity: {
|
|
240
|
-
categoryCodes: string[];
|
|
241
|
-
merchantNames: string[];
|
|
242
|
-
};
|
|
243
|
-
confidenceScore: number;
|
|
244
|
-
policyName: string;
|
|
245
|
-
requiredReceiptThreshold: number;
|
|
246
|
-
transactionLimit: number;
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Adapter so callers can hand the `MccCategory[]` array from
|
|
250
|
-
* `cardPolicyState.mccCategories` (or the suggested seeds) straight to
|
|
251
|
-
* the helpers expecting `MccCategoryLike[]`.
|
|
252
|
-
*/
|
|
253
|
-
export declare const toMccCategoryLike: (category: MccCategory) => MccCategoryLike;
|
package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyFormDraftTypes.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toMccCategoryLike = exports.CARD_POLICY_LIMIT_ROW_ID_REQUIRE_RECEIPT = exports.CARD_POLICY_LIMIT_ROW_ID_TRANSACTION = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Stable id for the transaction-limit toggle row inside `limits`.
|
|
6
|
-
*/
|
|
7
|
-
exports.CARD_POLICY_LIMIT_ROW_ID_TRANSACTION = 'transactionLimit';
|
|
8
|
-
/**
|
|
9
|
-
* Stable id for the require-receipt toggle row inside `limits`.
|
|
10
|
-
*/
|
|
11
|
-
exports.CARD_POLICY_LIMIT_ROW_ID_REQUIRE_RECEIPT = 'requireReceipt';
|
|
12
|
-
/**
|
|
13
|
-
* Adapter so callers can hand the `MccCategory[]` array from
|
|
14
|
-
* `cardPolicyState.mccCategories` (or the suggested seeds) straight to
|
|
15
|
-
* the helpers expecting `MccCategoryLike[]`.
|
|
16
|
-
*/
|
|
17
|
-
const toMccCategoryLike = (category) => ({
|
|
18
|
-
name: category.name,
|
|
19
|
-
mccCodes: category.mccCodes,
|
|
20
|
-
});
|
|
21
|
-
exports.toMccCategoryLike = toMccCategoryLike;
|
package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyRequestParts.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { ID } from '../../../../../commonStateTypes/common';
|
|
2
|
-
import { CardPolicyAllowBlockFieldValue, CardPolicyLimitFieldValue, CardPolicyReviewRow } from './cardPolicyFormDraftTypes';
|
|
3
|
-
/**
|
|
4
|
-
* Shared helpers for building the wire-ready
|
|
5
|
-
* `CreateCardPolicyTemplateRequest` payload from either the manual
|
|
6
|
-
* `CardPolicyCreateFormDraft` or the AI CFO `CardPolicyFormDraft`.
|
|
7
|
-
* Both forms emit the same `vendorPolicy` / `categoryPolicy` /
|
|
8
|
-
* `limits` slices, so the mapping primitives are factored out here.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Project the merchant names (chip `label`) selected on the given
|
|
12
|
-
* allow / block field, but only when the field's `mode` matches
|
|
13
|
-
* `forMode`. The other side's chips are preserved in form state for
|
|
14
|
-
* fast mode-flip but never belong on the wire for the current submit.
|
|
15
|
-
*/
|
|
16
|
-
export declare const collectMerchantNames: (field: CardPolicyAllowBlockFieldValue, forMode: "allow" | "block") => string[];
|
|
17
|
-
/**
|
|
18
|
-
* Project the MCC codes selected on the given allow / block field.
|
|
19
|
-
* Chips with `optionalCodes` emit every code; chips lacking the plural
|
|
20
|
-
* fall back to the singular `optionalCode`. Chips with neither are
|
|
21
|
-
* dropped silently.
|
|
22
|
-
*/
|
|
23
|
-
export declare const collectCategoryCodes: (field: CardPolicyAllowBlockFieldValue, forMode: "allow" | "block") => string[];
|
|
24
|
-
/**
|
|
25
|
-
* `null` when the toggle is off (BE treats `null` as "no threshold");
|
|
26
|
-
* otherwise the row's `amount` (or `0` when unset but the toggle is on).
|
|
27
|
-
*/
|
|
28
|
-
export declare const amountFromLimitRow: (limits: CardPolicyLimitFieldValue[], rowId: string) => number | null;
|
|
29
|
-
export interface CardPolicyReviewRowRequestParts {
|
|
30
|
-
allowedEntity: {
|
|
31
|
-
categoryCodes: string[];
|
|
32
|
-
merchantNames: string[];
|
|
33
|
-
};
|
|
34
|
-
applyToCards: ID[];
|
|
35
|
-
blockedEntity: {
|
|
36
|
-
categoryCodes: string[];
|
|
37
|
-
merchantNames: string[];
|
|
38
|
-
};
|
|
39
|
-
requiredReceiptThreshold: number | null;
|
|
40
|
-
spendLimits: {
|
|
41
|
-
transaction: number | null;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Project a single `auto`-mode review row's chip groups into the wire
|
|
46
|
-
* shape. Used by the AI CFO wire builder when `policyKind === "auto"`,
|
|
47
|
-
* where the source slices are empty and the row's `chipGroups` are
|
|
48
|
-
* canonical.
|
|
49
|
-
*/
|
|
50
|
-
export declare const projectAutoReviewRowToCardPolicyRequestParts: (row: CardPolicyReviewRow) => CardPolicyReviewRowRequestParts;
|
|
51
|
-
/**
|
|
52
|
-
* Group-id constants used by both auto and bulk wire builders. Exported
|
|
53
|
-
* so the bulk builder can mirror the contract without re-declaring.
|
|
54
|
-
*/
|
|
55
|
-
export declare const REVIEW_GROUP_IDS: {
|
|
56
|
-
readonly allowedVendors: "allowed-vendors";
|
|
57
|
-
readonly blockedVendors: "blocked-vendors";
|
|
58
|
-
readonly allowedCategories: "allowed-categories";
|
|
59
|
-
readonly restrictedCategories: "restricted-categories";
|
|
60
|
-
readonly appliedToCards: "applied-to-cards";
|
|
61
|
-
readonly limits: "limits";
|
|
62
|
-
};
|
|
63
|
-
export declare const REVIEW_LIMIT_CHIP_IDS: {
|
|
64
|
-
readonly transaction: "limit-transaction";
|
|
65
|
-
readonly receipt: "limit-receipt";
|
|
66
|
-
};
|
package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyRequestParts.js
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.REVIEW_LIMIT_CHIP_IDS = exports.REVIEW_GROUP_IDS = exports.projectAutoReviewRowToCardPolicyRequestParts = exports.amountFromLimitRow = exports.collectCategoryCodes = exports.collectMerchantNames = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Shared helpers for building the wire-ready
|
|
6
|
-
* `CreateCardPolicyTemplateRequest` payload from either the manual
|
|
7
|
-
* `CardPolicyCreateFormDraft` or the AI CFO `CardPolicyFormDraft`.
|
|
8
|
-
* Both forms emit the same `vendorPolicy` / `categoryPolicy` /
|
|
9
|
-
* `limits` slices, so the mapping primitives are factored out here.
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* Project the merchant names (chip `label`) selected on the given
|
|
13
|
-
* allow / block field, but only when the field's `mode` matches
|
|
14
|
-
* `forMode`. The other side's chips are preserved in form state for
|
|
15
|
-
* fast mode-flip but never belong on the wire for the current submit.
|
|
16
|
-
*/
|
|
17
|
-
const collectMerchantNames = (field, forMode) => {
|
|
18
|
-
if (field.mode !== forMode) {
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
const items = forMode === 'allow' ? field.allowItems : field.blockItems;
|
|
22
|
-
return items.filter((item) => item.isSelected).map((item) => item.label);
|
|
23
|
-
};
|
|
24
|
-
exports.collectMerchantNames = collectMerchantNames;
|
|
25
|
-
/**
|
|
26
|
-
* Project the MCC codes selected on the given allow / block field.
|
|
27
|
-
* Chips with `optionalCodes` emit every code; chips lacking the plural
|
|
28
|
-
* fall back to the singular `optionalCode`. Chips with neither are
|
|
29
|
-
* dropped silently.
|
|
30
|
-
*/
|
|
31
|
-
const collectCategoryCodes = (field, forMode) => {
|
|
32
|
-
if (field.mode !== forMode) {
|
|
33
|
-
return [];
|
|
34
|
-
}
|
|
35
|
-
const items = forMode === 'allow' ? field.allowItems : field.blockItems;
|
|
36
|
-
return items
|
|
37
|
-
.filter((item) => item.isSelected)
|
|
38
|
-
.flatMap((item) => {
|
|
39
|
-
if (item.optionalCodes != null && item.optionalCodes.length > 0) {
|
|
40
|
-
return item.optionalCodes;
|
|
41
|
-
}
|
|
42
|
-
return item.optionalCode != null ? [item.optionalCode] : [];
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
exports.collectCategoryCodes = collectCategoryCodes;
|
|
46
|
-
/**
|
|
47
|
-
* `null` when the toggle is off (BE treats `null` as "no threshold");
|
|
48
|
-
* otherwise the row's `amount` (or `0` when unset but the toggle is on).
|
|
49
|
-
*/
|
|
50
|
-
const amountFromLimitRow = (limits, rowId) => {
|
|
51
|
-
const row = limits.find((entry) => entry.id === rowId);
|
|
52
|
-
if (row == null || !row.isEnabled) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
return row.amount ?? 0;
|
|
56
|
-
};
|
|
57
|
-
exports.amountFromLimitRow = amountFromLimitRow;
|
|
58
|
-
const REVIEW_GROUP_ID_ALLOWED_VENDORS = 'allowed-vendors';
|
|
59
|
-
const REVIEW_GROUP_ID_BLOCKED_VENDORS = 'blocked-vendors';
|
|
60
|
-
const REVIEW_GROUP_ID_ALLOWED_CATEGORIES = 'allowed-categories';
|
|
61
|
-
const REVIEW_GROUP_ID_RESTRICTED_CATEGORIES = 'restricted-categories';
|
|
62
|
-
const REVIEW_GROUP_ID_APPLIED_TO_CARDS = 'applied-to-cards';
|
|
63
|
-
const REVIEW_GROUP_ID_LIMITS = 'limits';
|
|
64
|
-
const REVIEW_LIMIT_CHIP_ID_TRANSACTION = 'limit-transaction';
|
|
65
|
-
const REVIEW_LIMIT_CHIP_ID_RECEIPT = 'limit-receipt';
|
|
66
|
-
const isChipOn = (chip) => chip.isSelected !== false;
|
|
67
|
-
const findGroup = (row, groupId) => row.chipGroups.find((group) => group.id === groupId);
|
|
68
|
-
const projectMerchantNamesFromGroup = (group) => group == null ? [] : group.chips.filter(isChipOn).map((chip) => chip.label);
|
|
69
|
-
const projectCategoryCodesFromGroup = (group) => {
|
|
70
|
-
if (group == null) {
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
73
|
-
const codes = [];
|
|
74
|
-
for (const chip of group.chips) {
|
|
75
|
-
if (!isChipOn(chip)) {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (chip.optionalCode != null && chip.optionalCode.length > 0) {
|
|
79
|
-
codes.push(chip.optionalCode);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return codes;
|
|
83
|
-
};
|
|
84
|
-
const projectApplyToCardsFromGroup = (group) => {
|
|
85
|
-
if (group == null) {
|
|
86
|
-
return [];
|
|
87
|
-
}
|
|
88
|
-
const cardIds = [];
|
|
89
|
-
for (const chip of group.chips) {
|
|
90
|
-
if (!isChipOn(chip)) {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
if (chip.cardIds != null && chip.cardIds.length > 0) {
|
|
94
|
-
cardIds.push(...chip.cardIds);
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
cardIds.push(chip.id);
|
|
98
|
-
}
|
|
99
|
-
return cardIds;
|
|
100
|
-
};
|
|
101
|
-
const amountFromLimitsChip = (chip) => {
|
|
102
|
-
if (chip == null || chip.isSelected !== true) {
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
if (chip.optionalCode == null || chip.optionalCode.length === 0) {
|
|
106
|
-
return 0;
|
|
107
|
-
}
|
|
108
|
-
const parsed = Number(chip.optionalCode);
|
|
109
|
-
return Number.isFinite(parsed) ? parsed : 0;
|
|
110
|
-
};
|
|
111
|
-
/**
|
|
112
|
-
* Project a single `auto`-mode review row's chip groups into the wire
|
|
113
|
-
* shape. Used by the AI CFO wire builder when `policyKind === "auto"`,
|
|
114
|
-
* where the source slices are empty and the row's `chipGroups` are
|
|
115
|
-
* canonical.
|
|
116
|
-
*/
|
|
117
|
-
const projectAutoReviewRowToCardPolicyRequestParts = (row) => {
|
|
118
|
-
const limitsGroup = findGroup(row, REVIEW_GROUP_ID_LIMITS);
|
|
119
|
-
const transactionChip = limitsGroup?.chips.find((chip) => chip.id === REVIEW_LIMIT_CHIP_ID_TRANSACTION);
|
|
120
|
-
const receiptChip = limitsGroup?.chips.find((chip) => chip.id === REVIEW_LIMIT_CHIP_ID_RECEIPT);
|
|
121
|
-
return {
|
|
122
|
-
allowedEntity: {
|
|
123
|
-
merchantNames: projectMerchantNamesFromGroup(findGroup(row, REVIEW_GROUP_ID_ALLOWED_VENDORS)),
|
|
124
|
-
categoryCodes: projectCategoryCodesFromGroup(findGroup(row, REVIEW_GROUP_ID_ALLOWED_CATEGORIES)),
|
|
125
|
-
},
|
|
126
|
-
blockedEntity: {
|
|
127
|
-
merchantNames: projectMerchantNamesFromGroup(findGroup(row, REVIEW_GROUP_ID_BLOCKED_VENDORS)),
|
|
128
|
-
categoryCodes: projectCategoryCodesFromGroup(findGroup(row, REVIEW_GROUP_ID_RESTRICTED_CATEGORIES)),
|
|
129
|
-
},
|
|
130
|
-
applyToCards: projectApplyToCardsFromGroup(findGroup(row, REVIEW_GROUP_ID_APPLIED_TO_CARDS)),
|
|
131
|
-
spendLimits: { transaction: amountFromLimitsChip(transactionChip) },
|
|
132
|
-
requiredReceiptThreshold: amountFromLimitsChip(receiptChip),
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
|
-
exports.projectAutoReviewRowToCardPolicyRequestParts = projectAutoReviewRowToCardPolicyRequestParts;
|
|
136
|
-
/**
|
|
137
|
-
* Group-id constants used by both auto and bulk wire builders. Exported
|
|
138
|
-
* so the bulk builder can mirror the contract without re-declaring.
|
|
139
|
-
*/
|
|
140
|
-
exports.REVIEW_GROUP_IDS = {
|
|
141
|
-
allowedVendors: REVIEW_GROUP_ID_ALLOWED_VENDORS,
|
|
142
|
-
blockedVendors: REVIEW_GROUP_ID_BLOCKED_VENDORS,
|
|
143
|
-
allowedCategories: REVIEW_GROUP_ID_ALLOWED_CATEGORIES,
|
|
144
|
-
restrictedCategories: REVIEW_GROUP_ID_RESTRICTED_CATEGORIES,
|
|
145
|
-
appliedToCards: REVIEW_GROUP_ID_APPLIED_TO_CARDS,
|
|
146
|
-
limits: REVIEW_GROUP_ID_LIMITS,
|
|
147
|
-
};
|
|
148
|
-
exports.REVIEW_LIMIT_CHIP_IDS = {
|
|
149
|
-
transaction: REVIEW_LIMIT_CHIP_ID_TRANSACTION,
|
|
150
|
-
receipt: REVIEW_LIMIT_CHIP_ID_RECEIPT,
|
|
151
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { CardPolicyAllowBlockFieldValue, CardPolicyCardSelectionRow, CardPolicyLimitFieldValue, CardPolicyReviewRow, CardPolicySuggestedPolicySeed } from './cardPolicyFormDraftTypes';
|
|
2
|
-
export interface DeriveAiPolicyReviewRowsFromInputsArgs {
|
|
3
|
-
cardSelections: CardPolicyCardSelectionRow[];
|
|
4
|
-
categoryPolicy: CardPolicyAllowBlockFieldValue;
|
|
5
|
-
limits: CardPolicyLimitFieldValue[];
|
|
6
|
-
/**
|
|
7
|
-
* Existing review rows from the prior draft. User edits to
|
|
8
|
-
* checked-state are preserved when the source row still exists;
|
|
9
|
-
* chip-level `isSelected` flags are preserved across rebuilds.
|
|
10
|
-
*/
|
|
11
|
-
prevPoliciesReview: CardPolicyReviewRow[];
|
|
12
|
-
/**
|
|
13
|
-
* Identity-only seed (id + name + isChecked). One output row per
|
|
14
|
-
* seed entry, in the same order.
|
|
15
|
-
*/
|
|
16
|
-
suggestedPoliciesSeed: CardPolicySuggestedPolicySeed[];
|
|
17
|
-
vendorPolicy: CardPolicyAllowBlockFieldValue;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Compose the Step 5 review rows from the live Step 1–4 form state.
|
|
21
|
-
*
|
|
22
|
-
* - One row per `suggestedPoliciesSeed` entry, in the same order.
|
|
23
|
-
* - Per-row `isChecked` preserved from `prevPoliciesReview`; otherwise
|
|
24
|
-
* falls back to the seed value.
|
|
25
|
-
* - Chip groups rebuilt from the live vendor / category / card / limit
|
|
26
|
-
* slices, with per-chip `isSelected` merged from the previous build
|
|
27
|
-
* so user-removed (`+ name`) chips don't snap back when an upstream
|
|
28
|
-
* slice changes.
|
|
29
|
-
*/
|
|
30
|
-
export declare const deriveAiPolicyReviewRowsFromInputs: ({ vendorPolicy, categoryPolicy, cardSelections, limits, suggestedPoliciesSeed, prevPoliciesReview, }: DeriveAiPolicyReviewRowsFromInputsArgs) => CardPolicyReviewRow[];
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deriveAiPolicyReviewRowsFromInputs = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Compose the Step 5 review rows from the live Step 1–4 form state.
|
|
6
|
-
*
|
|
7
|
-
* - One row per `suggestedPoliciesSeed` entry, in the same order.
|
|
8
|
-
* - Per-row `isChecked` preserved from `prevPoliciesReview`; otherwise
|
|
9
|
-
* falls back to the seed value.
|
|
10
|
-
* - Chip groups rebuilt from the live vendor / category / card / limit
|
|
11
|
-
* slices, with per-chip `isSelected` merged from the previous build
|
|
12
|
-
* so user-removed (`+ name`) chips don't snap back when an upstream
|
|
13
|
-
* slice changes.
|
|
14
|
-
*/
|
|
15
|
-
const deriveAiPolicyReviewRowsFromInputs = ({ vendorPolicy, categoryPolicy, cardSelections, limits, suggestedPoliciesSeed, prevPoliciesReview, }) => {
|
|
16
|
-
const prevById = new Map(prevPoliciesReview.map((row) => [row.id, row]));
|
|
17
|
-
const groups = deriveSharedChipGroups({
|
|
18
|
-
vendorPolicy,
|
|
19
|
-
categoryPolicy,
|
|
20
|
-
cardSelections,
|
|
21
|
-
limits,
|
|
22
|
-
});
|
|
23
|
-
return suggestedPoliciesSeed.map((seed) => {
|
|
24
|
-
const previous = prevById.get(seed.id);
|
|
25
|
-
return {
|
|
26
|
-
id: seed.id,
|
|
27
|
-
name: seed.name,
|
|
28
|
-
isChecked: previous?.isChecked ?? seed.isChecked,
|
|
29
|
-
chipGroups: previous != null
|
|
30
|
-
? mergeChipSelections(groups, previous.chipGroups)
|
|
31
|
-
: groups,
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
exports.deriveAiPolicyReviewRowsFromInputs = deriveAiPolicyReviewRowsFromInputs;
|
|
36
|
-
const mergeChipSelections = (next, prev) => {
|
|
37
|
-
const prevByGroupId = new Map(prev.map((group) => [group.id, group]));
|
|
38
|
-
return next.map((group) => {
|
|
39
|
-
const prevGroup = prevByGroupId.get(group.id);
|
|
40
|
-
if (prevGroup == null) {
|
|
41
|
-
return group;
|
|
42
|
-
}
|
|
43
|
-
const prevSelectedById = new Map(prevGroup.chips.map((chip) => [chip.id, chip.isSelected]));
|
|
44
|
-
return {
|
|
45
|
-
...group,
|
|
46
|
-
chips: group.chips.map((chip) => {
|
|
47
|
-
const prevSelected = prevSelectedById.get(chip.id);
|
|
48
|
-
return prevSelected === undefined
|
|
49
|
-
? chip
|
|
50
|
-
: { ...chip, isSelected: prevSelected };
|
|
51
|
-
}),
|
|
52
|
-
};
|
|
53
|
-
});
|
|
54
|
-
};
|
|
55
|
-
const deriveSharedChipGroups = ({ vendorPolicy, categoryPolicy, cardSelections, limits, }) => {
|
|
56
|
-
const groups = [];
|
|
57
|
-
const vendorChips = chipsFromAllowBlock(vendorPolicy);
|
|
58
|
-
if (vendorChips.length > 0) {
|
|
59
|
-
groups.push({
|
|
60
|
-
id: 'vendors',
|
|
61
|
-
label: vendorPolicy.mode === 'allow' ? 'Allowed vendors' : 'Blocked vendors',
|
|
62
|
-
chips: vendorChips,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
const categoryChips = chipsFromAllowBlock(categoryPolicy);
|
|
66
|
-
if (categoryChips.length > 0) {
|
|
67
|
-
groups.push({
|
|
68
|
-
id: 'categories',
|
|
69
|
-
label: categoryPolicy.mode === 'allow'
|
|
70
|
-
? 'Allowed categories'
|
|
71
|
-
: 'Blocked categories',
|
|
72
|
-
chips: categoryChips,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
const cardChips = cardSelections
|
|
76
|
-
.filter((row) => row.isChecked)
|
|
77
|
-
.map((row) => ({
|
|
78
|
-
id: row.id,
|
|
79
|
-
label: row.owner.displayName,
|
|
80
|
-
chipKind: 'avatar',
|
|
81
|
-
}));
|
|
82
|
-
if (cardChips.length > 0) {
|
|
83
|
-
groups.push({ id: 'cardholders', label: 'Cardholders', chips: cardChips });
|
|
84
|
-
}
|
|
85
|
-
const limitChips = limits.map((row) => ({
|
|
86
|
-
id: limitChipIdForRowId(row.id),
|
|
87
|
-
label: limitDisplayLabelForRowId(row.id),
|
|
88
|
-
helperText: limitHelperTextForRowId(row.id),
|
|
89
|
-
placeholder: '$0',
|
|
90
|
-
chipKind: 'positive',
|
|
91
|
-
isSelected: row.isEnabled,
|
|
92
|
-
optionalCode: row.isEnabled && row.amount != null ? String(row.amount) : undefined,
|
|
93
|
-
}));
|
|
94
|
-
if (limitChips.length > 0) {
|
|
95
|
-
groups.push({
|
|
96
|
-
id: 'limits',
|
|
97
|
-
label: 'Limits',
|
|
98
|
-
kind: 'limits',
|
|
99
|
-
chips: limitChips,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
return groups;
|
|
103
|
-
};
|
|
104
|
-
const chipsFromAllowBlock = (field) => {
|
|
105
|
-
const items = field.mode === 'allow' ? field.allowItems : field.blockItems;
|
|
106
|
-
return items
|
|
107
|
-
.filter((item) => item.isSelected)
|
|
108
|
-
.map((item) => ({
|
|
109
|
-
id: item.id,
|
|
110
|
-
label: item.optionalCode != null
|
|
111
|
-
? `${item.label} (${item.optionalCode})`
|
|
112
|
-
: item.label,
|
|
113
|
-
chipKind: field.mode === 'allow' ? 'positive' : 'negative',
|
|
114
|
-
}));
|
|
115
|
-
};
|
|
116
|
-
const limitChipIdForRowId = (rowId) => {
|
|
117
|
-
if (rowId === 'transactionLimit') {
|
|
118
|
-
return 'limit-transaction';
|
|
119
|
-
}
|
|
120
|
-
if (rowId === 'requireReceipt') {
|
|
121
|
-
return 'limit-receipt';
|
|
122
|
-
}
|
|
123
|
-
return rowId;
|
|
124
|
-
};
|
|
125
|
-
const limitDisplayLabelForRowId = (rowId) => {
|
|
126
|
-
if (rowId === 'transactionLimit') {
|
|
127
|
-
return 'Transaction Limit';
|
|
128
|
-
}
|
|
129
|
-
if (rowId === 'requireReceipt') {
|
|
130
|
-
return 'Require Receipt';
|
|
131
|
-
}
|
|
132
|
-
return humanizeLimitId(rowId);
|
|
133
|
-
};
|
|
134
|
-
const limitHelperTextForRowId = (rowId) => {
|
|
135
|
-
if (rowId === 'transactionLimit') {
|
|
136
|
-
return 'Maximum amount per single transaction';
|
|
137
|
-
}
|
|
138
|
-
if (rowId === 'requireReceipt') {
|
|
139
|
-
return 'Require a receipt above this amount';
|
|
140
|
-
}
|
|
141
|
-
return undefined;
|
|
142
|
-
};
|
|
143
|
-
const humanizeLimitId = (id) => {
|
|
144
|
-
const spaced = id
|
|
145
|
-
.replace(/([A-Z])/g, ' $1')
|
|
146
|
-
.replace(/[_-]+/g, ' ')
|
|
147
|
-
.trim();
|
|
148
|
-
if (spaced.length === 0) {
|
|
149
|
-
return id;
|
|
150
|
-
}
|
|
151
|
-
return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
|
|
152
|
-
};
|