nucleus-core-ts 0.10.130 → 0.10.131
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/dist/.build-ok +1 -1
- package/dist/fe/components/VerificationFlowPage/components/PendingTab.js +12 -0
- package/dist/fe/components/VerificationFlowPage/components/VerificationEntityList.d.ts +14 -2
- package/dist/fe/components/VerificationFlowPage/components/VerificationEntityList.js +64 -1
- package/dist/fe/components/VerificationFlowPage/components/VerificationFlowPage.d.ts +1 -1
- package/dist/fe/components/VerificationFlowPage/components/VerificationFlowPage.js +9 -2
- package/dist/fe/components/VerificationFlowPage/labels.d.ts +9 -0
- package/dist/fe/components/VerificationFlowPage/labels.js +8 -0
- package/dist/fe/components/VerificationFlowPage/theme/index.d.ts +11 -0
- package/dist/fe/components/VerificationFlowPage/theme/index.js +6 -2
- package/dist/fe/components/VerificationFlowPage/types/index.d.ts +15 -0
- package/dist/index.js +1 -1
- package/dist/server.js +1 -1
- package/dist/src/Client/ApiCaller/types.d.ts +23 -0
- package/dist/src/Services/Verification/types.d.ts +50 -1
- package/package.json +1 -1
package/dist/.build-ok
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.10.
|
|
1
|
+
0.10.131
|
|
@@ -281,6 +281,18 @@ export function PendingTab({ pendingAction, decideAction, uploadSignatureAction,
|
|
|
281
281
|
store.decidingId === item.instance_id ? /*#__PURE__*/ _jsxs("div", {
|
|
282
282
|
className: theme.pending.card.actions,
|
|
283
283
|
children: [
|
|
284
|
+
typeof item.pass_no === 'number' && typeof item.max_passes === 'number' ? /*#__PURE__*/ _jsxs("p", {
|
|
285
|
+
className: theme.pending.card.decisionMeta,
|
|
286
|
+
children: [
|
|
287
|
+
item.max_passes > 1 ? say.pendingRound(item.pass_no, item.max_passes) : null,
|
|
288
|
+
item.max_passes > 1 ? ' · ' : null,
|
|
289
|
+
item.rejection_sends_back_to ? say.pendingRejectSendsBack(say.stepOption(item.rejection_sends_back_to.step_order, item.rejection_sends_back_to.step_name)) : say.pendingRejectEndsReview
|
|
290
|
+
]
|
|
291
|
+
}) : null,
|
|
292
|
+
item.is_last_pass === true && (item.max_passes ?? 1) > 1 ? /*#__PURE__*/ _jsx("p", {
|
|
293
|
+
className: theme.pending.card.lastRoundWarning,
|
|
294
|
+
children: say.pendingLastRoundWarning
|
|
295
|
+
}) : null,
|
|
284
296
|
item.require_signature ? /*#__PURE__*/ _jsxs("label", {
|
|
285
297
|
className: "flex flex-col gap-1 text-xs",
|
|
286
298
|
children: [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { VerificationFlowLabels } from '../labels';
|
|
2
|
-
import type { VerificationBulkStatusItem, VerificationCancelAction, VerificationEntityStatusesAction } from '../types';
|
|
2
|
+
import type { VerificationBulkStatusItem, VerificationCancelAction, VerificationEntityStatusesAction, VerificationStartForEntityAction } from '../types';
|
|
3
3
|
export type VerificationEntityListTheme = {
|
|
4
4
|
container: string;
|
|
5
5
|
header: string;
|
|
@@ -52,5 +52,17 @@ export type VerificationEntityListProps = {
|
|
|
52
52
|
* now the API had one and the product offered none.
|
|
53
53
|
*/
|
|
54
54
|
cancelAction?: VerificationCancelAction;
|
|
55
|
+
/**
|
|
56
|
+
* Puts a record back into review.
|
|
57
|
+
*
|
|
58
|
+
* It was declared on the page's props, passed in by the panel, and never
|
|
59
|
+
* destructured anywhere — so on a flow with `trigger_on: 'manual'` there was
|
|
60
|
+
* no way from the product to start a review at all. This list is the one
|
|
61
|
+
* screen that knows which chains have FINISHED, so a rejected record that has
|
|
62
|
+
* since been corrected gets its next review here. A record that has never
|
|
63
|
+
* been reviewed does not appear in this list (it is built from instances), so
|
|
64
|
+
* its first review still starts from the record's own screen.
|
|
65
|
+
*/
|
|
66
|
+
startForEntityAction?: VerificationStartForEntityAction;
|
|
55
67
|
};
|
|
56
|
-
export declare function VerificationEntityList({ entityName, entityStatusesAction, theme: themeOverrides, themeMode, onEntityClick, pageSize, labels, cancelAction, }: VerificationEntityListProps): import("react/jsx-runtime").JSX.Element;
|
|
68
|
+
export declare function VerificationEntityList({ entityName, entityStatusesAction, theme: themeOverrides, themeMode, onEntityClick, pageSize, labels, cancelAction, startForEntityAction, }: VerificationEntityListProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -97,7 +97,7 @@ const lightTheme = {
|
|
|
97
97
|
};
|
|
98
98
|
return map[status] ?? status;
|
|
99
99
|
}
|
|
100
|
-
export function VerificationEntityList({ entityName, entityStatusesAction, theme: themeOverrides, themeMode = 'dark', onEntityClick, pageSize = 20, labels, cancelAction }) {
|
|
100
|
+
export function VerificationEntityList({ entityName, entityStatusesAction, theme: themeOverrides, themeMode = 'dark', onEntityClick, pageSize = 20, labels, cancelAction, startForEntityAction }) {
|
|
101
101
|
const baseTheme = themeMode === 'light' ? lightTheme : darkTheme;
|
|
102
102
|
const t = {
|
|
103
103
|
...baseTheme,
|
|
@@ -113,6 +113,50 @@ export function VerificationEntityList({ entityName, entityStatusesAction, theme
|
|
|
113
113
|
const [cancellingId, setCancellingId] = useState(null);
|
|
114
114
|
const [cancelReason, setCancelReason] = useState('');
|
|
115
115
|
const [cancelNote, setCancelNote] = useState(null);
|
|
116
|
+
// Which row is being sent back into review, and what it was told.
|
|
117
|
+
const [startingId, setStartingId] = useState(null);
|
|
118
|
+
const [startNote, setStartNote] = useState(null);
|
|
119
|
+
const startAgain = useEffectEvent((item)=>{
|
|
120
|
+
if (!startForEntityAction) return;
|
|
121
|
+
setStartingId(item.instance_id);
|
|
122
|
+
setStartNote(null);
|
|
123
|
+
startForEntityAction.start({
|
|
124
|
+
payload: {
|
|
125
|
+
entity_name: item.entity_name,
|
|
126
|
+
entity_id: item.entity_id
|
|
127
|
+
},
|
|
128
|
+
onAfterHandle: (res)=>{
|
|
129
|
+
setStartingId(null);
|
|
130
|
+
const r = res;
|
|
131
|
+
/*
|
|
132
|
+
* The engine has plenty of legitimate reasons to refuse — no live flow
|
|
133
|
+
* for this entity, the first step resolves to nobody, a chain is
|
|
134
|
+
* already running — and each one is a sentence. Shown on the row rather
|
|
135
|
+
* than swallowed: a button that does nothing and says nothing is how
|
|
136
|
+
* "send to review does not work" became a support conversation.
|
|
137
|
+
*/ if (r.success === false) {
|
|
138
|
+
setStartNote({
|
|
139
|
+
id: item.instance_id,
|
|
140
|
+
text: r.message || say.startReviewFailed
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
setStartNote({
|
|
145
|
+
id: item.instance_id,
|
|
146
|
+
text: r.message || say.reviewStartedNote
|
|
147
|
+
});
|
|
148
|
+
loadStatuses(activeTab === 'all' ? undefined : activeTab, currentPage);
|
|
149
|
+
},
|
|
150
|
+
onErrorHandle: (err)=>{
|
|
151
|
+
setStartingId(null);
|
|
152
|
+
const e = err;
|
|
153
|
+
setStartNote({
|
|
154
|
+
id: item.instance_id,
|
|
155
|
+
text: e?.message || say.startReviewFailed
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
});
|
|
116
160
|
const loadStatuses = useEffectEvent((status, page)=>{
|
|
117
161
|
entityStatusesAction.start({
|
|
118
162
|
payload: {
|
|
@@ -332,6 +376,25 @@ export function VerificationEntityList({ entityName, entityStatusesAction, theme
|
|
|
332
376
|
className: `${t.statusBadge} ${getStatusBadgeClass(item.status)}`,
|
|
333
377
|
children: statusLabel(say, item.status)
|
|
334
378
|
}),
|
|
379
|
+
startForEntityAction && item.status !== 'active' ? /*#__PURE__*/ _jsxs("div", {
|
|
380
|
+
className: "shrink-0 flex flex-col items-end gap-1",
|
|
381
|
+
children: [
|
|
382
|
+
/*#__PURE__*/ _jsx("button", {
|
|
383
|
+
type: "button",
|
|
384
|
+
disabled: startingId === item.instance_id,
|
|
385
|
+
onClick: (e)=>{
|
|
386
|
+
e.stopPropagation();
|
|
387
|
+
startAgain(item);
|
|
388
|
+
},
|
|
389
|
+
className: themeMode === 'light' ? 'rounded-lg border border-gray-200 bg-white px-2.5 py-1 text-[11px] font-medium text-gray-600 hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed' : 'rounded-lg border border-white/[0.08] bg-white/[0.04] px-2.5 py-1 text-[11px] font-medium text-white/60 hover:bg-white/[0.1] disabled:opacity-40 disabled:cursor-not-allowed',
|
|
390
|
+
children: startingId === item.instance_id ? say.startingReview : say.startNewReview
|
|
391
|
+
}),
|
|
392
|
+
startNote?.id === item.instance_id ? /*#__PURE__*/ _jsx("p", {
|
|
393
|
+
className: themeMode === 'light' ? 'max-w-[18rem] text-right text-[10px] leading-relaxed text-gray-500' : 'max-w-[18rem] text-right text-[10px] leading-relaxed text-white/45',
|
|
394
|
+
children: startNote.text
|
|
395
|
+
}) : null
|
|
396
|
+
]
|
|
397
|
+
}) : null,
|
|
335
398
|
cancelAction && item.status === 'active' ? cancellingId === item.instance_id ? // No handlers on this wrapper: the row above is a button
|
|
336
399
|
// when `onEntityClick` is set, so each INTERACTIVE child
|
|
337
400
|
// stops the bubble itself rather than a bare div doing it
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '@xyflow/react/dist/style.css';
|
|
2
2
|
import type { ReactElement } from 'react';
|
|
3
3
|
import type { VerificationFlowPageProps } from '../types';
|
|
4
|
-
export declare function VerificationFlowPage({ entityName, title, subtitle, flowListAction, flowGetAction, flowSaveAction, flowPublishAction, flowUnpublishAction, flowDeleteAction, pendingAction, decideAction, uploadSignatureAction, listUsersAction, listRolesAction, entityStatusesAction, onFlowSelected, onDecisionMade, onEntityClick, onBack, showPending, showEntityStatuses, className, themeMode, labels, describeEntity, entityHref, availableChannels, initialTab, cancelAction, authoringModel, flowFeasibilityAction, manageRolesHref, }: VerificationFlowPageProps): ReactElement;
|
|
4
|
+
export declare function VerificationFlowPage({ entityName, title, subtitle, flowListAction, flowGetAction, flowSaveAction, flowPublishAction, flowUnpublishAction, flowDeleteAction, pendingAction, decideAction, uploadSignatureAction, listUsersAction, listRolesAction, entityStatusesAction, onFlowSelected, onDecisionMade, onEntityClick, onBack, showPending, showEntityStatuses, className, themeMode, labels, describeEntity, entityHref, availableChannels, initialTab, cancelAction, startForEntityAction, authoringModel, flowFeasibilityAction, manageRolesHref, }: VerificationFlowPageProps): ReactElement;
|
|
@@ -284,7 +284,7 @@ function buildSavePayload(flowId, entityName, flowName, flowDescription, trigger
|
|
|
284
284
|
};
|
|
285
285
|
}
|
|
286
286
|
// ─── Main Component ───────────────────────────────────────────────
|
|
287
|
-
export function VerificationFlowPage({ entityName, title, subtitle, flowListAction, flowGetAction, flowSaveAction, flowPublishAction, flowUnpublishAction, flowDeleteAction, pendingAction, decideAction, uploadSignatureAction, listUsersAction, listRolesAction, entityStatusesAction, onFlowSelected, onDecisionMade, onEntityClick, onBack, showPending = true, showEntityStatuses = false, className, themeMode = 'dark', labels, describeEntity, entityHref, availableChannels, initialTab, cancelAction, authoringModel = 1, flowFeasibilityAction, manageRolesHref }) {
|
|
287
|
+
export function VerificationFlowPage({ entityName, title, subtitle, flowListAction, flowGetAction, flowSaveAction, flowPublishAction, flowUnpublishAction, flowDeleteAction, pendingAction, decideAction, uploadSignatureAction, listUsersAction, listRolesAction, entityStatusesAction, onFlowSelected, onDecisionMade, onEntityClick, onBack, showPending = true, showEntityStatuses = false, className, themeMode = 'dark', labels, describeEntity, entityHref, availableChannels, initialTab, cancelAction, startForEntityAction, authoringModel = 1, flowFeasibilityAction, manageRolesHref }) {
|
|
288
288
|
const theme = getVerificationFlowTheme(themeMode);
|
|
289
289
|
setActiveTheme(theme);
|
|
290
290
|
const say = {
|
|
@@ -1551,7 +1551,14 @@ export function VerificationFlowPage({ entityName, title, subtitle, flowListActi
|
|
|
1551
1551
|
onEntityClick: onEntityClick,
|
|
1552
1552
|
themeMode: themeMode,
|
|
1553
1553
|
labels: say,
|
|
1554
|
-
cancelAction: cancelAction
|
|
1554
|
+
cancelAction: cancelAction,
|
|
1555
|
+
/*
|
|
1556
|
+
* Declared on these props, passed in by the panel, and destructured
|
|
1557
|
+
* NOWHERE until now — so on a flow with `trigger_on: 'manual'` the
|
|
1558
|
+
* product had no way to put a record into review at all. The list
|
|
1559
|
+
* knows which chains have finished, so a corrected record gets its
|
|
1560
|
+
* next review from the row it is already on.
|
|
1561
|
+
*/ startForEntityAction: startForEntityAction
|
|
1555
1562
|
})
|
|
1556
1563
|
})
|
|
1557
1564
|
]
|
|
@@ -409,6 +409,15 @@ export type VerificationFlowLabels = {
|
|
|
409
409
|
/** In the diagram's text alternative: the chain finishing approved / rejected. */
|
|
410
410
|
diagramFinishesApproved: string;
|
|
411
411
|
diagramFinishesRejected: string;
|
|
412
|
+
startNewReview: string;
|
|
413
|
+
startingReview: string;
|
|
414
|
+
startReviewFailed: string;
|
|
415
|
+
reviewStartedNote: string;
|
|
416
|
+
/** On the reviewer's card: which round, and what Reject will do. */
|
|
417
|
+
pendingRound: (pass: number, max: number) => string;
|
|
418
|
+
pendingRejectSendsBack: (stepLabel: string) => string;
|
|
419
|
+
pendingRejectEndsReview: string;
|
|
420
|
+
pendingLastRoundWarning: string;
|
|
412
421
|
locale: string;
|
|
413
422
|
};
|
|
414
423
|
export declare const DEFAULT_VERIFICATION_FLOW_LABELS: VerificationFlowLabels;
|
|
@@ -307,6 +307,14 @@
|
|
|
307
307
|
diagramSendsBackTo: (stepLabel)=>`if rejected, goes back to ${stepLabel}`,
|
|
308
308
|
diagramFinishesApproved: 'then the record is approved',
|
|
309
309
|
diagramFinishesRejected: 'if rejected, the record is rejected and the review ends',
|
|
310
|
+
startNewReview: 'Review again',
|
|
311
|
+
startingReview: 'Starting…',
|
|
312
|
+
startReviewFailed: 'The review could not be started.',
|
|
313
|
+
reviewStartedNote: 'Sent for review.',
|
|
314
|
+
pendingRound: (pass, max)=>`Round ${pass} of ${max}`,
|
|
315
|
+
pendingRejectSendsBack: (stepLabel)=>`Rejecting sends this back to ${stepLabel}.`,
|
|
316
|
+
pendingRejectEndsReview: 'Rejecting ends this review.',
|
|
317
|
+
pendingLastRoundWarning: 'This is the last round this flow allows, so rejecting now ends the review for good — the record will not go back to its author again.',
|
|
310
318
|
locale: 'en-US'
|
|
311
319
|
};
|
|
312
320
|
// ─── Enum → label maps ────────────────────────────────────────────
|
|
@@ -165,6 +165,17 @@ export type VerificationFlowPageTheme = {
|
|
|
165
165
|
recordLabel: string;
|
|
166
166
|
recordValue: string;
|
|
167
167
|
recordLink: string;
|
|
168
|
+
/**
|
|
169
|
+
* The round and what Reject will do, on the card, before the press.
|
|
170
|
+
* Set as a plain fact beside the buttons.
|
|
171
|
+
*/
|
|
172
|
+
decisionMeta: string;
|
|
173
|
+
/**
|
|
174
|
+
* The last allowed round. Louder than `decisionMeta`, because pressing
|
|
175
|
+
* Reject here ends a regulated review for good rather than sending the
|
|
176
|
+
* record back to be corrected.
|
|
177
|
+
*/
|
|
178
|
+
lastRoundWarning: string;
|
|
168
179
|
};
|
|
169
180
|
input: string;
|
|
170
181
|
approveButton: string;
|
|
@@ -160,7 +160,9 @@ export const verificationFlowPageTheme = {
|
|
|
160
160
|
recordRow: 'mt-3 flex flex-wrap items-baseline gap-x-2 gap-y-1',
|
|
161
161
|
recordLabel: 'text-[10px] uppercase tracking-wide text-white/30',
|
|
162
162
|
recordValue: 'text-xs text-white/70',
|
|
163
|
-
recordLink: 'text-xs font-medium text-blue-400 underline underline-offset-2'
|
|
163
|
+
recordLink: 'text-xs font-medium text-blue-400 underline underline-offset-2',
|
|
164
|
+
decisionMeta: 'text-[11px] text-white/45 leading-relaxed',
|
|
165
|
+
lastRoundWarning: 'text-[11px] leading-relaxed text-amber-300/90 rounded-lg border border-amber-500/25 bg-amber-500/[0.07] px-2.5 py-1.5'
|
|
164
166
|
},
|
|
165
167
|
input: 'rounded-lg border border-white/[0.08] bg-white/[0.04] px-3 py-1.5 text-[11px] text-white/80 w-40 outline-none focus:border-white/20',
|
|
166
168
|
approveButton: 'rounded-lg bg-emerald-500/20 border border-emerald-500/30 px-3 py-1.5 text-[11px] font-medium text-emerald-400 hover:bg-emerald-500/30 transition-all',
|
|
@@ -379,7 +381,9 @@ export const verificationFlowPageLightTheme = {
|
|
|
379
381
|
recordRow: 'mt-3 flex flex-wrap items-baseline gap-x-2 gap-y-1',
|
|
380
382
|
recordLabel: 'text-[10px] uppercase tracking-wide text-gray-400',
|
|
381
383
|
recordValue: 'text-xs text-gray-700',
|
|
382
|
-
recordLink: 'text-xs font-medium text-blue-600 underline underline-offset-2'
|
|
384
|
+
recordLink: 'text-xs font-medium text-blue-600 underline underline-offset-2',
|
|
385
|
+
decisionMeta: 'text-[11px] text-gray-500 leading-relaxed',
|
|
386
|
+
lastRoundWarning: 'text-[11px] leading-relaxed text-amber-800 rounded-lg border border-amber-300 bg-amber-50 px-2.5 py-1.5'
|
|
383
387
|
},
|
|
384
388
|
input: 'rounded-lg border border-gray-200 bg-gray-50 px-3 py-1.5 text-[11px] text-gray-800 w-40 outline-none focus:border-gray-400',
|
|
385
389
|
approveButton: 'rounded-lg bg-emerald-50 border border-emerald-200 px-3 py-1.5 text-[11px] font-medium text-emerald-700 hover:bg-emerald-100 transition-all',
|
|
@@ -208,6 +208,21 @@ export type PendingItem = {
|
|
|
208
208
|
step_name?: string;
|
|
209
209
|
require_signature: boolean;
|
|
210
210
|
created_at: string;
|
|
211
|
+
/**
|
|
212
|
+
* The round, and what a rejection would DO — so the card can say it beside
|
|
213
|
+
* the button instead of in the answer that comes back after it is pressed.
|
|
214
|
+
*
|
|
215
|
+
* Optional because a host on an older backend sends neither, and a card that
|
|
216
|
+
* crashes on a missing field is worse than one that says nothing about
|
|
217
|
+
* rounds. Absent reads as "one round", which is what model 1 is.
|
|
218
|
+
*/
|
|
219
|
+
pass_no?: number;
|
|
220
|
+
max_passes?: number;
|
|
221
|
+
is_last_pass?: boolean;
|
|
222
|
+
rejection_sends_back_to?: {
|
|
223
|
+
step_order: number;
|
|
224
|
+
step_name?: string;
|
|
225
|
+
};
|
|
211
226
|
};
|
|
212
227
|
export type VerificationFlowPageThemeOverrides = {
|
|
213
228
|
layout?: Record<string, string>;
|