nucleus-core-ts 0.10.136 → 0.10.137
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 +7 -0
- package/dist/fe/components/VerificationFlowPage/components/VerificationFlowPage.js +25 -6
- package/dist/fe/components/VerificationFlowPage/labels.d.ts +2 -0
- package/dist/fe/components/VerificationFlowPage/labels.js +8 -2
- package/dist/fe/components/VerificationFlowPage/model2/StepCard.js +3 -1
- package/dist/fe/components/VerificationFlowPage/model2/editorGraph.js +15 -5
- package/dist/index.js +1 -1
- package/dist/server.js +1 -1
- package/dist/src/Services/Verification/model2Validate.d.ts +1 -1
- package/package.json +1 -1
package/dist/.build-ok
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.10.
|
|
1
|
+
0.10.137
|
|
@@ -474,6 +474,13 @@ export function PendingTab({ pendingAction, decideAction, uploadSignatureAction,
|
|
|
474
474
|
className: theme.pending.card.subtitle,
|
|
475
475
|
children: item.step_name
|
|
476
476
|
}) : null,
|
|
477
|
+
item.sent_back?.reason ? /*#__PURE__*/ _jsxs("p", {
|
|
478
|
+
className: theme.pending.card.decisionMeta,
|
|
479
|
+
children: [
|
|
480
|
+
typeof item.pass_no === 'number' && typeof item.max_passes === 'number' ? `${say.pendingRound(item.pass_no, item.max_passes)} · ` : null,
|
|
481
|
+
say.previousRoundReason(item.sent_back.reason)
|
|
482
|
+
]
|
|
483
|
+
}) : null,
|
|
477
484
|
renderRecord(item)
|
|
478
485
|
]
|
|
479
486
|
}),
|
|
@@ -316,6 +316,7 @@ export function VerificationFlowPage({ entityName, title, subtitle, flowListActi
|
|
|
316
316
|
* a ref here, because the render needs it too — to tell this editor's save
|
|
317
317
|
* from one left behind — and a ref restarted at 0 on each mount.
|
|
318
318
|
*/ /** The latest readiness question; any older answer is about another graph. */ const feasibilityTicketRef = useRef(0);
|
|
319
|
+
/** The pending automatic re-check after an edit; see `scheduleFeasibility`. */ const feasibilityTimerRef = useRef(null);
|
|
319
320
|
/*
|
|
320
321
|
* The id a NEW flow is saved under, minted at its first save and reused
|
|
321
322
|
* until one succeeds. It is not written to `selectedFlowId` before then:
|
|
@@ -756,22 +757,40 @@ export function VerificationFlowPage({ entityName, title, subtitle, flowListActi
|
|
|
756
757
|
}
|
|
757
758
|
});
|
|
758
759
|
});
|
|
760
|
+
/*
|
|
761
|
+
* Re-ask once the author PAUSES, with the graph they paused on.
|
|
762
|
+
*
|
|
763
|
+
* The answer was dropped on every edit and came back only on "Şimdi kontrol
|
|
764
|
+
* et" or a save, so adding a third step left the card blank ("henüz
|
|
765
|
+
* karşılaştırılmadı") exactly when it should have turned red (found by the
|
|
766
|
+
* re-check). A request per keystroke is not the fix either; one request
|
|
767
|
+
* 700ms after the last edit is. The ticket still discards an answer that
|
|
768
|
+
* lands after a newer edit.
|
|
769
|
+
*/ const scheduleFeasibility = useEffectEvent(()=>{
|
|
770
|
+
if (feasibilityTimerRef.current) clearTimeout(feasibilityTimerRef.current);
|
|
771
|
+
feasibilityTimerRef.current = setTimeout(()=>{
|
|
772
|
+
feasibilityTimerRef.current = null;
|
|
773
|
+
checkFeasibility();
|
|
774
|
+
}, 700);
|
|
775
|
+
});
|
|
776
|
+
useEffect(()=>()=>{
|
|
777
|
+
if (feasibilityTimerRef.current) clearTimeout(feasibilityTimerRef.current);
|
|
778
|
+
}, []);
|
|
759
779
|
const handleModel2Change = useEffectEvent((next, notes)=>{
|
|
760
780
|
store.setModel2Graph(next);
|
|
761
781
|
if (notes.length > 0) store.setModel2Notes(notes);
|
|
762
782
|
store.markEdited();
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
* with the button, and a save always re-asks on the server anyway.
|
|
768
|
-
*/ dropFeasibility();
|
|
783
|
+
// The old answer is about a graph that no longer exists: drop it now,
|
|
784
|
+
// re-ask when the author pauses.
|
|
785
|
+
dropFeasibility();
|
|
786
|
+
scheduleFeasibility();
|
|
769
787
|
});
|
|
770
788
|
const handleMaxPassesChange = useEffectEvent((value)=>{
|
|
771
789
|
store.setMaxPasses(value);
|
|
772
790
|
store.markEdited();
|
|
773
791
|
// The round limit is part of the question the card answered.
|
|
774
792
|
dropFeasibility();
|
|
793
|
+
scheduleFeasibility();
|
|
775
794
|
});
|
|
776
795
|
// ─── Flow details ─────────────────────────────────────────────
|
|
777
796
|
//
|
|
@@ -443,6 +443,8 @@ export type VerificationFlowLabels = {
|
|
|
443
443
|
reviewStartedNote: string;
|
|
444
444
|
/** On the reviewer's card: which round, and what Reject will do. */
|
|
445
445
|
pendingRound: (pass: number, max: number) => string;
|
|
446
|
+
/** On a reviewer's card in a later round: why the previous round was rejected. */
|
|
447
|
+
previousRoundReason: (reason: string) => string;
|
|
446
448
|
pendingRejectSendsBack: (stepLabel: string) => string;
|
|
447
449
|
pendingRejectEndsReview: string;
|
|
448
450
|
pendingLastRoundWarning: string;
|
|
@@ -235,7 +235,7 @@
|
|
|
235
235
|
approvalModeAll: 'Everyone listed',
|
|
236
236
|
approvalModeAllHint: 'Every person above must decide before the record moves on.',
|
|
237
237
|
approvalModeAny: 'Any one of them',
|
|
238
|
-
approvalModeAnyHint: 'The first
|
|
238
|
+
approvalModeAnyHint: 'The first person listed to finish closes the step, and the others are no longer asked. A role set to "every member" finishes only when all its members have signed.',
|
|
239
239
|
outcomes: 'Where each answer sends it',
|
|
240
240
|
onApproved: 'If approved',
|
|
241
241
|
onApprovedNext: 'Go to the next step',
|
|
@@ -320,6 +320,7 @@
|
|
|
320
320
|
startReviewFailed: 'The review could not be started.',
|
|
321
321
|
reviewStartedNote: 'Sent for review.',
|
|
322
322
|
pendingRound: (pass, max)=>`Round ${pass} (at most ${max})`,
|
|
323
|
+
previousRoundReason: (reason)=>`Rejected last round because: ${reason}`,
|
|
323
324
|
pendingRejectSendsBack: (stepLabel)=>`Rejecting sends this back to ${stepLabel}.`,
|
|
324
325
|
pendingRejectEndsReview: 'Rejecting ends this review.',
|
|
325
326
|
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.',
|
|
@@ -431,7 +432,12 @@ export function recipientTypeLabels(say) {
|
|
|
431
432
|
// one, the engine's sentence when it does not, and a generic line only when
|
|
432
433
|
// the engine sent nothing at all.
|
|
433
434
|
export function refusalSentence(say, code, detail, fallback, generic) {
|
|
434
|
-
|
|
435
|
+
/*
|
|
436
|
+
* Publish refuses with the READINESS codes too (a chain needing more people
|
|
437
|
+
* than the install has). A host that worded those only for the readiness
|
|
438
|
+
* card got the English sentence in the publish banner — measured by the
|
|
439
|
+
* re-check on the Turkish panel.
|
|
440
|
+
*/ const own = code ? say.flowRefusalByCode[code] ?? say.feasibilityByCode[code] : undefined;
|
|
435
441
|
if (own) return own(detail ?? {});
|
|
436
442
|
const decision = code ? say.decisionRefusalByCode[code] : undefined;
|
|
437
443
|
if (decision) return decision;
|
|
@@ -251,7 +251,9 @@ export function StepCard({ step, graph, isFirst, isLast, roles, users, triggerLa
|
|
|
251
251
|
step_node_id: step.node_id
|
|
252
252
|
},
|
|
253
253
|
actions: stepActions,
|
|
254
|
-
|
|
254
|
+
// "The author sent it back" can only happen on the author's own
|
|
255
|
+
// correction step; offered elsewhere it saved and never fired.
|
|
256
|
+
triggers: (step.kind ?? 'approval') === 'revision' ? STEP_TRIGGERS : STEP_TRIGGERS.filter((t)=>t !== 'on_resubmitted'),
|
|
255
257
|
triggerLabels: triggerLabels,
|
|
256
258
|
recipientTypeLabels: recipientTypeLabels,
|
|
257
259
|
channelLabels: channelLabels,
|
|
@@ -412,7 +412,15 @@ export function updateActionAt(graph, index, patch) {
|
|
|
412
412
|
/** The steps an approval on `nodeId` may skip to: strictly later ones. */ export function approveTargets(graph, nodeId) {
|
|
413
413
|
const step = (graph.steps ?? []).find((s)=>s.node_id === nodeId);
|
|
414
414
|
if (!step) return [];
|
|
415
|
-
|
|
415
|
+
const later = (graph.steps ?? []).filter((s)=>s.step_order > step.step_order).sort(byOrder);
|
|
416
|
+
if ((step.kind ?? 'approval') !== 'revision') return later;
|
|
417
|
+
/*
|
|
418
|
+
* A correction step may not jump OVER a reviewer. Two correction steps at
|
|
419
|
+
* the front with different jumps gave each round a different entry, and a
|
|
420
|
+
* reviewer walked in round 1 but jumped over in round 2 kept a signature on
|
|
421
|
+
* the old text (found by the re-check). Mirrors `revision_skips_reviewers`.
|
|
422
|
+
*/ const firstReviewer = later.find((s)=>(s.kind ?? 'approval') !== 'revision');
|
|
423
|
+
return firstReviewer ? later.filter((s)=>s.step_order <= firstReviewer.step_order) : later;
|
|
416
424
|
}
|
|
417
425
|
/**
|
|
418
426
|
* The approval outcomes the step card may OFFER for `nodeId`.
|
|
@@ -547,10 +555,12 @@ export const MAX_PASSES_MAX = 20;
|
|
|
547
555
|
* first (found in the audit). Telling the author the two buttons do the same
|
|
548
556
|
* thing there is telling them a choice that matters does not.
|
|
549
557
|
*/ export function approvalModeHasNoEffect(step) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
558
|
+
/*
|
|
559
|
+
* The engine reads "any one of them" as any one SLOT, and a slot of "every
|
|
560
|
+
* member" is finished only when every member has signed (0.10.135). So with
|
|
561
|
+
* ONE slot the two modes are the same rule whatever its quorum — the
|
|
562
|
+
* exception this carried described the engine before that fix.
|
|
563
|
+
*/ return (step.assignees ?? []).length === 1;
|
|
554
564
|
}
|
|
555
565
|
/**
|
|
556
566
|
* The part of a step patch a live flow still accepts: its wording.
|