@lax-wp/editor 0.4.13 → 0.4.15-beta.0
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/README.md +25 -0
- package/dist/api/audit.d.ts +79 -0
- package/dist/api/derivedRulebook.d.ts +470 -0
- package/dist/api/documentVersions.d.ts +519 -0
- package/dist/api/effectiveRules.d.ts +372 -0
- package/dist/api/methodology.d.ts +62 -0
- package/dist/api/playbook.d.ts +604 -0
- package/dist/api/promotions.d.ts +1432 -0
- package/dist/api/r1.d.ts +1097 -0
- package/dist/api/r1.fixtures.d.ts +111 -0
- package/dist/api/redlineJobs.d.ts +377 -0
- package/dist/api/redlineStream.d.ts +2979 -0
- package/dist/api/redlines.d.ts +504 -0
- package/dist/api/regsync.d.ts +2355 -0
- package/dist/api/ruleAuthoring.d.ts +305 -0
- package/dist/api/ruleBuilder.d.ts +1009 -0
- package/dist/api/ruleOverrides.d.ts +31 -0
- package/dist/api/ruleStats.d.ts +84 -0
- package/dist/api/rulesCatalog.d.ts +234 -0
- package/dist/api/versions.d.ts +76 -0
- package/dist/api/workspace.d.ts +41 -0
- package/dist/components/EditorSidebar.d.ts +4 -1
- package/dist/components/audit/AuditView.d.ts +8 -0
- package/dist/components/capturededits/AddAsRuleModal.d.ts +8 -0
- package/dist/components/capturededits/CapturedEditCard.d.ts +15 -0
- package/dist/components/capturededits/CapturedEditsTray.d.ts +4 -0
- package/dist/components/capturededits/capturedEditIntent.d.ts +23 -0
- package/dist/components/common/EscDropdown.d.ts +2 -0
- package/dist/components/compliance/MethodologyPanel.d.ts +14 -0
- package/dist/components/compliance/RegSyncPanel.d.ts +18 -0
- package/dist/components/compliance/index.d.ts +8 -0
- package/dist/components/compliance/primitives.d.ts +41 -0
- package/dist/components/documents/DocumentVersionHistory.d.ts +12 -0
- package/dist/components/documents/documentDiff.d.ts +68 -0
- package/dist/components/documents/index.d.ts +4 -0
- package/dist/components/flowdown/FlowdownPanel.d.ts +28 -0
- package/dist/components/flowdown/FlowdownRowCard.d.ts +27 -0
- package/dist/components/flowdown/flowdownModel.d.ts +150 -0
- package/dist/components/history/PlaybookVersionHistory.d.ts +10 -0
- package/dist/components/history/versionDiff.d.ts +14 -0
- package/dist/components/playbook/AllPlaybooksView.d.ts +41 -0
- package/dist/components/playbook/DerivedRulebookView.d.ts +9 -0
- package/dist/components/playbook/DraftedRulePreview.d.ts +17 -0
- package/dist/components/playbook/EffectiveRulesView.d.ts +11 -0
- package/dist/components/playbook/NewRuleDrawer.d.ts +11 -0
- package/dist/components/playbook/PlaybookCard.d.ts +13 -0
- package/dist/components/playbook/PlaybookPage.d.ts +29 -0
- package/dist/components/playbook/PlaybookPanel.d.ts +73 -0
- package/dist/components/playbook/PromotionSuggestions.d.ts +1 -0
- package/dist/components/playbook/ReprioritizeDialog.d.ts +16 -0
- package/dist/components/playbook/RuleDetail.d.ts +27 -0
- package/dist/components/playbook/RuleEditorFields.d.ts +42 -0
- package/dist/components/playbook/RuleEditorModal.d.ts +27 -0
- package/dist/components/playbook/RulePerformancePanel.d.ts +4 -0
- package/dist/components/playbook/RuleRow.d.ts +26 -0
- package/dist/components/playbook/ThisDocumentView.d.ts +45 -0
- package/dist/components/playbook/ViewTabs.d.ts +8 -0
- package/dist/components/playbook/index.d.ts +14 -0
- package/dist/components/playbook/predicateSummary.d.ts +10 -0
- package/dist/components/playbook/primitives.d.ts +82 -0
- package/dist/components/playbook/useFocusTrap.d.ts +6 -0
- package/dist/components/playbook/usePlaybookData.d.ts +161 -0
- package/dist/components/playbook/usePlaybookLabel.d.ts +18 -0
- package/dist/components/r1/ApprovalPanel.d.ts +10 -0
- package/dist/components/r1/CandidateRuleCard.d.ts +8 -0
- package/dist/components/r1/ExecSummaryPanel.d.ts +23 -0
- package/dist/components/r1/PrimeUploadPanel.d.ts +8 -0
- package/dist/components/r1/ReviewStartControls.d.ts +24 -0
- package/dist/components/r1/ReviewSummaryTab.d.ts +38 -0
- package/dist/components/r1/index.d.ts +13 -0
- package/dist/components/r1/primitives.d.ts +59 -0
- package/dist/components/redline/AiReviewPanel.d.ts +194 -0
- package/dist/components/redline/RedlineHoverCard.d.ts +13 -0
- package/dist/components/redline/RedlineItem.d.ts +12 -0
- package/dist/components/redline/ReviewCard.d.ts +49 -0
- package/dist/components/redline/index.d.ts +6 -0
- package/dist/components/redline/reviewItems.d.ts +49 -0
- package/dist/components/redline/reviewPrefs.d.ts +18 -0
- package/dist/components/redline/useRunScopedCards.d.ts +16 -0
- package/dist/components/rulebuilder/AuthorForms.d.ts +28 -0
- package/dist/components/rulebuilder/CandidateQueue.d.ts +21 -0
- package/dist/components/rulebuilder/DraftPane.d.ts +12 -0
- package/dist/components/rulebuilder/RuleBuilderPanel.d.ts +6 -0
- package/dist/components/rulebuilder/RuleCard.d.ts +16 -0
- package/dist/components/rulebuilder/TestBench.d.ts +10 -0
- package/dist/components/rulebuilder/VocabularyPanel.d.ts +26 -0
- package/dist/components/rulebuilder/index.d.ts +13 -0
- package/dist/components/rulebuilder/primitives.d.ts +54 -0
- package/dist/components/rulebuilder/useRuleBuilder.d.ts +291 -0
- package/dist/components/sidebar/ExpandableSidebar.d.ts +2 -0
- package/dist/components/sidebar/WorkspaceRetentionPanel.d.ts +18 -0
- package/dist/components/sidebar/content/TrackChangesContent.d.ts +8 -0
- package/dist/components/sidebar/content/anonymization-page/PIIAnonymization.d.ts +1 -1
- package/dist/components/sidebar/content/anonymization-page/PiiIdleView.d.ts +12 -0
- package/dist/components/sidebar/content/anonymization-page/PiiRecoveryView.d.ts +16 -0
- package/dist/components/sidebar/content/anonymization-page/PiiSummaryView.d.ts +34 -0
- package/dist/components/sidebar/content/anonymization-page/PiiUnavailableView.d.ts +1 -0
- package/dist/components/sidebar/content/anonymization-page/RestoreConfirmDialog.d.ts +9 -0
- package/dist/components/sidebar/content/anonymization-page/anonymizationUtils.d.ts +38 -17
- package/dist/components/sidebar/content/anonymization-page/piiVault.d.ts +18 -0
- package/dist/components/sidebar/content/index.d.ts +0 -1
- package/dist/components/toolbar/AutocompletionToggle.d.ts +1 -0
- package/dist/components/trackChanges/TrackChangesCards.d.ts +1 -0
- package/dist/components/trackChanges/index.d.ts +2 -0
- package/dist/components/trackChanges/utils.d.ts +5 -0
- package/dist/config/EditorConfig.d.ts +197 -73
- package/dist/constants/Extensions.d.ts +12 -0
- package/dist/constants/playbook.d.ts +108 -0
- package/dist/contexts/CapturedEditsContext.d.ts +56 -0
- package/dist/contexts/EditorShellContext.d.ts +4 -1
- package/dist/editor.css +1 -1
- package/dist/extensions/AnonymizedText.d.ts +31 -2
- package/dist/extensions/VariableText.d.ts +20 -0
- package/dist/extensions/index.d.ts +1 -1
- package/dist/extensions/plugins/CapturedEditsPlugin.d.ts +90 -0
- package/dist/extensions/plugins/MarkHighlightPlugin.d.ts +0 -1
- package/dist/extensions/plugins/RedlinePlugin.d.ts +9 -0
- package/dist/extensions/redline/changeTypes.d.ts +70 -0
- package/dist/extensions/redline/constants.d.ts +25 -0
- package/dist/extensions/redline/engine/blockNodes.d.ts +31 -0
- package/dist/extensions/redline/engine/clipboard.d.ts +16 -0
- package/dist/extensions/redline/engine/deletion.d.ts +34 -0
- package/dist/extensions/redline/engine/formatSplit.d.ts +16 -0
- package/dist/extensions/redline/engine/insertion.d.ts +26 -0
- package/dist/extensions/redline/engine/predicates.d.ts +73 -0
- package/dist/extensions/redline/engine/textReplace.d.ts +19 -0
- package/dist/extensions/redline/id.d.ts +7 -0
- package/dist/extensions/redline/index.d.ts +36 -0
- package/dist/extensions/redline/plugin.d.ts +34 -0
- package/dist/extensions/redline/query/scan.d.ts +52 -0
- package/dist/extensions/redline/review/applyChange.d.ts +25 -0
- package/dist/extensions/redline/review/index.d.ts +1 -0
- package/dist/extensions/redline/review/nodeResolvers.d.ts +29 -0
- package/dist/extensions/redline/review/pairedNodes.d.ts +38 -0
- package/dist/extensions/redline/review/structuralRevert.d.ts +20 -0
- package/dist/extensions/redline/review/textResolver.d.ts +9 -0
- package/dist/extensions/redline/schema/marks.d.ts +65 -0
- package/dist/extensions/redline/schema/shared.d.ts +34 -0
- package/dist/extensions/redline/session.d.ts +71 -0
- package/dist/extensions/redline/types.d.ts +24 -0
- package/dist/extensions/trackedChanges/TrackedChanges.d.ts +64 -0
- package/dist/extensions/trackedChanges/constants.d.ts +34 -0
- package/dist/extensions/trackedChanges/engine.d.ts +32 -0
- package/dist/extensions/trackedChanges/index.d.ts +13 -0
- package/dist/extensions/trackedChanges/marks.d.ts +20 -0
- package/dist/extensions/trackedChanges/normalize.d.ts +2 -0
- package/dist/extensions/trackedChanges/plugin.d.ts +32 -0
- package/dist/extensions/trackedChanges/query.d.ts +3 -0
- package/dist/extensions/trackedChanges/review.d.ts +34 -0
- package/dist/extensions/trackedChanges/types.d.ts +72 -0
- package/dist/extensions/trackedChanges/utils.d.ts +20 -0
- package/dist/hooks/useMediaQuery.d.ts +2 -0
- package/dist/hooks/useRedlineHover.d.ts +17 -0
- package/dist/hooks/useRedlineReview.d.ts +83 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.es.js +38491 -22189
- package/dist/index.umd.js +224 -125
- package/dist/utils/cdts.d.ts +37 -0
- package/dist/utils/groundingAdapter.d.ts +36 -0
- package/package.json +39 -33
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aligns git-store diff hunks against the two versions' documents.
|
|
3
|
+
*
|
|
4
|
+
* GET /v1/documents/{docId}/diff/{from}/{to} returns structural hunks only —
|
|
5
|
+
* `{op, lineNo, oldId?, newId?}` where the ids are line-node SHA256s. The
|
|
6
|
+
* server never sends text, and the FE has no way to resolve a line-node hash,
|
|
7
|
+
* so rendering a diff means fetching BOTH versions (GET .../versions/{id}) and
|
|
8
|
+
* aligning the hunks against their `doc.content` arrays.
|
|
9
|
+
*
|
|
10
|
+
* The lineNo is NOT on a single side of the diff (internal/git-store/lib/diff
|
|
11
|
+
* diff.go `Refine`):
|
|
12
|
+
*
|
|
13
|
+
* INSERT → lineNo indexes the NEW document (newNode.LineNo)
|
|
14
|
+
* DELETE → lineNo indexes the OLD document (oldNode.LineNo)
|
|
15
|
+
* REPLACE → lineNo indexes the OLD document (oldNode.LineNo); the matching
|
|
16
|
+
* new line is NOT addressed at all, which is why a two-pointer
|
|
17
|
+
* walk is needed rather than a lookup.
|
|
18
|
+
*
|
|
19
|
+
* Repeated lines make lineNo ambiguous — several hunks can report the SAME
|
|
20
|
+
* lineNo because the server addresses lines by content hash. See the surplus
|
|
21
|
+
* handling in `alignDiff`; contract boilerplate hits this routinely.
|
|
22
|
+
*
|
|
23
|
+
* Walk order is INSERT-first at each position. A Myers edit script can emit an
|
|
24
|
+
* insert BEFORE the delete that a later REPLACE was folded from; consuming the
|
|
25
|
+
* new-side insert first keeps the REPLACE paired with the correct new line.
|
|
26
|
+
* (Draining old-side first would pair a REPLACE with a line that belonged to
|
|
27
|
+
* the standalone insert, silently showing the wrong "after" text.)
|
|
28
|
+
*/
|
|
29
|
+
import type { DiffHunk, ProseMirrorDocument, ProseMirrorNode } from "@/api/documentVersions";
|
|
30
|
+
export type DiffRowKind = "equal" | "insert" | "delete" | "replace";
|
|
31
|
+
export interface DiffRow {
|
|
32
|
+
kind: DiffRowKind;
|
|
33
|
+
/** 1-based line number in the `from` version, or null for a pure insert. */
|
|
34
|
+
oldLineNo: number | null;
|
|
35
|
+
/** 1-based line number in the `to` version, or null for a pure delete. */
|
|
36
|
+
newLineNo: number | null;
|
|
37
|
+
oldText: string | null;
|
|
38
|
+
newText: string | null;
|
|
39
|
+
}
|
|
40
|
+
export interface DiffCounts {
|
|
41
|
+
inserted: number;
|
|
42
|
+
deleted: number;
|
|
43
|
+
replaced: number;
|
|
44
|
+
unchanged: number;
|
|
45
|
+
}
|
|
46
|
+
export interface AlignedDiff {
|
|
47
|
+
rows: DiffRow[];
|
|
48
|
+
counts: DiffCounts;
|
|
49
|
+
/**
|
|
50
|
+
* False when the hunks could not be reconciled with the two documents —
|
|
51
|
+
* every hunk consumed and both sides walked to the end. Callers must not
|
|
52
|
+
* present an unaligned diff as an accurate account of the change.
|
|
53
|
+
*/
|
|
54
|
+
aligned: boolean;
|
|
55
|
+
}
|
|
56
|
+
/** Flattens a top-level node to its text, the way a reviewer reads the line. */
|
|
57
|
+
export declare const nodeText: (node: ProseMirrorNode | undefined | null) => string;
|
|
58
|
+
/** A short human label for a line that carries no text (image, rule, …). */
|
|
59
|
+
export declare const lineLabel: (node: ProseMirrorNode | undefined | null) => string;
|
|
60
|
+
/**
|
|
61
|
+
* Produces renderable diff rows for `from` → `to`.
|
|
62
|
+
*
|
|
63
|
+
* `hunks` must be the server's diff for exactly that commit pair; passing a
|
|
64
|
+
* mismatched pair is what `aligned: false` is there to catch.
|
|
65
|
+
*/
|
|
66
|
+
export declare const alignDiff: (fromDoc: ProseMirrorDocument | null | undefined, toDoc: ProseMirrorDocument | null | undefined, hunks: DiffHunk[]) => AlignedDiff;
|
|
67
|
+
/** One-line summary of a change set, e.g. "1 replaced, 1 added". */
|
|
68
|
+
export declare const summarizeCounts: (counts: DiffCounts) => string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { DocumentVersionHistory } from "./DocumentVersionHistory";
|
|
2
|
+
export type { DocumentVersionHistoryProps } from "./DocumentVersionHistory";
|
|
3
|
+
export { alignDiff, summarizeCounts } from "./documentDiff";
|
|
4
|
+
export type { AlignedDiff, DiffRow, DiffRowKind, DiffCounts } from "./documentDiff";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type PlaybookApiConfig } from "@/api/playbook";
|
|
2
|
+
import { type FlowdownFlagInput, type FlowdownInsertionInput } from "./flowdownModel";
|
|
3
|
+
export interface FlowdownPanelProps {
|
|
4
|
+
/** `rulebook` flag events with baseline rule ids, from the review stream. */
|
|
5
|
+
flags: FlowdownFlagInput[];
|
|
6
|
+
/** `rulebook_insertion` events with baseline rule ids. */
|
|
7
|
+
insertions: FlowdownInsertionInput[];
|
|
8
|
+
/** Enables disposition re-hydration (GET /api/redlines?document_id=). */
|
|
9
|
+
documentId?: string;
|
|
10
|
+
/** Host user's display name → X-Actor (localStorage `lax.flowdownActor` overrides). */
|
|
11
|
+
actorName?: string;
|
|
12
|
+
/** Apply an accepted insertion's text into the editor doc (host owns the editor). */
|
|
13
|
+
onApplyInsertion?: (insertion: FlowdownInsertionInput) => void;
|
|
14
|
+
/** Strike a previously-applied insertion (deletion redline mark on its text). */
|
|
15
|
+
onStrikeInsertion?: (insertion: FlowdownInsertionInput) => void;
|
|
16
|
+
/** Latest editor doc JSON, for the matrix export body. */
|
|
17
|
+
getDoc?: () => Record<string, unknown> | null;
|
|
18
|
+
/**
|
|
19
|
+
* The completed review this panel's findings came from, off the stream's
|
|
20
|
+
* `summary` frame (`review_id`). Enables the CPSR audit-packet export, which
|
|
21
|
+
* is keyed by review — not by document. Absent ⇒ the export is offered but
|
|
22
|
+
* disabled with the reason shown, rather than 404-ing on click.
|
|
23
|
+
*/
|
|
24
|
+
reviewId?: string | null;
|
|
25
|
+
/** API endpoint config (base URL / workspace), shared with the playbook client. */
|
|
26
|
+
api?: PlaybookApiConfig;
|
|
27
|
+
}
|
|
28
|
+
export declare const FlowdownPanel: ({ flags, insertions, documentId, actorName, onApplyInsertion, onStrikeInsertion, getDoc, reviewId, api, }: FlowdownPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Rule } from "@/api/playbook";
|
|
2
|
+
import { type FlowdownRow } from "./flowdownModel";
|
|
3
|
+
export type RuleLookupState = {
|
|
4
|
+
state: "loading";
|
|
5
|
+
} | {
|
|
6
|
+
state: "error";
|
|
7
|
+
} | {
|
|
8
|
+
state: "ok";
|
|
9
|
+
rule: Rule;
|
|
10
|
+
};
|
|
11
|
+
interface FlowdownRowCardProps {
|
|
12
|
+
row: FlowdownRow;
|
|
13
|
+
/** Lazy enrichment cache entry for this row's rule id. */
|
|
14
|
+
ruleLookup?: RuleLookupState;
|
|
15
|
+
/** First expand → parent fetches GET /v1/rules/{id}. */
|
|
16
|
+
onExpand?: (ruleId: string) => void;
|
|
17
|
+
/** Accept: disposition + apply the insertion text. `teach` = scope "playbook". */
|
|
18
|
+
onAccept?: (row: FlowdownRow, teach: boolean) => void;
|
|
19
|
+
/** Not applicable: reject with the REQUIRED note. */
|
|
20
|
+
onReject?: (row: FlowdownRow, note: string) => void;
|
|
21
|
+
/** Strike a previously-applied insertion (deletion mark + reject disposition). */
|
|
22
|
+
onStrike?: (row: FlowdownRow, note: string) => void;
|
|
23
|
+
/** An action for this row is in flight. */
|
|
24
|
+
busy?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare const FlowdownRowCard: ({ row, ruleLookup, onExpand, onAccept, onReject, onStrike, busy, }: FlowdownRowCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flowdown determination model — pure logic for the Flowdown tab.
|
|
3
|
+
*
|
|
4
|
+
* The gov baseline lane emits per-clause `rulebook` flags ("Required clause
|
|
5
|
+
* FAR 52.204-21 is absent … (rule baseline:gov:cyber-safeguarding)") plus at
|
|
6
|
+
* most one `rulebook_insertion` per rule carrying ready-to-insert
|
|
7
|
+
* incorporation text. The flag's top-level `rule_id` and the insertion's
|
|
8
|
+
* `citation.rule_id` share the same `baseline:gov:<topic>` value — that id is
|
|
9
|
+
* the join key, and its third segment is the topic.
|
|
10
|
+
*
|
|
11
|
+
* One RULE is one determination unit (the insertion covers the rule's whole
|
|
12
|
+
* clause set); its clauses render as lines within the row. No React in here —
|
|
13
|
+
* everything is unit-testable with plain objects.
|
|
14
|
+
*/
|
|
15
|
+
export interface FlowdownFlagInput {
|
|
16
|
+
id: string;
|
|
17
|
+
/** `baseline:gov:<topic>` on the rulecheck lane; absent on other lanes. */
|
|
18
|
+
rule_id?: string;
|
|
19
|
+
rationale: string;
|
|
20
|
+
severity: string;
|
|
21
|
+
}
|
|
22
|
+
export interface FlowdownInsertionInput {
|
|
23
|
+
id: string;
|
|
24
|
+
rationale: string;
|
|
25
|
+
severity: string;
|
|
26
|
+
/** Ready-to-insert incorporation-by-reference text. */
|
|
27
|
+
text: string;
|
|
28
|
+
/** Anchor node, e.g. "[41]". */
|
|
29
|
+
position_path: string;
|
|
30
|
+
/** "before" | "after" | "child" relative to the anchor. */
|
|
31
|
+
placement?: string;
|
|
32
|
+
/** ProseMirror node type to insert, e.g. "paragraph". */
|
|
33
|
+
node_type?: string;
|
|
34
|
+
citation: {
|
|
35
|
+
rule_id: string;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export interface FlowdownClause {
|
|
39
|
+
flagId: string;
|
|
40
|
+
/** "FAR 52.204-21" — parsed from the flag rationale; null when unparsable. */
|
|
41
|
+
clause: string | null;
|
|
42
|
+
rationale: string;
|
|
43
|
+
}
|
|
44
|
+
export interface FlowdownDetermination {
|
|
45
|
+
status: "accepted" | "rejected";
|
|
46
|
+
note?: string;
|
|
47
|
+
scope?: string;
|
|
48
|
+
/** The persisted record the disposition landed on (insertion or flag id). */
|
|
49
|
+
recordId?: string;
|
|
50
|
+
}
|
|
51
|
+
/** One rule = one determination unit; its clauses list within the row. */
|
|
52
|
+
export interface FlowdownRow {
|
|
53
|
+
ruleId: string;
|
|
54
|
+
topic: string;
|
|
55
|
+
severity: string;
|
|
56
|
+
clauses: FlowdownClause[];
|
|
57
|
+
insertion?: FlowdownInsertionInput;
|
|
58
|
+
determination?: FlowdownDetermination;
|
|
59
|
+
/** The insertion's proposed text was applied into the editor doc. */
|
|
60
|
+
applied?: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface FlowdownGroup {
|
|
63
|
+
topic: string;
|
|
64
|
+
rows: FlowdownRow[];
|
|
65
|
+
}
|
|
66
|
+
export type FlowdownRowStatus = "missing" | "insert_proposed" | "determined";
|
|
67
|
+
export declare const isBaselineRuleId: (id: string | undefined) => id is string;
|
|
68
|
+
/** "baseline:gov:cyber-safeguarding" → "cyber-safeguarding". */
|
|
69
|
+
export declare const topicOfRuleId: (ruleId: string) => string;
|
|
70
|
+
/** "cyber-safeguarding" → "Cyber safeguarding". */
|
|
71
|
+
export declare const topicLabel: (topic: string) => string;
|
|
72
|
+
/**
|
|
73
|
+
* "Required clause FAR 52.204-21 is absent …" → "FAR 52.204-21".
|
|
74
|
+
* The rulecheck lane's canonical citation form is "PREFIX N.NNN(-N)".
|
|
75
|
+
*/
|
|
76
|
+
export declare const parseClauseRef: (rationale: string) => string | null;
|
|
77
|
+
/** "[41]" or "41,0" → [41, 0] — same encoding useRedlineReview parses. */
|
|
78
|
+
export declare const parseInsertionNodePath: (path: string) => number[];
|
|
79
|
+
/**
|
|
80
|
+
* Pair the baseline flags with their sibling insertions by shared rule id and
|
|
81
|
+
* group the rows by topic. Non-baseline events are ignored. Topic order and
|
|
82
|
+
* row order follow first appearance in the stream (document/severity order is
|
|
83
|
+
* the backend's choice; we preserve it).
|
|
84
|
+
*/
|
|
85
|
+
export declare const buildFlowdownGroups: (flags: readonly FlowdownFlagInput[], insertions: readonly FlowdownInsertionInput[]) => FlowdownGroup[];
|
|
86
|
+
/**
|
|
87
|
+
* Total determination rows buildFlowdownGroups yields for these stream
|
|
88
|
+
* inputs — one row per baseline rule, the unit the Flowdown tab renders.
|
|
89
|
+
* Used for the tab badge so it can never disagree with the tab body.
|
|
90
|
+
*/
|
|
91
|
+
export declare const flowdownRowCount: (flags: readonly FlowdownFlagInput[], insertions: readonly FlowdownInsertionInput[]) => number;
|
|
92
|
+
export declare const rowStatus: (row: FlowdownRow) => FlowdownRowStatus;
|
|
93
|
+
/** The note is REQUIRED before a not-applicable rejection can be submitted. */
|
|
94
|
+
export declare const canSubmitRejection: (note: string) => boolean;
|
|
95
|
+
/** Structural subset of api/redlines' DispositionRecord. */
|
|
96
|
+
export interface FlowdownDispositionRecord {
|
|
97
|
+
ID: string;
|
|
98
|
+
State: string;
|
|
99
|
+
RejectScope?: string;
|
|
100
|
+
RejectNote?: string;
|
|
101
|
+
Lane?: string;
|
|
102
|
+
Suggestion?: {
|
|
103
|
+
rationale?: string;
|
|
104
|
+
severity?: string;
|
|
105
|
+
text?: string;
|
|
106
|
+
position_path?: string;
|
|
107
|
+
placement?: string;
|
|
108
|
+
node_type?: string;
|
|
109
|
+
citation?: {
|
|
110
|
+
rule_id?: string;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Rebuild row inputs from persisted records so the tab is populated on a
|
|
116
|
+
* fresh page load (or after any live-stream state loss) — persistence, not
|
|
117
|
+
* the stream, is the source of truth for what needs determining. Records
|
|
118
|
+
* written before Citation.RuleID was persisted on flags fall back to parsing
|
|
119
|
+
* the rule id out of the rationale's "(rule baseline:gov:<topic>)" tail.
|
|
120
|
+
*/
|
|
121
|
+
export declare const recordsToInputs: (records: readonly FlowdownDispositionRecord[]) => {
|
|
122
|
+
flags: FlowdownFlagInput[];
|
|
123
|
+
insertions: FlowdownInsertionInput[];
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Overlay persisted dispositions onto rows. A record matches a row when its
|
|
127
|
+
* id is the row's insertion id or one of its flag ids; the insertion id wins
|
|
128
|
+
* when both were disposed (it is the disposition the accept path writes).
|
|
129
|
+
* Rows without a matching non-proposed record keep their current
|
|
130
|
+
* determination (a merge, not a reset), so in-session decisions survive a
|
|
131
|
+
* fetch that raced them.
|
|
132
|
+
*/
|
|
133
|
+
export declare const mergeDispositions: (groups: readonly FlowdownGroup[], records: readonly FlowdownDispositionRecord[]) => FlowdownGroup[];
|
|
134
|
+
export interface FlowdownProgress {
|
|
135
|
+
total: number;
|
|
136
|
+
determined: number;
|
|
137
|
+
inserted: number;
|
|
138
|
+
rejected: number;
|
|
139
|
+
}
|
|
140
|
+
export declare const flowdownProgress: (groups: readonly FlowdownGroup[]) => FlowdownProgress;
|
|
141
|
+
/**
|
|
142
|
+
* Project rows onto the flowdown-matrix export's entries: one entry per
|
|
143
|
+
* parsed clause. `clause` is the bare number (the backend's contract),
|
|
144
|
+
* `source` the full FAR/DFARS citation; the whole baseline is `required`.
|
|
145
|
+
*/
|
|
146
|
+
export declare const matrixEntriesFromGroups: (groups: readonly FlowdownGroup[]) => {
|
|
147
|
+
clause: string;
|
|
148
|
+
source: string;
|
|
149
|
+
classification: string;
|
|
150
|
+
}[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type VersionsApiConfig } from "@/api/versions";
|
|
2
|
+
export interface PlaybookVersionHistoryProps {
|
|
3
|
+
/** The playbook whose history to show. */
|
|
4
|
+
playbookId: string;
|
|
5
|
+
/** Display name for the header (falls back to the id). */
|
|
6
|
+
playbookName?: string;
|
|
7
|
+
/** API endpoint config (base URL / workspace). */
|
|
8
|
+
api?: VersionsApiConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare const PlaybookVersionHistory: ({ playbookId, playbookName, api, }: PlaybookVersionHistoryProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule-id diff between two playbook versions' /rules payloads (client-side —
|
|
3
|
+
* the backend serves each version's rules, never a diff).
|
|
4
|
+
*/
|
|
5
|
+
import type { VersionRule } from "@/api/versions";
|
|
6
|
+
export interface RuleDiff {
|
|
7
|
+
/** Rule ids present in `current` but not `previous`. */
|
|
8
|
+
added: string[];
|
|
9
|
+
/** Rule ids present in `previous` but not `current`. */
|
|
10
|
+
removed: string[];
|
|
11
|
+
/** Rule ids present in both whose rule payload differs. */
|
|
12
|
+
changed: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare const diffRules: (previous: VersionRule[], current: VersionRule[]) => RuleDiff;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Playbook, type Rule } from "@/api/playbook";
|
|
2
|
+
import type { PlaybookFilter } from "@/constants/playbook";
|
|
3
|
+
import { type CdtsScope } from "@/utils/cdts";
|
|
4
|
+
import { type FetchState } from "./usePlaybookData";
|
|
5
|
+
export interface AllPlaybooksViewProps {
|
|
6
|
+
docScope: CdtsScope;
|
|
7
|
+
playbooksState: FetchState<Playbook[]>;
|
|
8
|
+
onRetry: () => void;
|
|
9
|
+
search: string;
|
|
10
|
+
onSearchChange: (query: string) => void;
|
|
11
|
+
filter: PlaybookFilter;
|
|
12
|
+
onFilterChange: (filter: PlaybookFilter) => void;
|
|
13
|
+
firedCounts: ReadonlyMap<string, number> | null;
|
|
14
|
+
justSavedRuleIds: ReadonlySet<string>;
|
|
15
|
+
onEditRule: (rule: Rule) => void;
|
|
16
|
+
onDuplicateRule: (rule: Rule, bundled: boolean) => void;
|
|
17
|
+
onShowSuggestions?: (ruleId: string) => void;
|
|
18
|
+
onNewPlaybook?: () => void;
|
|
19
|
+
onImport?: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Drill-in state lifted to the panel: while a playbook is open the drill-in
|
|
22
|
+
* renders its own footer, so the panel must hide the list-level one rather
|
|
23
|
+
* than stacking two footers.
|
|
24
|
+
*/
|
|
25
|
+
onDrillChange?: (playbook: Playbook | null) => void;
|
|
26
|
+
onNewRule?: (playbook: Playbook) => void;
|
|
27
|
+
onDeleteRule?: (rule: Rule) => void;
|
|
28
|
+
/** Opens the full-page playbook surface (⤢ in the drill-in footer). */
|
|
29
|
+
onOpenFullPage?: (playbook: Playbook) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Duplicates a whole bundled playbook into the workspace. Omitted → the
|
|
32
|
+
* built-in flow runs (duplicatePlaybookToWorkspace: POST /v1/playbooks +
|
|
33
|
+
* one rule copy per rule).
|
|
34
|
+
*/
|
|
35
|
+
onDuplicatePlaybook?: (playbook: Playbook) => void;
|
|
36
|
+
/** Rules ignored workspace-wide (durable rule-overrides). */
|
|
37
|
+
ignoredRuleIds?: ReadonlySet<string>;
|
|
38
|
+
onIgnoreRule?: (rule: Rule) => void;
|
|
39
|
+
onUnignoreRule?: (ruleId: string) => void;
|
|
40
|
+
}
|
|
41
|
+
export declare const AllPlaybooksView: (props: AllPlaybooksViewProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface DerivedRulebookViewProps {
|
|
2
|
+
/** Prime contract id — the rulebook key. */
|
|
3
|
+
primeContractId: string;
|
|
4
|
+
/** Shown in the header above the coordinate line. */
|
|
5
|
+
title?: string;
|
|
6
|
+
onClose?: () => void;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const DerivedRulebookView: (props: DerivedRulebookViewProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DraftedRulePreview — the single way a drafted (uncommitted) rule renders:
|
|
3
|
+
* category hue dot + display category + severity chip, the caller-supplied
|
|
4
|
+
* rule-text body, then the one-line predicate summary. Shared by
|
|
5
|
+
* AddAsRuleModal and PromotionSuggestions so the two preview surfaces cannot
|
|
6
|
+
* drift.
|
|
7
|
+
*/
|
|
8
|
+
import type { ReactNode } from "react";
|
|
9
|
+
import type { PredicateNode } from "@/api/ruleBuilder";
|
|
10
|
+
export interface DraftedRulePreviewProps {
|
|
11
|
+
category: string;
|
|
12
|
+
severity: string;
|
|
13
|
+
predicate?: PredicateNode;
|
|
14
|
+
/** The rule-text body, rendered between the chip row and the predicate. */
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
}
|
|
17
|
+
export declare const DraftedRulePreview: ({ category, severity, predicate, children, }: DraftedRulePreviewProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type PlaybookApiConfig } from "@/api/playbook";
|
|
2
|
+
import { type CdtsScope } from "@/utils/cdts";
|
|
3
|
+
export interface EffectiveRulesViewProps {
|
|
4
|
+
/** Resolves the attached prime (`lax.primeContract.{documentId}`) so this
|
|
5
|
+
* prime's derived rulebook joins the union, exactly as a run would. */
|
|
6
|
+
documentId?: string;
|
|
7
|
+
/** CDTS coordinate for the walk. Omitted ⇒ the workspace's full union. */
|
|
8
|
+
scope?: CdtsScope;
|
|
9
|
+
api?: PlaybookApiConfig;
|
|
10
|
+
}
|
|
11
|
+
export declare const EffectiveRulesView: ({ documentId, scope, api }: EffectiveRulesViewProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Playbook, type Rule } from "@/api/playbook";
|
|
2
|
+
export interface NewRuleDrawerProps {
|
|
3
|
+
playbook: Playbook;
|
|
4
|
+
/** Documents currently using this playbook — costs the re-review offer. */
|
|
5
|
+
affectedDocumentCount?: number;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
onSaved: (rule: Rule) => void;
|
|
8
|
+
/** Called after save when the author opted into re-reviewing open documents. */
|
|
9
|
+
onRunAgainstOpenDocuments?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export declare const NewRuleDrawer: (props: NewRuleDrawerProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlaybookCard — REQ-P4: CDTS-hue icon tile (REQ-T6) · name (one line,
|
|
3
|
+
* ellipsis) · CDTS coordinate (one line, ellipsis) · green "active" chip when
|
|
4
|
+
* on this document's walk-up chain · rule count · chevron (drills in).
|
|
5
|
+
*/
|
|
6
|
+
import type { Playbook } from "@/api/playbook";
|
|
7
|
+
export interface PlaybookCardProps {
|
|
8
|
+
playbook: Playbook;
|
|
9
|
+
active: boolean;
|
|
10
|
+
ruleCount?: number;
|
|
11
|
+
onOpen: (playbook: Playbook) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare const PlaybookCard: ({ playbook, active, ruleCount, onOpen }: PlaybookCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Playbook, type Rule } from "@/api/playbook";
|
|
2
|
+
export interface PlaybookPageProps {
|
|
3
|
+
playbook: Playbook;
|
|
4
|
+
/** rule_id → times fired in the currently-open document. */
|
|
5
|
+
firedCounts?: ReadonlyMap<string, number> | null;
|
|
6
|
+
/**
|
|
7
|
+
* Dismisses the modal (✕, Esc, or scrim click). Aliased by
|
|
8
|
+
* `onBackToDocument` for callers written against the full-page version.
|
|
9
|
+
*/
|
|
10
|
+
onClose?: () => void;
|
|
11
|
+
/** @deprecated Use `onClose`. Kept so existing call sites keep working. */
|
|
12
|
+
onBackToDocument?: () => void;
|
|
13
|
+
/** Breadcrumb root, e.g. the workspace name. */
|
|
14
|
+
workspaceName?: string;
|
|
15
|
+
/** Header meta line, e.g. "Edited 3 days ago · A. Reyes". */
|
|
16
|
+
editedLabel?: string;
|
|
17
|
+
/** Documents this playbook is active on (header chip + drawer cost line). */
|
|
18
|
+
activeDocumentCount?: number;
|
|
19
|
+
onEditRule?: (rule: Rule) => void;
|
|
20
|
+
onDuplicatePlaybook?: (playbook: Playbook) => void;
|
|
21
|
+
onOpenSettings?: (playbook: Playbook) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Version history. No backend endpoint exists for this yet, so the link is
|
|
24
|
+
* only rendered when the host supplies a handler.
|
|
25
|
+
*/
|
|
26
|
+
onOpenVersionHistory?: (playbook: Playbook) => void;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare const PlaybookPage: (props: PlaybookPageProps) => import("react").ReactPortal;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type Playbook, type PlaybookApiConfig } from "@/api/playbook";
|
|
2
|
+
import { type CdtsScope } from "@/utils/cdts";
|
|
3
|
+
import { type ReviewResponseLike } from "@/utils/groundingAdapter";
|
|
4
|
+
export interface SaveAsRulePrefill {
|
|
5
|
+
name?: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
category?: string;
|
|
8
|
+
sourceRuleId?: string;
|
|
9
|
+
section?: string;
|
|
10
|
+
clauseQuote?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Dismissals the host persists across documents, keyed by rule id. */
|
|
13
|
+
export interface RuleDismissalRecord {
|
|
14
|
+
ruleId: string;
|
|
15
|
+
documentCount: number;
|
|
16
|
+
}
|
|
17
|
+
export interface PlaybookPanelProps {
|
|
18
|
+
/** Document CDTS coordinate — drives the this-document walk-up chain. */
|
|
19
|
+
documentScope: CdtsScope;
|
|
20
|
+
documentId?: string;
|
|
21
|
+
workspaceId?: string;
|
|
22
|
+
workspaceName?: string;
|
|
23
|
+
/** Regime chips on the scope card, e.g. ["FAR / DFARS", "gov"]. */
|
|
24
|
+
regimeLabels?: string[];
|
|
25
|
+
/** Latest review response (grounding[] sidecar) — null before any run. */
|
|
26
|
+
reviewResponse?: ReviewResponseLike | null;
|
|
27
|
+
onClose?: () => void;
|
|
28
|
+
/** Cross-link: rule detail → AI tab filtered to the rule (REQ-B3). */
|
|
29
|
+
onShowSuggestionsForRule?: (ruleId: string) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Optional one-click re-run offer after a save (REQ-B2). Never auto-runs.
|
|
32
|
+
* Receives the rules the reviewer suppressed, so the next run can pass them
|
|
33
|
+
* as `disabled_rule_ids` — per-run only, no playbook mutation.
|
|
34
|
+
*/
|
|
35
|
+
onRunReview?: (options?: {
|
|
36
|
+
disabledRuleIds: string[];
|
|
37
|
+
}) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Rules the server reports the reviewer keeps rejecting (`rule_fatigue`).
|
|
40
|
+
* Server-side and durable per (workspace, rule), so it survives reloads and
|
|
41
|
+
* counts real rejections rather than this session's dismissals.
|
|
42
|
+
*/
|
|
43
|
+
ruleFatigue?: readonly {
|
|
44
|
+
rule_id: string;
|
|
45
|
+
rejections: number;
|
|
46
|
+
}[];
|
|
47
|
+
/** Cross-link target: suggestion grounding → "View rule ⚖" (REQ-B3). */
|
|
48
|
+
focusedRuleId?: string | null;
|
|
49
|
+
/** Dismiss + save-as-rule trigger: opens the editor pre-filled (REQ-M1). */
|
|
50
|
+
saveAsRulePrefill?: SaveAsRulePrefill | null;
|
|
51
|
+
onNewPlaybook?: () => void;
|
|
52
|
+
onImportPlaybook?: () => void;
|
|
53
|
+
onOpenSettings?: () => void;
|
|
54
|
+
/** Auth/baseUrl pass-through for src/api/playbook.ts (REQ-D1). */
|
|
55
|
+
api?: PlaybookApiConfig;
|
|
56
|
+
/**
|
|
57
|
+
* Opens the full-page playbook surface. This library ships no router, so the
|
|
58
|
+
* host decides how to route/mount `PlaybookPage`; omitted → no ⤢ affordance.
|
|
59
|
+
*/
|
|
60
|
+
onOpenPlaybookPage?: (playbook: Playbook) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Prior dismissals of a rule across other documents. Dismissal itself is
|
|
63
|
+
* client-side, but the *count* that drives the escalation nudge only means
|
|
64
|
+
* anything if the host persists it; omitted → the nudge never fires.
|
|
65
|
+
*/
|
|
66
|
+
priorDismissals?: readonly RuleDismissalRecord[];
|
|
67
|
+
/** Fired when the reviewer asks the owner to remove a repeatedly-dismissed rule. */
|
|
68
|
+
onSuggestRuleRemoval?: (ruleId: string) => void;
|
|
69
|
+
/** Name shown on the escalation nudge ("goes to <owner>"). */
|
|
70
|
+
playbookOwnerName?: string;
|
|
71
|
+
className?: string;
|
|
72
|
+
}
|
|
73
|
+
export declare const PlaybookPanel: (props: PlaybookPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PromotionSuggestions: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type V6Severity } from "@/constants/playbook";
|
|
2
|
+
export type ReprioritizeDirection = "demote" | "escalate";
|
|
3
|
+
/** One rung on the ladder; undefined when already at the end. */
|
|
4
|
+
export declare const steppedSeverity: (current: V6Severity, direction: ReprioritizeDirection) => V6Severity | undefined;
|
|
5
|
+
export interface ReprioritizeDialogProps {
|
|
6
|
+
direction: ReprioritizeDirection;
|
|
7
|
+
ruleName: string;
|
|
8
|
+
currentSeverity: V6Severity;
|
|
9
|
+
nextSeverity: V6Severity;
|
|
10
|
+
busy: boolean;
|
|
11
|
+
/** Inline error under the textarea; null when none. */
|
|
12
|
+
error: string | null;
|
|
13
|
+
onCancel: () => void;
|
|
14
|
+
onConfirm: (note: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare const ReprioritizeDialog: (props: ReprioritizeDialogProps) => import("react").ReactPortal;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RuleDetail — REQ-R3 inline accordion body: full rule text in an inset well
|
|
3
|
+
* → meta chips → actions row. REQ-R4 bundled/workspace asymmetry: bundled
|
|
4
|
+
* rules NEVER get an Edit affordance that would 403 — only "Duplicate to
|
|
5
|
+
* workspace". Rule text renders as text, never HTML.
|
|
6
|
+
*/
|
|
7
|
+
import { type Rule } from "@/api/playbook";
|
|
8
|
+
import { type FiredState } from "./primitives";
|
|
9
|
+
export interface RuleDetailProps {
|
|
10
|
+
rule: Rule;
|
|
11
|
+
bundled: boolean;
|
|
12
|
+
fired: FiredState;
|
|
13
|
+
onEdit?: (rule: Rule) => void;
|
|
14
|
+
onDuplicate?: (rule: Rule) => void;
|
|
15
|
+
onShowSuggestions?: (ruleId: string) => void;
|
|
16
|
+
/** Dismissed for this document only (client-side, reversible). */
|
|
17
|
+
dismissed?: boolean;
|
|
18
|
+
onDismiss?: (rule: Rule) => void;
|
|
19
|
+
onRestore?: (ruleId: string) => void;
|
|
20
|
+
/** Permanent removal (DELETE /v1/rules/{id}). Omitted → not offered. */
|
|
21
|
+
onDelete?: (rule: Rule) => void;
|
|
22
|
+
/** Workspace-wide ignore (PUT/DELETE /v1/rule-overrides/{family}). */
|
|
23
|
+
ignored?: boolean;
|
|
24
|
+
onIgnore?: (rule: Rule) => void;
|
|
25
|
+
onUnignore?: (ruleId: string) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare const RuleDetail: ({ rule, bundled, fired, onEdit, onDuplicate, onShowSuggestions, dismissed, onDismiss, onRestore, onDelete, ignored, onIgnore, onUnignore, }: RuleDetailProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule editor form fields — REQ-M2. Field-level validation renders inline
|
|
3
|
+
* (never a toast, §5). All text renders as text, never HTML.
|
|
4
|
+
*/
|
|
5
|
+
import { type DisplayCategory, type NegotiationTier } from "@/constants/playbook";
|
|
6
|
+
export interface RuleEditorProvenance {
|
|
7
|
+
sourceRuleId?: string;
|
|
8
|
+
section?: string;
|
|
9
|
+
clauseQuote?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RuleFieldErrors {
|
|
12
|
+
name?: string;
|
|
13
|
+
category?: string;
|
|
14
|
+
text?: string;
|
|
15
|
+
scope?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ScopeOption {
|
|
18
|
+
id: string;
|
|
19
|
+
label: string;
|
|
20
|
+
}
|
|
21
|
+
export interface RuleEditorFieldsProps {
|
|
22
|
+
disabled: boolean;
|
|
23
|
+
name: string;
|
|
24
|
+
onNameChange: (value: string) => void;
|
|
25
|
+
category: DisplayCategory | null;
|
|
26
|
+
onCategoryChange: (value: DisplayCategory) => void;
|
|
27
|
+
tier: NegotiationTier;
|
|
28
|
+
onTierChange: (value: NegotiationTier) => void;
|
|
29
|
+
text: string;
|
|
30
|
+
onTextChange: (value: string) => void;
|
|
31
|
+
scope: "document" | "playbook";
|
|
32
|
+
onScopeChange: (value: "document" | "playbook") => void;
|
|
33
|
+
playbookOptions: ScopeOption[];
|
|
34
|
+
selectedPlaybookId: string | null;
|
|
35
|
+
onPlaybookChange: (id: string) => void;
|
|
36
|
+
documentScopeAvailable: boolean;
|
|
37
|
+
errors: RuleFieldErrors;
|
|
38
|
+
provenance?: RuleEditorProvenance;
|
|
39
|
+
/** Stack the scope cards vertically (<640px sheet, REQ-V3). */
|
|
40
|
+
stacked: boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare const RuleEditorFields: (props: RuleEditorFieldsProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type CdtsScope, type Rule } from "@/api/playbook";
|
|
2
|
+
import { type RuleEditorProvenance, type ScopeOption } from "./RuleEditorFields";
|
|
3
|
+
export interface RuleEditorSession {
|
|
4
|
+
mode: "create" | "edit";
|
|
5
|
+
/** Existing rule (edit mode). */
|
|
6
|
+
rule?: Rule;
|
|
7
|
+
/** Prefill for create mode (duplicate / dismiss + save-as-rule). */
|
|
8
|
+
prefill?: {
|
|
9
|
+
name?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
category?: string;
|
|
12
|
+
};
|
|
13
|
+
/** Blue provenance strip for the save-as-rule path (REQ-M1). */
|
|
14
|
+
provenance?: RuleEditorProvenance;
|
|
15
|
+
title?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface RuleEditorModalProps {
|
|
18
|
+
session: RuleEditorSession;
|
|
19
|
+
documentId?: string;
|
|
20
|
+
/** The document's CDTS scope — carried onto the auto-created doc playbook. */
|
|
21
|
+
documentScope?: CdtsScope;
|
|
22
|
+
playbookOptions: ScopeOption[];
|
|
23
|
+
defaultPlaybookId?: string;
|
|
24
|
+
onClose: () => void;
|
|
25
|
+
onSaved: (rule: Rule) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare const RuleEditorModal: (props: RuleEditorModalProps) => import("react").ReactPortal;
|