yarramate 1.2.0 → 1.4.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/catalogues/core-enrichment.yaml +237 -2
- package/dist/adapters/visual/session-server.js +16 -1
- package/dist/adapters/visual/view-identity.d.ts +1 -1
- package/dist/adapters/visual/view-identity.js +61 -3
- package/dist/adapters/visual/wire.d.ts +30 -0
- package/dist/adapters/visual/workspace-model.d.ts +35 -3
- package/dist/adapters/visual/workspace-model.js +62 -2
- package/dist/ask-command.js +37 -14
- package/dist/cli-support.d.ts +1 -1
- package/dist/cli-support.js +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +26 -5
- package/dist/compiler.d.ts +13 -1
- package/dist/compiler.js +646 -0
- package/dist/concept-drafting.d.ts +13 -2
- package/dist/concept-drafting.js +15 -3
- package/dist/design-command.js +30 -4
- package/dist/evidence.js +25 -0
- package/dist/graph-projection.d.ts +10 -0
- package/dist/graph-projection.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/interrogate-command.d.ts +37 -1
- package/dist/interrogate-command.js +93 -42
- package/dist/interrogation-entry.d.ts +1 -1
- package/dist/layout-direction.d.ts +14 -0
- package/dist/layout-direction.js +5 -0
- package/dist/projection.d.ts +22 -6
- package/dist/projection.js +23 -2
- package/dist/relationship-drafting.d.ts +21 -2
- package/dist/relationship-drafting.js +49 -4
- package/dist/subject-references.js +5 -0
- package/dist/visual-app/assets/index-Rkq6smL2.css +1 -0
- package/dist/visual-app/assets/index-yCHtmQUH.js +394 -0
- package/dist/visual-app/index.html +2 -2
- package/dist/visual-app-lib/editor.js +29639 -27514
- package/dist/visual-app-lib/styles.css +1 -1
- package/dist/visual-app-lib/types/adapters/visual/view-identity.d.ts +1 -1
- package/dist/visual-app-lib/types/adapters/visual/wire.d.ts +30 -0
- package/dist/visual-app-lib/types/adapters/visual/workspace-model.d.ts +35 -3
- package/dist/visual-app-lib/types/compiler.d.ts +13 -1
- package/dist/visual-app-lib/types/concept-drafting.d.ts +13 -2
- package/dist/visual-app-lib/types/graph-projection.d.ts +10 -0
- package/dist/visual-app-lib/types/interrogate-command.d.ts +207 -0
- package/dist/visual-app-lib/types/layout-direction.d.ts +14 -0
- package/dist/visual-app-lib/types/projection.d.ts +22 -6
- package/dist/visual-app-lib/types/relationship-drafting.d.ts +21 -2
- package/dist/visual-app-lib/types/subject-identity.d.ts +34 -0
- package/dist/visual-app-lib/types/visual-app/App.d.ts +27 -2
- package/dist/visual-app-lib/types/visual-app/badges.d.ts +1 -0
- package/dist/visual-app-lib/types/visual-app/connection-panel.d.ts +9 -1
- package/dist/visual-app-lib/types/visual-app/context-menu-model.d.ts +15 -6
- package/dist/visual-app-lib/types/visual-app/graph-canvas.d.ts +77 -6
- package/dist/visual-app-lib/types/visual-app/kind-palette.d.ts +37 -0
- package/dist/visual-app-lib/types/visual-app/local-host.d.ts +42 -0
- package/dist/visual-app-lib/types/visual-app/mount.d.ts +73 -2
- package/dist/visual-app-lib/types/visual-app/open-questions.d.ts +15 -0
- package/dist/visual-app-lib/types/visual-app/query-fields.d.ts +3 -2
- package/dist/visual-app-lib/types/visual-app/query-panel.d.ts +8 -1
- package/dist/visual-app-lib/types/visual-app/save-view.d.ts +11 -5
- package/dist/visual-app-lib/types/visual-app/shipped-catalogue.d.ts +10 -0
- package/dist/visual-app-lib/types/visual-app/state.d.ts +15 -4
- package/dist/visual-app-lib/types/visual-app/subject-draft-panel.d.ts +13 -1
- package/dist/visual-app-lib/types/visual-app/subject-filter.d.ts +35 -0
- package/dist/visual-app-lib/types/visual-app/subject-form.d.ts +8 -0
- package/dist/visual-app-lib/types/visual-app/view-tree-model.d.ts +42 -9
- package/dist/visual-app-lib/types/visual-app/view-tree.d.ts +11 -2
- package/dist/visual-app-lib/types/visual-app/workspace-state.d.ts +81 -11
- package/dist/visual-app-lib/types/workspace.d.ts +2 -0
- package/dist/workspace.d.ts +2 -0
- package/dist/workspace.js +1 -0
- package/docs/CONSUMING-YARRAMATE.md +81 -0
- package/package.json +2 -1
- package/schema/yarramate-design-step.schema.json +26 -0
- package/schema/yarramate-document.schema.json +14 -0
- package/schema/yarramate-interrogation-report.schema.json +31 -0
- package/schema/yarramate-pattern.schema.json +133 -0
- package/schema/yarramate-projection.schema.json +9 -0
- package/schema/yarramate-question-catalogue.schema.json +34 -0
- package/schema/yarramate-visual-graph.schema.json +9 -0
- package/schema/yarramate-workspace.schema.json +4 -0
- package/skills/yarramate-architecture/SKILL.md +5 -0
- package/dist/visual-app/assets/index-CcmfL3oY.js +0 -394
- package/dist/visual-app/assets/index-DLutIWES.css +0 -1
|
@@ -33,8 +33,16 @@ export declare const connectableKinds: (graph: CanvasGraph, fromId: string, toId
|
|
|
33
33
|
* relationship kind is a single lowercase word. A collision takes a numeric
|
|
34
34
|
* suffix rather than a hash, because the id is authored text a human will read
|
|
35
35
|
* in a diff.
|
|
36
|
+
*
|
|
37
|
+
* `reserved` carries ids the graph does not know yet: a staged-but-uncommitted
|
|
38
|
+
* draft never enters the rendered graph, so without it a second relationship
|
|
39
|
+
* between the same pair re-proposed the identical id and the editor's
|
|
40
|
+
* replace-by-target staging silently swallowed the first (#306). The schema
|
|
41
|
+
* places no uniqueness on the (from, kind, to) triple - parallel relationships
|
|
42
|
+
* with distinct ids compile cleanly - so the id proposal is the only place the
|
|
43
|
+
* collision can be stepped past.
|
|
36
44
|
*/
|
|
37
|
-
export declare const proposeRelationshipId: (graph: CanvasGraph, fromId: string, kind: RelationshipKind, toId: string) => string;
|
|
45
|
+
export declare const proposeRelationshipId: (graph: CanvasGraph, fromId: string, kind: RelationshipKind, toId: string, reserved?: Iterable<string>) => string;
|
|
38
46
|
/**
|
|
39
47
|
* The operation that lands a drafted relationship, or `null` when the draft is
|
|
40
48
|
* one the table does not permit.
|
|
@@ -47,5 +55,16 @@ export declare const proposeRelationshipId: (graph: CanvasGraph, fromId: string,
|
|
|
47
55
|
* relationship has to live somewhere, both endpoints are equally defensible,
|
|
48
56
|
* and the source is where a reader looking for what this thing does would go
|
|
49
57
|
* first.
|
|
58
|
+
*
|
|
59
|
+
* A caller holding drafts the graph has not landed yet - an editor with a
|
|
60
|
+
* pending changeset - passes their ids as `reserved`, so a second parallel
|
|
61
|
+
* relationship steps to `-2` instead of colliding with the first (#306).
|
|
62
|
+
*/
|
|
63
|
+
export declare const draftRelationship: (graph: CanvasGraph, fromId: string, kind: RelationshipKind, toId: string, reserved?: Iterable<string>) => YarramateOperation | null;
|
|
64
|
+
/**
|
|
65
|
+
* The ids a pending changeset already claims, for `proposeRelationshipId`'s
|
|
66
|
+
* `reserved` parameter. Every operation that names a subject id reserves it -
|
|
67
|
+
* an update's id is already in the graph and reserving it twice is harmless,
|
|
68
|
+
* while an add's id is exactly the one the graph cannot know yet.
|
|
50
69
|
*/
|
|
51
|
-
export declare const
|
|
70
|
+
export declare const stagedSubjectIds: (operations: readonly YarramateOperation[]) => readonly string[];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare const normalizeLabel: (label: string) => readonly string[];
|
|
2
|
+
export declare const headTokens: (tokens: readonly string[]) => readonly string[];
|
|
3
|
+
export declare const similarity: (left: string, right: string) => number;
|
|
4
|
+
export interface IdentitySubject {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly kind: string;
|
|
7
|
+
readonly labels: readonly string[];
|
|
8
|
+
readonly owner?: string;
|
|
9
|
+
readonly neighbours: ReadonlySet<string>;
|
|
10
|
+
readonly distinctFrom: ReadonlySet<string>;
|
|
11
|
+
}
|
|
12
|
+
export interface NearDuplicatePair {
|
|
13
|
+
readonly left: string;
|
|
14
|
+
readonly right: string;
|
|
15
|
+
readonly score: number;
|
|
16
|
+
readonly corroboration: 'lexical' | 'owner' | 'neighbourhood';
|
|
17
|
+
}
|
|
18
|
+
export declare const strongLexicalThreshold = 0.95;
|
|
19
|
+
export declare const moderateLexicalThreshold = 0.8;
|
|
20
|
+
export declare const lexicalScore: (left: IdentitySubject, right: IdentitySubject) => number;
|
|
21
|
+
/**
|
|
22
|
+
* Every candidate near-duplicate pair, sorted by subject id. Only subjects
|
|
23
|
+
* of the same qualified kind are compared: kind is the cheapest structural
|
|
24
|
+
* disagreement there is, and it also bounds the pairwise cost to the square
|
|
25
|
+
* of the largest kind bucket rather than of the whole model.
|
|
26
|
+
*/
|
|
27
|
+
export declare const findNearDuplicates: (subjects: readonly IdentitySubject[]) => readonly NearDuplicatePair[];
|
|
28
|
+
/**
|
|
29
|
+
* Both members of every candidate pair, mapped to their counterparts. The
|
|
30
|
+
* question attaches to both sides deliberately: `ask --advise` filters open
|
|
31
|
+
* questions to the subjects in a slice, so a finding recorded only against
|
|
32
|
+
* the lexically-first member would vanish from a slice seeded on the other.
|
|
33
|
+
*/
|
|
34
|
+
export declare const nearDuplicateIndex: (subjects: readonly IdentitySubject[]) => ReadonlyMap<string, readonly string[]>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type DecorationMap } from "./graph-canvas.js";
|
|
1
2
|
import type { EditorHost } from "./editor-host.js";
|
|
2
|
-
import { type RightSectionId } from "./workspace-state.js";
|
|
3
|
+
import { type EditorPointer, type RightSectionId } from "./workspace-state.js";
|
|
3
4
|
/**
|
|
4
5
|
* The editor.
|
|
5
6
|
*
|
|
@@ -8,8 +9,32 @@ import { type RightSectionId } from "./workspace-state.js";
|
|
|
8
9
|
* embedder's own store with no server at all. `sections` is what the host
|
|
9
10
|
* wants shown - a product with no agent behind it leaves `chat` out, and the
|
|
10
11
|
* section and the session button go with it.
|
|
12
|
+
*
|
|
13
|
+
* `readOnly` is one flag, threaded once (#298, ADR 0117): a viewer keeps
|
|
14
|
+
* everything that reads - the canvas, the tree, the query fields, the facts,
|
|
15
|
+
* the questions - and every affordance that stages or commits is absent
|
|
16
|
+
* rather than disabled. A UI posture only: whatever this shell draws, the
|
|
17
|
+
* host still answers for its own store.
|
|
11
18
|
*/
|
|
12
|
-
export declare const App: ({ host, sections, }: {
|
|
19
|
+
export declare const App: ({ host, sections, readOnly, decorations: initialDecorations, onReady, }: {
|
|
13
20
|
readonly host: EditorHost;
|
|
14
21
|
readonly sections?: readonly RightSectionId[];
|
|
22
|
+
readonly readOnly?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The host's per-subject marks at mount time (#314, ADR 0119) - the
|
|
25
|
+
* initial value only, the way React means an initial value: later
|
|
26
|
+
* hand-overs travel through the pointer's `setDecorations`, each one
|
|
27
|
+
* replacing the map wholesale. Client state like selection, so it rides a
|
|
28
|
+
* prop rather than the `EditorHost` seam.
|
|
29
|
+
*/
|
|
30
|
+
readonly decorations?: DecorationMap;
|
|
31
|
+
/**
|
|
32
|
+
* How the mount layer's handle reaches this shell's reducer (#297,
|
|
33
|
+
* ADR 0118). Called once, after the first render, with the pointer the
|
|
34
|
+
* handle delegates to - which is what makes the handle's pre-ready
|
|
35
|
+
* false-return window real. Selection and dialog state are client state,
|
|
36
|
+
* so this rides a prop rather than the `EditorHost` seam: the protocol
|
|
37
|
+
* carries documents, not gestures.
|
|
38
|
+
*/
|
|
39
|
+
readonly onReady?: (pointer: EditorPointer) => void;
|
|
15
40
|
}) => import("react").JSX.Element;
|
|
@@ -4,4 +4,5 @@ export declare const LIFECYCLE_BADGE_URI: Record<LifecycleStatus, string>;
|
|
|
4
4
|
export declare const EVIDENCE_BADGE_URI: string;
|
|
5
5
|
export declare function ownerColorOf(owner: string | null): string | null;
|
|
6
6
|
export declare function ownerBadgeUri(owner: string, initials: string): string;
|
|
7
|
+
export declare function openQuestionsBadgeUri(count: number): string;
|
|
7
8
|
export declare function ownerInitialsOf(owner: string | null): string | null;
|
|
@@ -15,9 +15,17 @@ import type { ConnectionDraft } from './workspace-state.js';
|
|
|
15
15
|
* means an endpoint outside the ArchiMate vocabulary rather than a dead end,
|
|
16
16
|
* and the panel says which.
|
|
17
17
|
*/
|
|
18
|
-
export declare const ConnectionPanel: ({ draft, graph, onStage, onCancel, }: {
|
|
18
|
+
export declare const ConnectionPanel: ({ draft, graph, reservedIds, onStage, onCancel, }: {
|
|
19
19
|
readonly draft: ConnectionDraft;
|
|
20
20
|
readonly graph: CanvasGraph;
|
|
21
|
+
/**
|
|
22
|
+
* Ids the pending changeset already claims. The graph only knows what has
|
|
23
|
+
* landed, so without these a second relationship between the same pair
|
|
24
|
+
* proposed the identical id and replace-by-target staging swallowed it
|
|
25
|
+
* silently (#306). Required rather than defaulted: a caller has to say
|
|
26
|
+
* what is staged, even when the answer is nothing.
|
|
27
|
+
*/
|
|
28
|
+
readonly reservedIds: readonly string[];
|
|
21
29
|
readonly onStage: (operation: YarramateOperation) => void;
|
|
22
30
|
readonly onCancel: () => void;
|
|
23
31
|
}) => React.ReactElement;
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import type { CanvasGraph } from "../graph-projection.js";
|
|
26
26
|
import type { VisualKindOption } from "../adapters/visual/protocol-contract.js";
|
|
27
|
+
import type { ActiveViewMembership } from "./state.js";
|
|
27
28
|
/** The id of the "All subjects" row, which is the absence of a view. */
|
|
28
29
|
export declare const ALL_SUBJECTS_VIEW = "";
|
|
29
30
|
export type ContextMenuTarget = {
|
|
@@ -144,14 +145,22 @@ export interface ContextMenuContext {
|
|
|
144
145
|
/** Whether anything at all is narrowing the canvas right now. */
|
|
145
146
|
readonly filtered: boolean;
|
|
146
147
|
/**
|
|
147
|
-
*
|
|
148
|
+
* How the active view can be told what it holds, or `null` when no view is
|
|
149
|
+
* active and there is nothing to tell.
|
|
148
150
|
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
151
|
+
* A view that enumerates its subjects is told by its list; one that
|
|
152
|
+
* describes them with facets is told by `exclude` (#267, ADR 0122). A
|
|
153
|
+
* faceted view used to be `null` here, on the reasoning that an item which
|
|
154
|
+
* could only ever do nothing is worse than no item (#255) - true of adding a
|
|
155
|
+
* subject to a rule, and never true of taking one out of it.
|
|
153
156
|
*/
|
|
154
|
-
readonly membership:
|
|
157
|
+
readonly membership: ActiveViewMembership | null;
|
|
158
|
+
/**
|
|
159
|
+
* A viewer, not an author (#298, ADR 0117). A read-only menu keeps the items
|
|
160
|
+
* that read or navigate and drops every item whose intent stages a change -
|
|
161
|
+
* absent, never disabled.
|
|
162
|
+
*/
|
|
163
|
+
readonly readOnly?: boolean;
|
|
155
164
|
}
|
|
156
165
|
/**
|
|
157
166
|
* The menu for a target, already ordered: view groups first, model groups
|
|
@@ -1,22 +1,65 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import cytoscape from 'cytoscape';
|
|
3
|
-
import type { Core, NodeCollection } from 'cytoscape';
|
|
4
|
-
import type { CanvasGraph, CanvasEdge } from '../graph-projection.js';
|
|
3
|
+
import type { Core, ElementDefinition, NodeCollection } from 'cytoscape';
|
|
4
|
+
import type { CanvasGraph, CanvasNode, CanvasEdge } from '../graph-projection.js';
|
|
5
5
|
import { type NestingKind } from '../nesting.js';
|
|
6
|
+
import { type LayoutDirection } from '../layout-direction.js';
|
|
6
7
|
import type { VisualLayoutPositions, VisualLayoutSavePayload } from '../adapters/visual/protocol-contract.js';
|
|
7
8
|
import { LAYER_COLORS } from '../notation/archimate.js';
|
|
8
9
|
export { LAYER_COLORS };
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function
|
|
10
|
+
export declare function steppedZoom(current: number, direction: 1 | -1): number;
|
|
11
|
+
export declare function buildLayoutConfig(direction: LayoutDirection): cytoscape.LayoutOptions;
|
|
12
|
+
/**
|
|
13
|
+
* The closed mark vocabulary a host may hand the mounted viewer (#314,
|
|
14
|
+
* ADR 0119). Three marks, because three is what comparison against another
|
|
15
|
+
* model needs and a fourth waits for the demand that names it. What a mark
|
|
16
|
+
* MEANS - added relative to what, changed since when - lives entirely on the
|
|
17
|
+
* host's side of the seam: this canvas renders marks, it never diffs.
|
|
18
|
+
*/
|
|
19
|
+
export type DecorationMark = 'added' | 'removed' | 'changed';
|
|
20
|
+
/**
|
|
21
|
+
* Subject id (concepts and relationships alike) to mark. The whole map is the
|
|
22
|
+
* unit of exchange: each hand-over REPLACES the previous marks wholesale,
|
|
23
|
+
* never merges into them, and an id the current model does not name marks
|
|
24
|
+
* nothing, silently - the host may be describing subjects this model has not
|
|
25
|
+
* gained (or has already lost).
|
|
26
|
+
*/
|
|
27
|
+
export type DecorationMap = Readonly<Record<string, DecorationMark>>;
|
|
28
|
+
/**
|
|
29
|
+
* Marks every subject the host's decoration map names, the exact class
|
|
30
|
+
* mechanism faults use: previous `deco-*` classes come off every element
|
|
31
|
+
* first (replacement is wholesale, the map is the unit), then each id that
|
|
32
|
+
* names a drawn node or edge gains its mark's class. Unknown ids are
|
|
33
|
+
* silently inert. The `faulted` class is never touched here, and the
|
|
34
|
+
* stylesheet orders the fault rule after the decoration rules, so a subject
|
|
35
|
+
* both decorated and refused reads as refused.
|
|
36
|
+
*/
|
|
37
|
+
export declare function applyDecorations(cy: Core, decorations: DecorationMap): void;
|
|
38
|
+
export declare function buildStylesheet(showLifecycle: boolean, showEvidence: boolean, showOwnership: boolean, showNudges: boolean): cytoscape.StylesheetJsonBlock[];
|
|
11
39
|
export declare function resolveNestingParents(edges: readonly CanvasEdge[], nesting: readonly NestingKind[], kindOf: (id: string) => string): {
|
|
12
40
|
readonly parentOf: ReadonlyMap<string, string>;
|
|
13
41
|
readonly consumedEdgeIds: ReadonlySet<string>;
|
|
14
42
|
};
|
|
43
|
+
export declare function graphToElements(graph: CanvasGraph, nesting: readonly NestingKind[], openQuestionCounts: ReadonlyMap<string, number>): ElementDefinition[];
|
|
44
|
+
export declare function filteredSubjectCount(nodes: readonly Pick<CanvasNode, 'id' | 'name' | 'kindLabel'>[], matchedIds: readonly string[] | null, quickFilterText: string): number;
|
|
15
45
|
export declare function applyFilter(cy: Core, matchedIds: readonly string[] | null, quickFilterText: string): void;
|
|
16
|
-
export declare function relayoutVisible(cy: Core): void;
|
|
46
|
+
export declare function relayoutVisible(cy: Core, direction: LayoutDirection): void;
|
|
47
|
+
export declare function fitVisible(cy: Core): boolean;
|
|
17
48
|
export declare const DRAG_SAVE_DEBOUNCE_MS = 500;
|
|
18
49
|
export declare function buildPositionMap(nodes: NodeCollection): VisualLayoutPositions;
|
|
19
50
|
export declare function applySavedPositions(cy: Core, saved: VisualLayoutPositions | undefined): void;
|
|
51
|
+
export declare function effectiveSavedPositions(saved: VisualLayoutPositions | undefined, viewId: string, discardedViews: ReadonlySet<string>): VisualLayoutPositions | undefined;
|
|
52
|
+
export declare function savedLayoutInForce(saved: VisualLayoutPositions | undefined, graphNodeIds: readonly string[], matchedIds: readonly string[] | null): boolean;
|
|
53
|
+
export declare function modelPositionOf(rendered: {
|
|
54
|
+
readonly x: number;
|
|
55
|
+
readonly y: number;
|
|
56
|
+
}, pan: {
|
|
57
|
+
readonly x: number;
|
|
58
|
+
readonly y: number;
|
|
59
|
+
}, zoom: number): {
|
|
60
|
+
readonly x: number;
|
|
61
|
+
readonly y: number;
|
|
62
|
+
};
|
|
20
63
|
export interface DragSaveHandle {
|
|
21
64
|
/** Cancels a queued save without unbinding the drag listener. */
|
|
22
65
|
readonly cancelPending: () => void;
|
|
@@ -46,13 +89,41 @@ interface GraphCanvasProps {
|
|
|
46
89
|
readonly nesting: readonly NestingKind[];
|
|
47
90
|
/** Subjects a diagnostic named, marked so a failure is visible where it is. */
|
|
48
91
|
readonly faultedIds: ReadonlySet<string>;
|
|
92
|
+
/**
|
|
93
|
+
* The host's per-subject marks (#314, ADR 0119), rendered as `deco-*`
|
|
94
|
+
* classes the way faults are rendered. The map replaces wholesale on every
|
|
95
|
+
* change; an empty map draws nothing, an unknown id marks nothing, and a
|
|
96
|
+
* subject that is also faulted reads as faulted.
|
|
97
|
+
*/
|
|
98
|
+
readonly decorations: DecorationMap;
|
|
49
99
|
readonly showLifecycle: boolean;
|
|
50
100
|
readonly showEvidence: boolean;
|
|
51
101
|
readonly showOwnership: boolean;
|
|
102
|
+
readonly showNudges: boolean;
|
|
103
|
+
/** Open-question count per subject id, from the model's interrogation
|
|
104
|
+
* overlay; an empty map (host shipped no overlay) draws no chips. */
|
|
105
|
+
readonly openQuestionCounts: ReadonlyMap<string, number>;
|
|
52
106
|
readonly activeViewId: string;
|
|
107
|
+
/**
|
|
108
|
+
* Which way the active view runs its layers (#274, ADR 0121), from its
|
|
109
|
+
* `presentation.direction`. A view that declares none is handed
|
|
110
|
+
* `DEFAULT_DIRECTION`, so the canvas never has to decide what silence means.
|
|
111
|
+
*/
|
|
112
|
+
readonly direction: LayoutDirection;
|
|
53
113
|
/** Saved layout for the active view, or undefined when it has none yet. */
|
|
54
114
|
readonly savedPositions: VisualLayoutPositions | undefined;
|
|
55
115
|
readonly onSaveLayout: (payload: VisualLayoutSavePayload) => void;
|
|
116
|
+
/**
|
|
117
|
+
* A kind dropped from the palette (#295): the kind's label and the model
|
|
118
|
+
* position under the pointer. Optional because only a shell with a palette
|
|
119
|
+
* has anything to drop; a host without one never sees a drop at all - the
|
|
120
|
+
* `dragover` acceptance is gated on the callback too, so a stray drag is
|
|
121
|
+
* left to the browser's default refusal.
|
|
122
|
+
*/
|
|
123
|
+
readonly onKindDrop?: (kindLabel: string, position: {
|
|
124
|
+
readonly x: number;
|
|
125
|
+
readonly y: number;
|
|
126
|
+
}) => void;
|
|
56
127
|
/**
|
|
57
128
|
* A way to take a picture of what is drawn, handed up once the instance
|
|
58
129
|
* exists and withdrawn when it goes. The shell holds it so a menu item can
|
|
@@ -70,4 +141,4 @@ interface GraphCanvasProps {
|
|
|
70
141
|
* - Wires node/edge tap handlers to call onSelect(id, type)
|
|
71
142
|
* - Reflects selectedId prop as a visual highlight class on the matching element
|
|
72
143
|
*/
|
|
73
|
-
export declare function GraphCanvas({ graph, selectedId, onSelect, onContextMenu, matchedIds, quickFilterText, nesting, faultedIds, activeViewId, savedPositions, onSaveLayout, onCanvasReady, showLifecycle, showEvidence, showOwnership, }: GraphCanvasProps): React.ReactElement;
|
|
144
|
+
export declare function GraphCanvas({ graph, selectedId, onSelect, onContextMenu, matchedIds, quickFilterText, nesting, faultedIds, decorations, activeViewId, direction, savedPositions, onSaveLayout, onKindDrop, onCanvasReady, showLifecycle, showEvidence, showOwnership, showNudges, openQuestionCounts, }: GraphCanvasProps): React.ReactElement;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { VisualKindOption } from '../adapters/visual/protocol-contract.js';
|
|
3
|
+
/**
|
|
4
|
+
* The kind palette (#295): the profile's concept kinds, listed to be picked up.
|
|
5
|
+
*
|
|
6
|
+
* The kinds are the same vocabulary the Add-subject dialog's Kind select
|
|
7
|
+
* compiles from - `vocabulary.conceptKinds`, sent with every model frame - so
|
|
8
|
+
* nothing here decides what a workspace may contain. A row is a thing to drag
|
|
9
|
+
* onto the canvas, and a thing to click for the same result without a pointer
|
|
10
|
+
* gesture: either way the details dialog opens with the kind already chosen,
|
|
11
|
+
* and the palette itself holds nothing afterwards (ADR 0116).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The drag payload's type. Custom rather than `text/plain`, so the canvas
|
|
15
|
+
* accepts exactly what the palette offers and a stray text drop onto the
|
|
16
|
+
* diagram stays inert. The payload is the kind's LABEL, not its full identity:
|
|
17
|
+
* a document names a kind the short way, and `apply` refuses the identity as
|
|
18
|
+
* an unknown kind (`YM401`) - the same rule the dialog's own select follows.
|
|
19
|
+
*/
|
|
20
|
+
export declare const KIND_MIME = "application/x-yarramate-kind";
|
|
21
|
+
export interface PaletteGroup {
|
|
22
|
+
readonly layer: string;
|
|
23
|
+
readonly kinds: readonly VisualKindOption[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Rows grouped by layer, in the profile's own layer order - the same bands the
|
|
27
|
+
* model tree groups subjects by, so the palette and the rail read as one
|
|
28
|
+
* organisation. Within a group the wire's order is kept: the vocabulary
|
|
29
|
+
* arrives sorted and re-sorting it here would be a second opinion.
|
|
30
|
+
*/
|
|
31
|
+
export declare const paletteGroups: (kinds: readonly VisualKindOption[]) => readonly PaletteGroup[];
|
|
32
|
+
export declare const KindPalette: ({ kinds, onPick, }: {
|
|
33
|
+
readonly kinds: readonly VisualKindOption[];
|
|
34
|
+
/** A kind chosen without the drag - a click, a keyboard - which opens the
|
|
35
|
+
* same dialog a drop does. */
|
|
36
|
+
readonly onPick: (kindLabel: string) => void;
|
|
37
|
+
}) => React.ReactElement;
|
|
@@ -34,5 +34,47 @@ export interface LocalHostOptions {
|
|
|
34
34
|
readonly description?: string;
|
|
35
35
|
/** Told after every landed commit, so a host can persist what it was given. */
|
|
36
36
|
readonly onCommit?: (documents: readonly string[]) => void;
|
|
37
|
+
/**
|
|
38
|
+
* The question catalogue the questions section evaluates, or the shipped
|
|
39
|
+
* `core-enrichment` one when absent (#328).
|
|
40
|
+
*
|
|
41
|
+
* The engine is yarramate's and so is the UI; the QUESTIONS belong to
|
|
42
|
+
* whoever adopted it. `core-enrichment` is a general modelling interview,
|
|
43
|
+
* right for this repository's own CLI and for a host with no domain of its
|
|
44
|
+
* own, and wrong for a product whose interview is about its own subject
|
|
45
|
+
* matter. Until this existed a host could have the questions UI only by
|
|
46
|
+
* also running yarramate's catalogue, so a product with its own interview
|
|
47
|
+
* had to omit the section and show its questions on a separate surface,
|
|
48
|
+
* away from the model they are about.
|
|
49
|
+
*
|
|
50
|
+
* Bytes rather than a parsed catalogue, matching what the seam beneath
|
|
51
|
+
* already takes: a catalogue that does not load leaves the overlay absent
|
|
52
|
+
* rather than failing the mount, because the overlay is a garnish on the
|
|
53
|
+
* model and a model frame must not be blocked by it.
|
|
54
|
+
*/
|
|
55
|
+
readonly catalogue?: {
|
|
56
|
+
readonly path: string;
|
|
57
|
+
readonly source: string;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Questions this host has already dealt with and does not want asked again
|
|
61
|
+
* (#328).
|
|
62
|
+
*
|
|
63
|
+
* A host-supplied catalogue alone does not close this: the editor evaluates
|
|
64
|
+
* the catalogue itself and cannot know that a reviewer set a question aside,
|
|
65
|
+
* with a reason, recorded somewhere the editor cannot see. Without this the
|
|
66
|
+
* pane would go on asking a question its own product had answered.
|
|
67
|
+
*
|
|
68
|
+
* `subject` absent dismisses the question wherever it appears - the
|
|
69
|
+
* workspace-scoped entry and every subject's - which is "stop asking this".
|
|
70
|
+
* `subject` present dismisses it for that subject alone, which is "not for
|
|
71
|
+
* this one". Dismissal hides a question from the pane and changes nothing
|
|
72
|
+
* about the model or about what `ask --open` reports; the interview is not
|
|
73
|
+
* the editor's to settle.
|
|
74
|
+
*/
|
|
75
|
+
readonly dismissed?: readonly {
|
|
76
|
+
readonly questionId: string;
|
|
77
|
+
readonly subject?: string;
|
|
78
|
+
}[];
|
|
37
79
|
}
|
|
38
80
|
export declare const createLocalHost: (options: LocalHostOptions) => EditorHost;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type LocalHostOptions } from './local-host.js';
|
|
2
|
+
import type { DecorationMap } from './graph-canvas.js';
|
|
2
3
|
import type { EditorHost } from './editor-host.js';
|
|
3
4
|
import { type RightSectionId } from './workspace-state.js';
|
|
4
5
|
import './styles.css';
|
|
@@ -19,6 +20,8 @@ import './styles.css';
|
|
|
19
20
|
* workspace, // a resolved manifest
|
|
20
21
|
* sections: ['properties', 'changes'],
|
|
21
22
|
* })
|
|
23
|
+
* editor.select('app.checkout') // as a canvas tap would (#297)
|
|
24
|
+
* editor.openDraft({ kind: 'goal' }) // as a palette pick would
|
|
22
25
|
* // later
|
|
23
26
|
* editor.unmount()
|
|
24
27
|
* ```
|
|
@@ -26,6 +29,9 @@ import './styles.css';
|
|
|
26
29
|
* `sections` is what the host wants shown. Chat is the one a product usually
|
|
27
30
|
* leaves out: with no agent behind it there is nobody to talk to and nothing to
|
|
28
31
|
* hand control back to, so the section and the session button go together.
|
|
32
|
+
*
|
|
33
|
+
* `readOnly: true` mounts a viewer (#298): the same canvas, tree, questions
|
|
34
|
+
* and properties, with every staging and committing affordance absent.
|
|
29
35
|
*/
|
|
30
36
|
export interface MountOptions extends LocalHostOptions {
|
|
31
37
|
/**
|
|
@@ -35,10 +41,72 @@ export interface MountOptions extends LocalHostOptions {
|
|
|
35
41
|
* name the two it wants.
|
|
36
42
|
*/
|
|
37
43
|
readonly sections?: readonly RightSectionId[];
|
|
44
|
+
/**
|
|
45
|
+
* A viewer, not an author (#298, ADR 0117). Every affordance that stages or
|
|
46
|
+
* commits a change is absent - not disabled - so a frozen snapshot renders
|
|
47
|
+
* with the authoring surface's visual language and none of its pen. A UI
|
|
48
|
+
* posture only: a host whose store also refuses writes has two independent
|
|
49
|
+
* defenses, and this option is not the one that guards the data.
|
|
50
|
+
*/
|
|
51
|
+
readonly readOnly?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The host's per-subject marks at mount time (#314, ADR 0119): subject id -
|
|
54
|
+
* concept or relationship - to `'added' | 'removed' | 'changed'`, rendered
|
|
55
|
+
* as class-based visual treatments the way faults are. This is the seam
|
|
56
|
+
* that lets a host with its own comparison model use the one viewer for
|
|
57
|
+
* decorated comparison: the SEMANTICS stay host-side - the viewer never
|
|
58
|
+
* diffs, it renders the marks it is handed. An id the model does not name
|
|
59
|
+
* is silently inert. This option is the initial map; a live comparison
|
|
60
|
+
* replaces it wholesale through the handle's `setDecorations`.
|
|
61
|
+
*/
|
|
62
|
+
readonly decorations?: DecorationMap;
|
|
38
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* The handle a mount returns (#297, ADR 0118): the disposal it always had,
|
|
66
|
+
* and three ways for the host to point at the canvas. Each method is the
|
|
67
|
+
* programmatic twin of a gesture the surface already has - never a second
|
|
68
|
+
* write path: nothing here commits, and anything the opened affordances stage
|
|
69
|
+
* still goes through the changeset like every reviewer gesture.
|
|
70
|
+
*
|
|
71
|
+
* Every method answers with whether it acted. False means nothing moved: the
|
|
72
|
+
* id named nothing in the current model, the model has not arrived yet - the
|
|
73
|
+
* editor renders before its host's first frame lands - or the mount is a
|
|
74
|
+
* viewer (`readOnly`, #298) and the gesture would have reached for the pen.
|
|
75
|
+
*/
|
|
39
76
|
export interface MountedEditor {
|
|
40
77
|
/** Releases the host and takes the editor out of the element. */
|
|
41
78
|
readonly unmount: () => void;
|
|
79
|
+
/**
|
|
80
|
+
* Selects the subject - concept or relationship - on the canvas and in the
|
|
81
|
+
* inspector, exactly as a tap on it would, which also scopes the Open
|
|
82
|
+
* questions section to it.
|
|
83
|
+
*/
|
|
84
|
+
readonly select: (subjectId: string) => boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Opens the Add-subject dialog, with the kind preselected when one is
|
|
87
|
+
* given - the same seed a palette pick rides (#295). Without a kind, the
|
|
88
|
+
* plain no-default form.
|
|
89
|
+
*/
|
|
90
|
+
readonly openDraft: (options?: {
|
|
91
|
+
readonly kind?: string;
|
|
92
|
+
}) => boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Arms the connection tool from the named subject, exactly as the
|
|
95
|
+
* inspector's Connect does: the next selection becomes the target and the
|
|
96
|
+
* kinds on offer are derived from the two endpoints.
|
|
97
|
+
*/
|
|
98
|
+
readonly startConnection: (fromSubjectId: string) => boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Replaces the per-subject marks wholesale (#314, ADR 0119) - never a
|
|
101
|
+
* merge: the map handed here is the map drawn, and `{}` clears every mark.
|
|
102
|
+
* The one handle method that is not a gesture's twin, because no gesture
|
|
103
|
+
* decorates: it is the live half of the `decorations` mount option, for a
|
|
104
|
+
* comparison that moves under an open viewer. Decorating is reading, so it
|
|
105
|
+
* works under `readOnly`, and unknown ids are silently inert - false is
|
|
106
|
+
* only the shared not-there window: before the shell's first render, or
|
|
107
|
+
* after unmount.
|
|
108
|
+
*/
|
|
109
|
+
readonly setDecorations: (decorations: DecorationMap) => boolean;
|
|
42
110
|
}
|
|
43
111
|
export declare const mountEditor: (element: Element, options: MountOptions) => MountedEditor;
|
|
44
112
|
/**
|
|
@@ -47,10 +115,13 @@ export declare const mountEditor: (element: Element, options: MountOptions) => M
|
|
|
47
115
|
* Exported for the case `mountEditor` does not cover: a product that already
|
|
48
116
|
* speaks the visual protocol - to its own server, over its own transport - and
|
|
49
117
|
* wants the editor in front of it. The protocol is the contract (ADR 0081), so
|
|
50
|
-
* anything that answers it is a host.
|
|
118
|
+
* anything that answers it is a host. `readOnly` composes: a custom host gets
|
|
119
|
+
* the same viewer posture `mountEditor` offers, and stays free to refuse
|
|
120
|
+
* writes on its own side of the seam as well.
|
|
51
121
|
*/
|
|
52
|
-
export declare const mountEditorWith: (element: Element, host: EditorHost, sections?: readonly RightSectionId[]) => MountedEditor;
|
|
122
|
+
export declare const mountEditorWith: (element: Element, host: EditorHost, sections?: readonly RightSectionId[], readOnly?: boolean, decorations?: DecorationMap) => MountedEditor;
|
|
53
123
|
export type { EditorHost, EditorHostEvents } from './editor-host.js';
|
|
124
|
+
export type { DecorationMap, DecorationMark } from './graph-canvas.js';
|
|
54
125
|
export type { LocalHostOptions } from './local-host.js';
|
|
55
126
|
export { createLocalHost } from './local-host.js';
|
|
56
127
|
export { RIGHT_SECTIONS, type RightSectionId } from './workspace-state.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { VisualInterrogationOverlay } from '../adapters/visual/wire.js';
|
|
2
|
+
/**
|
|
3
|
+
* The interview, where the drawing happens (#292).
|
|
4
|
+
*
|
|
5
|
+
* One home for both scopes: a selected element shows the questions that name
|
|
6
|
+
* it — the `design --subject` reading of the model — and no selection shows
|
|
7
|
+
* the workspace-scoped questions, which name no subject and would otherwise
|
|
8
|
+
* be the model's biggest holes rendered nowhere. Read-only by design: the
|
|
9
|
+
* answer path stays `apply` (through the editor's own forms or an agent),
|
|
10
|
+
* never a text box here that would bypass the compile gate.
|
|
11
|
+
*/
|
|
12
|
+
export declare function OpenQuestions({ overlay, selectedId, }: {
|
|
13
|
+
readonly overlay: VisualInterrogationOverlay;
|
|
14
|
+
readonly selectedId: string | null;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
@@ -39,7 +39,7 @@ export declare const queryToFields: (query: ProjectionQuery | null) => QueryFiel
|
|
|
39
39
|
* single-choice field is never sent, since `minItems: 1` on the schema's
|
|
40
40
|
* array properties makes `[]` itself invalid. */
|
|
41
41
|
export declare const composeQuery: (fields: QueryFields) => ProjectionQuery;
|
|
42
|
-
export type PresentationFlag = 'showLifecycle' | 'showEvidence' | 'showOwnership';
|
|
42
|
+
export type PresentationFlag = 'showLifecycle' | 'showEvidence' | 'showOwnership' | 'showNudges';
|
|
43
43
|
/** The checkbox's onChange handler, extracted so it is directly testable in
|
|
44
44
|
* isolation from rendering: it calls `onTogglePresentation` and nothing
|
|
45
45
|
* else — never `composeQuery`/`scheduleApply`. These three flags are
|
|
@@ -61,9 +61,10 @@ export declare function QueryFacets({ fields, onChange, }: {
|
|
|
61
61
|
* view document's `presentation` and never composed into a `ProjectionQuery`,
|
|
62
62
|
* which is why they take their own handler rather than sharing `onChange`.
|
|
63
63
|
*/
|
|
64
|
-
export declare function PresentationToggles({ showLifecycle, showEvidence, showOwnership, onTogglePresentation, }: {
|
|
64
|
+
export declare function PresentationToggles({ showLifecycle, showEvidence, showOwnership, showNudges, onTogglePresentation, }: {
|
|
65
65
|
readonly showLifecycle: boolean;
|
|
66
66
|
readonly showEvidence: boolean;
|
|
67
67
|
readonly showOwnership: boolean;
|
|
68
|
+
readonly showNudges: boolean;
|
|
68
69
|
readonly onTogglePresentation: (flag: PresentationFlag, value: boolean) => void;
|
|
69
70
|
}): import("react").JSX.Element;
|
|
@@ -131,6 +131,7 @@ export interface QueryPanelProps {
|
|
|
131
131
|
readonly showLifecycle: boolean;
|
|
132
132
|
readonly showEvidence: boolean;
|
|
133
133
|
readonly showOwnership: boolean;
|
|
134
|
+
readonly showNudges: boolean;
|
|
134
135
|
readonly onTogglePresentation: (flag: PresentationFlag, value: boolean) => void;
|
|
135
136
|
readonly onToggleOpen: () => void;
|
|
136
137
|
readonly onSelectTab: (tab: BottomPanelTabId) => void;
|
|
@@ -138,5 +139,11 @@ export interface QueryPanelProps {
|
|
|
138
139
|
* write: what is on screen is what the reviewer is composing. */
|
|
139
140
|
readonly onApply: (query: ProjectionQuery) => void;
|
|
140
141
|
readonly onStage: (operation: VisualViewOperation) => void;
|
|
142
|
+
/**
|
|
143
|
+
* A viewer, not an author (#298): the fields still narrow the canvas - a
|
|
144
|
+
* live filter writes nothing - but the affordance that stages the edit as a
|
|
145
|
+
* view change is absent. The document still shows, because it is a fact.
|
|
146
|
+
*/
|
|
147
|
+
readonly readOnly?: boolean;
|
|
141
148
|
}
|
|
142
|
-
export declare function QueryPanel({ nodes, activeFilter, view, open, tab, showLifecycle, showEvidence, showOwnership, onTogglePresentation, onToggleOpen, onSelectTab, onApply, onStage, }: QueryPanelProps): import("react").JSX.Element;
|
|
149
|
+
export declare function QueryPanel({ nodes, activeFilter, view, open, tab, showLifecycle, showEvidence, showOwnership, showNudges, onTogglePresentation, onToggleOpen, onSelectTab, onApply, onStage, readOnly, }: QueryPanelProps): import("react").JSX.Element;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LayoutDirection } from "../layout-direction.js";
|
|
1
2
|
import type { ProjectionQuery } from "../projection.js";
|
|
2
3
|
import type { VisualViewOperation, VisualViewSummary } from "../adapters/visual/protocol-contract.js";
|
|
3
4
|
export interface SaveViewDialogProps {
|
|
@@ -52,12 +53,12 @@ export interface BuildPayloadParams {
|
|
|
52
53
|
readonly showOwnership: boolean;
|
|
53
54
|
/**
|
|
54
55
|
* Whatever the view being overwritten already declared, carried through
|
|
55
|
-
* rather than restated. The canvas
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* drop a value the reviewer never
|
|
56
|
+
* rather than restated. The canvas draws the direction now (#274, ADR 0121)
|
|
57
|
+
* and the LikeC4 export has always read it, but there is still no control
|
|
58
|
+
* that sets one: the view declares it, so a save that simply omitted it
|
|
59
|
+
* would drop a value the reviewer never asked to discard.
|
|
59
60
|
*/
|
|
60
|
-
readonly carriedDirection:
|
|
61
|
+
readonly carriedDirection: LayoutDirection | undefined;
|
|
61
62
|
}
|
|
62
63
|
/**
|
|
63
64
|
* Pure translation from the form's local state to the staged operation — no
|
|
@@ -82,5 +83,10 @@ export declare const buildPayload: ({ id, taken, path, folder, title, descriptio
|
|
|
82
83
|
* an overwrite was immediate and unundoable; a staged overwrite is a row the
|
|
83
84
|
* reviewer can read, discard and undo before it lands, which is a better
|
|
84
85
|
* answer than a dialog.
|
|
86
|
+
*
|
|
87
|
+
* Opened with a folder preset — "New folder…", "New view in this folder…" —
|
|
88
|
+
* the overwrite is disabled (#299): it carries the active view's own folder
|
|
89
|
+
* by design, so it is the one button that would silently drop the folder the
|
|
90
|
+
* reviewer just named.
|
|
85
91
|
*/
|
|
86
92
|
export declare function SaveViewDialog({ views, activeViewId, query, layout, showLifecycle, showEvidence, showOwnership, open, folder, onClose, onStage, }: SaveViewDialogProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shipped question catalogue, bundled into the browser build so the
|
|
3
|
+
* embedded editor computes the same interrogation overlay the session
|
|
4
|
+
* server does (#292). The path is a diagnostic label, not a file: nothing
|
|
5
|
+
* in the browser resolves it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SHIPPED_CATALOGUE: {
|
|
8
|
+
readonly path: 'core-enrichment.yaml';
|
|
9
|
+
readonly source: string;
|
|
10
|
+
};
|
|
@@ -301,17 +301,28 @@ export declare const visualBrowserInputFor: (intent: VisualAppIntent, state: Vis
|
|
|
301
301
|
* reporting itself as the reviewer's own.
|
|
302
302
|
*/
|
|
303
303
|
/**
|
|
304
|
-
*
|
|
304
|
+
* How the active view can be told what it holds, as the menus must read it.
|
|
305
305
|
*
|
|
306
|
-
* `null` where there is no
|
|
307
|
-
*
|
|
306
|
+
* `null` only where there is no view at all. A view that ENUMERATES its
|
|
307
|
+
* subjects is told by editing that list; a view that describes them with
|
|
308
|
+
* FACETS is told by editing `exclude`, the exception a rule cannot state
|
|
309
|
+
* (#267, ADR 0122). Both are membership; they differ in which field moves and
|
|
310
|
+
* in which direction, which is why the shape is a union rather than a list
|
|
311
|
+
* with a flag.
|
|
308
312
|
*
|
|
309
313
|
* Read through the PENDING row when one is staged, not off the saved document.
|
|
310
314
|
* A reviewer who has just added a subject and right-clicks it again must be
|
|
311
315
|
* offered "Remove from view"; a menu built from the saved list would offer
|
|
312
316
|
* "Add to this view" a second time and stage nothing.
|
|
313
317
|
*/
|
|
314
|
-
export
|
|
318
|
+
export type ActiveViewMembership = {
|
|
319
|
+
readonly kind: "enumerated";
|
|
320
|
+
readonly subjects: readonly string[];
|
|
321
|
+
} | {
|
|
322
|
+
readonly kind: "faceted";
|
|
323
|
+
readonly excluded: readonly string[];
|
|
324
|
+
};
|
|
325
|
+
export declare const activeViewMembership: (state: VisualAppState) => ActiveViewMembership | null;
|
|
315
326
|
export declare const filterToReresolve: (frame: VisualServerFrame, state: VisualAppState) => {
|
|
316
327
|
readonly query: ProjectionQuery;
|
|
317
328
|
readonly source: FilterSource;
|