react-semaphor 0.1.545 → 0.1.547
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/analytics-protocol/index.js +408 -442
- package/dist/assistant-context/index.js +1 -1
- package/dist/assistant-protocol/index.js +100 -76
- package/dist/brand-studio/index.js +4 -4
- package/dist/briefings/index.js +6 -6
- package/dist/chunks/{add-to-dashboard-BuAqfA2Y.js → add-to-dashboard-BQRAAnc3.js} +55 -33
- package/dist/chunks/{analytics-base-schemas-BFAoRlkU.js → analytics-base-schemas-BKs3flFS.js} +2 -2
- package/dist/chunks/applied-constraints-DU-wndZ7.js +47 -0
- package/dist/chunks/{assistant-chat-D7sWTypJ.js → assistant-chat-CK84cPAB.js} +2826 -2595
- package/dist/chunks/{bookmark-state-CXw7lZ50.js → bookmark-state-Cu-a5ie_.js} +8 -15
- package/dist/chunks/comparison-window-caption-C2xF-eWw.js +1433 -0
- package/dist/chunks/{context-ClREvqCZ.js → context-BerEBuFR.js} +11 -6
- package/dist/chunks/custom-visual-inputs-ChL54gGm.js +295 -0
- package/dist/chunks/{dashboard-B1tMju0u.js → dashboard-DCk26-6i.js} +1 -1
- package/dist/chunks/{dashboard-briefing-launcher-CePgIu0Z.js → dashboard-briefing-launcher-CQ1eYsGy.js} +1291 -1277
- package/dist/chunks/dashboard-controls-BMeZjF7r.js +2307 -0
- package/dist/chunks/{dashboard-json-CoYRPqxx.js → dashboard-json-BZqCoanC.js} +5 -5
- package/dist/chunks/{document-dashboard-inputs-BesAHZvB.js → document-dashboard-inputs-tYd7ao0o.js} +877 -979
- package/dist/chunks/{edit-dashboard-visual-JPtNfJRb.js → edit-dashboard-visual-Bv3MHM_G.js} +2157 -2243
- package/dist/chunks/filter-reach-copy-CGWsL_ez.js +3480 -0
- package/dist/chunks/{filter-value-text-ff7osJr7.js → filter-value-text-Ddf55Ku1.js} +9 -9
- package/dist/chunks/global-date-filter-utils-BhAu8zIM.js +12137 -0
- package/dist/chunks/index-CtoK1Lgu.js +586 -0
- package/dist/chunks/{index-DRWiuqyd.js → index-DmrLP5Ro.js} +105 -104
- package/dist/chunks/list-filter-DsaTbM3J.js +15 -0
- package/dist/chunks/matrix-analytical-definition-B9vW-osb.js +717 -0
- package/dist/chunks/{matrix-card-DjwWcCo8.js → matrix-card-LiMEipvq.js} +3 -3
- package/dist/chunks/{matrix-formatter-DnCyRXJE.js → matrix-formatter-DWEeC0_c.js} +44 -44
- package/dist/chunks/{matrix-member-presentation-CQGdVks6.js → matrix-member-presentation-DqzG-UhQ.js} +1 -1
- package/dist/chunks/{matrix-operation-contract-8OIO4gob.js → matrix-operation-contract-D6vYkZK4.js} +72 -72
- package/dist/chunks/{metric-comparison-DEwi9uc2.js → metric-comparison-zpGw4lD6.js} +2 -2
- package/dist/chunks/normalize-dashboard-for-dirty-check-XKgH3GFX.js +119 -0
- package/dist/chunks/{pivot-header-presentation-DHcx1XGQ.js → pivot-header-presentation-CQnIDtUv.js} +1 -1
- package/dist/chunks/{pivot-result-identity-DJhXXcns.js → pivot-result-identity-C-Q1j1Wb.js} +1 -1
- package/dist/chunks/{pivot-result-lifecycle-DM4CyGKs.js → pivot-result-lifecycle-pwq3b7LC.js} +571 -380
- package/dist/chunks/{raw-temporal-contract-C51YG48G.js → raw-temporal-contract-WuXA8jBP.js} +1 -1
- package/dist/chunks/{raw-temporal-presentation-C3mUgnEx.js → raw-temporal-presentation-DypB7sMX.js} +8 -8
- package/dist/chunks/{report-preferences-dialog-DUtuUL_5.js → report-preferences-dialog-DoVyriYC.js} +154 -155
- package/dist/chunks/{report-runtime-context-Dq8XyODK.js → report-runtime-context-hWiTCzFV.js} +2 -2
- package/dist/chunks/resolve-dashboard-input-context-D0JDUa4h.js +5576 -0
- package/dist/chunks/{saved-dashboard-context-LrF_kW0l.js → saved-dashboard-context-BfAH5j4L.js} +34 -34
- package/dist/chunks/{selection-reducer-Dj_8xD69.js → selection-reducer-CJzkTZio.js} +15 -15
- package/dist/chunks/{semaphor-ready-indicator-BxF96Yhv.js → semaphor-ready-indicator-CRm17oIP.js} +51771 -52574
- package/dist/chunks/{shelf-drop-preview-context-CNaM_Gmh.js → shelf-drop-preview-context-vy6P9THz.js} +7 -7
- package/dist/chunks/{source-entity-resolution-BYn9giz3.js → source-entity-resolution-BIGRvtbG.js} +13 -13
- package/dist/chunks/{switch-uDtPgQlQ.js → switch-CEBOR4n7.js} +3 -3
- package/dist/chunks/{table-export-sheet-YzMioA7Y.js → table-export-sheet-4X9mAG3V.js} +1 -1
- package/dist/chunks/table-settings-WysCBj62.js +614 -0
- package/dist/chunks/{temporal-bucket-D7NBrrtL.js → temporal-bucket-CQOSbv9-.js} +26 -26
- package/dist/chunks/{token-types-DBbZVQsm.js → token-types-BMqRmT-C.js} +1 -1
- package/dist/chunks/{use-create-flow-overlay-state-CjB7ig1o.js → use-create-flow-overlay-state-Csx_Xjsh.js} +101 -101
- package/dist/chunks/{validators-DMHTpf7a.js → validators-C-aOQlTB.js} +713 -658
- package/dist/chunks/{relative-date-label-Bk2j94pA.js → zoned-wall-clock-MulfA26h.js} +64 -21
- package/dist/dashboard/index.js +2 -2
- package/dist/dashboard-authoring/index.js +1895 -1163
- package/dist/data-app-sdk/index.js +6 -6
- package/dist/data-app-sdk-adapters/index.js +3 -3
- package/dist/data-app-sdk-validation/index.js +14 -14
- package/dist/format-utils/index.js +133 -133
- package/dist/index.js +192 -186
- package/dist/layouts/index.js +5 -242
- package/dist/report-runtime-context/index.js +2 -2
- package/dist/shared/index.js +4 -5
- package/dist/style.css +1 -1
- package/dist/surfboard/index.js +2 -2
- package/dist/types/components/index.d.ts +2 -0
- package/dist/types/components/surfboard/arrange-layout-button.d.ts +8 -0
- package/dist/types/components/surfboard/filter/types.d.ts +7 -0
- package/dist/types/components/surfboard/screen-size-preview-button.d.ts +10 -0
- package/dist/types/components/visual/matrix-table/matrix-card-view.d.ts +3 -0
- package/dist/types/index.js +6 -6
- package/dist/types/lib/charts/table-chart-types.d.ts +4 -0
- package/dist/types/lib/charts/types.d.ts +2 -2
- package/dist/types/lib/dashboard-inputs/dashboard-filter-mapping-authoring.d.ts +346 -21
- package/dist/types/lib/dashboard-inputs/dashboard-filter-value-identity.d.ts +65 -0
- package/dist/types/lib/dashboard-inputs/dashboard-input-values.d.ts +6 -0
- package/dist/types/lib/dashboard-inputs/filter-settings.d.ts +2 -0
- package/dist/types/lib/dashboard-inputs/prepare-loaded-dashboard.d.ts +15 -0
- package/dist/types/lib/dashboard-inputs/resolve-selection-input.d.ts +3 -3
- package/dist/types/lib/hooks/use-dashboard-card.d.ts +2 -0
- package/dist/types/lib/matrix-table/matrix-delivery-policy.d.ts +1 -1
- package/dist/types/lib/matrix-table/matrix-editor.d.ts +52 -0
- package/dist/types/lib/matrix-table/matrix-runtime-types.d.ts +9 -1
- package/dist/types/lib/matrix-table/matrix-runtime.d.ts +5 -1
- package/dist/types/lib/query-context/dashboard-filter-mapping-resolution.d.ts +149 -10
- package/dist/types/lib/stores/dashboard-store.d.ts +137 -6
- package/dist/types/lib/types/common-types.d.ts +8 -0
- package/dist/types/lib/types/explorer-types.d.ts +10 -0
- package/dist/types/lib/types/semantic-types.d.ts +84 -0
- package/dist/types/lib/utils/build-saved-editor-card.d.ts +20 -0
- package/dist/types/lib/utils/card-type-change.d.ts +16 -0
- package/dist/types/lib/utils/field-availability-context.d.ts +25 -0
- package/dist/types/lib/utils/field-placement.d.ts +96 -0
- package/dist/types/lib/utils/field-state-calculator.d.ts +161 -0
- package/dist/types/lib/utils/qualified-entity-name.d.ts +2 -0
- package/dist/types/shared/analytics-protocol/applied-constraints.d.ts +57 -1
- package/dist/types/shared/analytics-protocol/field-provenance.d.ts +89 -0
- package/dist/types/shared/analytics-protocol/index.d.ts +2 -0
- package/dist/types/shared/analytics-protocol/query-policies.d.ts +52 -0
- package/dist/types/shared/analytics-protocol/time-window-schema.d.ts +1 -1
- package/dist/types/shared/analytics-protocol/time-window.d.ts +40 -1
- package/dist/types/shared/assistant-context/saved-dashboard-context.d.ts +4 -1
- package/dist/types/shared/assistant-protocol/answer-text.d.ts +20 -0
- package/dist/types/shared/assistant-protocol/context.d.ts +29 -29
- package/dist/types/shared/assistant-protocol/index.d.ts +1 -0
- package/dist/types/shared/assistant-protocol/limits.d.ts +6 -1
- package/dist/types/shared/assistant-protocol/parts.d.ts +43 -3
- package/dist/types/shared/assistant-protocol/request.d.ts +14 -2
- package/dist/types/shared/dashboard-authoring/calculated-field-identity.d.ts +3 -0
- package/dist/types/shared/dashboard-authoring/changes/card-query-part.d.ts +487 -0
- package/dist/types/shared/dashboard-authoring/changes/card-types.d.ts +34 -0
- package/dist/types/shared/dashboard-authoring/changes/dashboard-change.d.ts +7886 -0
- package/dist/types/shared/dashboard-authoring/changes/diagnostics.d.ts +45 -0
- package/dist/types/shared/dashboard-authoring/changes/read-card-query.d.ts +54 -0
- package/dist/types/shared/dashboard-authoring/changes/resolve-dashboard-changes.d.ts +96 -0
- package/dist/types/shared/dashboard-authoring/click-to-filter-settings.d.ts +3 -3
- package/dist/types/shared/dashboard-authoring/column-catalog.d.ts +32 -0
- package/dist/types/shared/dashboard-authoring/contracts.d.ts +0 -55
- package/dist/types/shared/dashboard-authoring/control-execution-contract.d.ts +24 -14
- package/dist/types/shared/dashboard-authoring/dashboard-card-source-index.d.ts +9 -1
- package/dist/types/shared/dashboard-authoring/dashboard-filter-automatic-target.d.ts +4 -4
- package/dist/types/shared/dashboard-authoring/dashboard-filter-mapping-contract.d.ts +3 -1
- package/dist/types/shared/dashboard-authoring/dashboard-filter-mapping-types.d.ts +27 -1
- package/dist/types/shared/dashboard-authoring/dashboard-filter-value-compatibility.d.ts +12 -3
- package/dist/types/shared/dashboard-authoring/dashboard-input-scope.d.ts +26 -0
- package/dist/types/shared/dashboard-authoring/filter-applicability.d.ts +75 -0
- package/dist/types/shared/dashboard-authoring/filter-reach-copy.d.ts +18 -0
- package/dist/types/shared/dashboard-authoring/filter-reach-preview.d.ts +97 -0
- package/dist/types/shared/dashboard-authoring/index.d.ts +22 -2
- package/dist/types/shared/dashboard-authoring/operations/apply-dashboard-operations.d.ts +10 -37
- package/dist/types/shared/dashboard-authoring/operations/operation-types.d.ts +189 -0
- package/dist/types/shared/dashboard-authoring/outline/outline-dashboard.d.ts +101 -0
- package/dist/types/shared/dashboard-authoring/outline/outline-filters.d.ts +100 -0
- package/dist/types/shared/dashboard-authoring/semantic-auto-join-card.d.ts +22 -0
- package/dist/types/shared/dashboard-authoring/validators.d.ts +1 -2
- package/dist/types/shared/layouts/engine/grid.d.ts +25 -0
- package/dist/types/shared/layouts/engine/index.d.ts +4 -0
- package/dist/types/shared/layouts/engine/sheet-layout.d.ts +7 -0
- package/dist/types/shared/layouts/engine/types.d.ts +125 -0
- package/dist/types/shared/layouts/index.d.ts +1 -2
- package/package.json +2 -2
- package/dist/chunks/apply-dashboard-operations-CZEMsx8E.js +0 -2080
- package/dist/chunks/calendar-day-equality-dvoQp1xW.js +0 -410
- package/dist/chunks/comparison-window-caption-D4E6IHPD.js +0 -1624
- package/dist/chunks/custom-visual-inputs-DLCD9Y5V.js +0 -329
- package/dist/chunks/dashboard-controls-Cq05n3e0.js +0 -2315
- package/dist/chunks/dashboard-filter-value-compatibility-CwQ_iSNb.js +0 -108
- package/dist/chunks/matrix-analytical-definition-C7Gb0e12.js +0 -117
- package/dist/chunks/normalize-dashboard-for-dirty-check-Bk3VYv_q.js +0 -67
- package/dist/chunks/numeric-presentation-7X_IrD58.js +0 -5226
- package/dist/chunks/resolve-dashboard-input-context-DJ2tICwz.js +0 -9415
- package/dist/chunks/stable-serialize-CfqXeiBP.js +0 -6
- package/dist/chunks/table-settings-CLZocegs.js +0 -501
- package/dist/chunks/use-debounced-dirty-check-BwAbnX_5.js +0 -59
- package/dist/chunks/zoned-wall-clock-BkxV9jS2.js +0 -46
- package/dist/types/shared/dashboard-authoring/change-compiler.d.ts +0 -7
- package/dist/types/shared/dashboard-authoring/layout-compiler.d.ts +0 -2
- package/dist/types/shared/layouts/create-frame-layouts.d.ts +0 -27
- package/dist/types/shared/layouts/frame-layouts.d.ts +0 -23
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { SemaphorSkippedConstraintReason } from '../analytics-protocol/index.js';
|
|
2
|
+
import { TFilterValue } from '../../components/surfboard/filter/types.js';
|
|
3
|
+
import { TCard } from '../../lib/types/common-types.js';
|
|
4
|
+
import { CardConfig, DataSource } from '../../lib/types/explorer-types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Whether a dashboard filter's value applies to a card: the one rule (MCP
|
|
7
|
+
* dashboard editing ledger V-44). The query builder runs it on every filter
|
|
8
|
+
* value a card receives (semaphor-app build-query); the dashboard's filter
|
|
9
|
+
* mapping decision (`decideDashboardFilterCardTarget`) and every description
|
|
10
|
+
* of reach (the outline, reach warnings, the change resolver's effect check)
|
|
11
|
+
* read it too, so a filter reaches the same cards whether or not it has card
|
|
12
|
+
* mappings. Moved unchanged from semaphor-app
|
|
13
|
+
* `src/lib/analytics/query/filter-applicability.ts`, which re-exports it.
|
|
14
|
+
*/
|
|
15
|
+
/** The protocol's skip reasons: evidence reports them as they are (D3b-4). */
|
|
16
|
+
export type FilterSkipReason = SemaphorSkippedConstraintReason;
|
|
17
|
+
export type SkippedFilter = {
|
|
18
|
+
filterId?: string;
|
|
19
|
+
name?: string;
|
|
20
|
+
reason: FilterSkipReason;
|
|
21
|
+
details?: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function formatSkippedFilterWarnings(skipped: ReadonlyArray<{
|
|
24
|
+
filterId?: string;
|
|
25
|
+
name?: string;
|
|
26
|
+
reason: string;
|
|
27
|
+
}>): string[];
|
|
28
|
+
export type FilterApplicabilityResult = {
|
|
29
|
+
applicableFilters: TFilterValue[];
|
|
30
|
+
skippedFilters: SkippedFilter[];
|
|
31
|
+
};
|
|
32
|
+
export type FilterApplicabilityPhase = 'pre_join' | 'post_join';
|
|
33
|
+
export type FilterApplicabilityContext = {
|
|
34
|
+
cardDataSource?: DataSource | null;
|
|
35
|
+
targetQualifiedTableName?: string;
|
|
36
|
+
allowCalculated?: boolean;
|
|
37
|
+
additionalAllowedIdentifiers?: string[];
|
|
38
|
+
phase?: FilterApplicabilityPhase;
|
|
39
|
+
};
|
|
40
|
+
/** The same explicit join sources participate in early and final applicability. */
|
|
41
|
+
export declare function collectJoinPlanIdentifiers(joinPlan: CardConfig['joinPlan'] | null): string[];
|
|
42
|
+
/** Only for physical cards after structural completeness validation. Semantic
|
|
43
|
+
* cards need current catalog dependencies before deciding applicability. Keep
|
|
44
|
+
* unknown or partially overlapping predicates for the authoritative path. */
|
|
45
|
+
export declare function pruneUnrelatedCalculatedFilters(filters: TFilterValue[], context: FilterApplicabilityContext): FilterApplicabilityResult;
|
|
46
|
+
/**
|
|
47
|
+
* How the rule decides one filter value: applied with dataset proof, applied
|
|
48
|
+
* without it (no datasets to check against, a legacy unqualified name, a
|
|
49
|
+
* calculation with unknown dependencies), or skipped with a reason.
|
|
50
|
+
*/
|
|
51
|
+
export type FilterApplicabilityDecision = {
|
|
52
|
+
kind: 'apply';
|
|
53
|
+
proven: boolean;
|
|
54
|
+
} | {
|
|
55
|
+
kind: 'skip';
|
|
56
|
+
reason: FilterSkipReason;
|
|
57
|
+
details?: string;
|
|
58
|
+
};
|
|
59
|
+
export declare function applyFilterApplicability(activeFilters: TFilterValue[] | undefined, context: FilterApplicabilityContext): FilterApplicabilityResult;
|
|
60
|
+
/**
|
|
61
|
+
* The applicability context of a card as the query builder runs it: the
|
|
62
|
+
* card's data source, its join plan's entities, and the join phase.
|
|
63
|
+
*/
|
|
64
|
+
export declare function filterApplicabilityContextForCard(card: {
|
|
65
|
+
dataSource?: DataSource | null;
|
|
66
|
+
joinPlan?: CardConfig['joinPlan'] | null;
|
|
67
|
+
}): FilterApplicabilityContext;
|
|
68
|
+
/**
|
|
69
|
+
* Whether a filter value reaches a saved card, by the one rule: `reachable`
|
|
70
|
+
* when the card's data (the datasets it selects or joins) proves it takes the
|
|
71
|
+
* value's field, `unreachable` when the rule skips it, `unknown` when the rule
|
|
72
|
+
* keeps it without proof (nothing to check against, a legacy unqualified
|
|
73
|
+
* name, a calculation with unknown dependencies).
|
|
74
|
+
*/
|
|
75
|
+
export declare function filterValueReachForCard(filterValue: TFilterValue, card: Pick<TCard, 'dataSource' | 'config'>): 'reachable' | 'unreachable' | 'unknown';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SemaphorRelationshipRoute, SemaphorSkippedConstraintReason } from '../analytics-protocol/index.js';
|
|
2
|
+
/** "Project" to "Projects", "Category" to "Categories"; a label ending in "s" stays. */
|
|
3
|
+
export declare function pluralDatasetLabel(label: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* P-8 and P-11: "through Project" for a to-one route; "Projects with at least
|
|
6
|
+
* one matching Dashboard" for a to-many route, where Dashboard is the dataset
|
|
7
|
+
* its first to-many step reaches. A route of more than one step names the
|
|
8
|
+
* datasets it passes through, not the filter's own, which it always ends at
|
|
9
|
+
* ("through Crew" for a Company filter; ledger R-21).
|
|
10
|
+
*/
|
|
11
|
+
export declare function describeRelationshipRoute(route: SemaphorRelationshipRoute): string;
|
|
12
|
+
/** P-1: a persisted route the domain no longer has. */
|
|
13
|
+
export declare const RELATIONSHIP_ROUTE_CHANGED_MESSAGE = "The relationship this card used changed; choose it again";
|
|
14
|
+
/** P-2, P-3, P-6, P-7: why a value was not applied to a card. */
|
|
15
|
+
export declare function describeRelationshipSkip(reason: SemaphorSkippedConstraintReason, cardDataset?: {
|
|
16
|
+
name: string;
|
|
17
|
+
label?: string;
|
|
18
|
+
}): string;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { SemaphorRelationshipRoute, SemaphorSkippedConstraintReason } from '../analytics-protocol/index.js';
|
|
2
|
+
import { TFilter } from '../../components/surfboard/filter/types.js';
|
|
3
|
+
import { DashboardFilterOptionSource, DashboardFilterRelationshipTarget } from './dashboard-filter-mapping-types.js';
|
|
4
|
+
/**
|
|
5
|
+
* The Cards tab's relationship preview (relationship filter reach, Phase 3):
|
|
6
|
+
* `POST /api/v1/filter-reach` resolves each in-scope card the way its query
|
|
7
|
+
* will, without a value. Authoring only, never on the card query path.
|
|
8
|
+
*/
|
|
9
|
+
export type FilterReachRequest = {
|
|
10
|
+
dashboardId: string;
|
|
11
|
+
/** The filter as staged in the settings popover (unsaved edits included). */
|
|
12
|
+
filter: TFilter;
|
|
13
|
+
/** The draft's Option Source; absent when the draft has none (ledger R-04). */
|
|
14
|
+
optionSource?: DashboardFilterOptionSource;
|
|
15
|
+
/** In-scope cards, each as the draft runs it. */
|
|
16
|
+
cards: FilterReachPreviewCard[];
|
|
17
|
+
};
|
|
18
|
+
/** A card to preview, with the route the draft runs it with (ledger R-02). */
|
|
19
|
+
export type FilterReachPreviewCard = {
|
|
20
|
+
cardId: string;
|
|
21
|
+
/**
|
|
22
|
+
* The card's chosen route as the draft stands (RF-D10): a staged choice,
|
|
23
|
+
* else the saved one unless the author dropped it. Absent: the card has no
|
|
24
|
+
* entry of its own, and the preview says what the domain's relationships do.
|
|
25
|
+
*/
|
|
26
|
+
target?: DashboardFilterRelationshipTarget;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* What the domain's relationships do for a card as the draft runs it
|
|
30
|
+
* (relationship filter reach S-D).
|
|
31
|
+
*/
|
|
32
|
+
export type FilterReachCardOutcome = {
|
|
33
|
+
status: 'applied';
|
|
34
|
+
route: SemaphorRelationshipRoute;
|
|
35
|
+
} | {
|
|
36
|
+
status: 'skipped';
|
|
37
|
+
reason: SemaphorSkippedConstraintReason;
|
|
38
|
+
}
|
|
39
|
+
/** More than one equally preferred path: the card skips the filter until one is chosen (P-7). */
|
|
40
|
+
| {
|
|
41
|
+
status: 'needsPath';
|
|
42
|
+
} | {
|
|
43
|
+
status: 'blocked';
|
|
44
|
+
message: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The card applies the value as one of its own filters: the value's dataset
|
|
48
|
+
* is one its query already uses (its own filters included), so no route is
|
|
49
|
+
* needed (ledger R-05).
|
|
50
|
+
*/
|
|
51
|
+
| {
|
|
52
|
+
status: 'kept';
|
|
53
|
+
}
|
|
54
|
+
/** Reached another way, or not a semantic auto-join card. */
|
|
55
|
+
| {
|
|
56
|
+
status: 'notRelationship';
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* One card's preview: the outcome for the decision it answers, and the
|
|
60
|
+
* card's paths. A reader shows the outcome only while the card's decision is
|
|
61
|
+
* still the one named in `answers` (RF-INV-15); the paths don't depend on the
|
|
62
|
+
* decision (RF-D27).
|
|
63
|
+
*/
|
|
64
|
+
export type FilterReachCardPreview = {
|
|
65
|
+
cardId: string;
|
|
66
|
+
/** The decision this outcome is for: the path ids the request carried for the card, or none. */
|
|
67
|
+
answers: {
|
|
68
|
+
relationshipIds?: string[];
|
|
69
|
+
};
|
|
70
|
+
outcome: FilterReachCardOutcome;
|
|
71
|
+
/** The card's equally preferred paths, worked out with no path chosen; empty without a tie. */
|
|
72
|
+
paths: FilterReachPathOption[];
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* One path an author can choose, with the target that saves it: built by the
|
|
76
|
+
* server from the filter's value field in the card's domain, never from the
|
|
77
|
+
* browser's guess of that field (ledger R-16).
|
|
78
|
+
*/
|
|
79
|
+
export type FilterReachPathOption = {
|
|
80
|
+
route: SemaphorRelationshipRoute;
|
|
81
|
+
target: DashboardFilterRelationshipTarget;
|
|
82
|
+
};
|
|
83
|
+
export type FilterReachResponse = {
|
|
84
|
+
previews: FilterReachCardPreview[];
|
|
85
|
+
/** Present only when the caller can edit the domain the routes run in. */
|
|
86
|
+
manageRelationships?: {
|
|
87
|
+
href: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
/** Whether a preview answers a card's decision as it stands: the same path, or no path for both (RF-INV-15). */
|
|
91
|
+
export declare function filterReachPreviewAnswers(preview: Pick<FilterReachCardPreview, 'answers'>, relationshipIds: readonly string[] | undefined): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Reads a `/api/v1/filter-reach` response body. A malformed preview is
|
|
94
|
+
* dropped whole: one with no decision it answers, an unknown outcome, a
|
|
95
|
+
* malformed path, or a tie with fewer than two paths.
|
|
96
|
+
*/
|
|
97
|
+
export declare function readFilterReachResponse(body: unknown): FilterReachResponse;
|
|
@@ -2,9 +2,7 @@ export * from './contracts.js';
|
|
|
2
2
|
export * from './comparison-document-migration.js';
|
|
3
3
|
export * from './source-matching.js';
|
|
4
4
|
export * from './validators.js';
|
|
5
|
-
export * from './layout-compiler.js';
|
|
6
5
|
export * from './artifact-compiler.js';
|
|
7
|
-
export * from './change-compiler.js';
|
|
8
6
|
export * from './protocol-adapter.js';
|
|
9
7
|
export * from './temporal-result-owner.js';
|
|
10
8
|
export * from './temporal-bucket-authoring.js';
|
|
@@ -39,3 +37,25 @@ export { matrixCatalogSources, matrixExecutionSources } from './matrix-control-s
|
|
|
39
37
|
export * from './dashboard-option-dependencies.js';
|
|
40
38
|
export * from './new-card.js';
|
|
41
39
|
export * from './operations/apply-dashboard-operations.js';
|
|
40
|
+
export * from './changes/card-types.js';
|
|
41
|
+
export * from './changes/diagnostics.js';
|
|
42
|
+
export * from './changes/card-query-part.js';
|
|
43
|
+
export * from './changes/read-card-query.js';
|
|
44
|
+
export * from './changes/dashboard-change.js';
|
|
45
|
+
export * from './changes/resolve-dashboard-changes.js';
|
|
46
|
+
export * from './outline/outline-filters.js';
|
|
47
|
+
export * from './outline/outline-dashboard.js';
|
|
48
|
+
export * from './column-catalog.js';
|
|
49
|
+
export { prepareLoadedDashboard } from '../../lib/dashboard-inputs/prepare-loaded-dashboard.js';
|
|
50
|
+
export { buildFilterInputFromField, buildFilterInputFromDefinition, applyFilterSettingsChange } from '../../lib/dashboard-inputs/filter-settings.js';
|
|
51
|
+
export { relationshipRouteTarget } from '../../lib/dashboard-inputs/dashboard-filter-value-identity.js';
|
|
52
|
+
export type { FilterSettingsChange, FilterValueEffect } from '../../lib/dashboard-inputs/filter-settings.js';
|
|
53
|
+
export { describeDashboardFilterCardReach, describeDashboardFilterCardReachDetail, type DashboardFilterCardReach, type DashboardFilterCardReachDetail, type DashboardRelationshipReachResolver, } from '../../lib/query-context/dashboard-filter-mapping-resolution.js';
|
|
54
|
+
export { changeCardType, sharedCardPreferences, type CardTypeChange, type CardTypeChangeOptions, } from '../../lib/utils/card-type-change.js';
|
|
55
|
+
export { buildSavedEditorCard } from '../../lib/utils/build-saved-editor-card.js';
|
|
56
|
+
export { getCardDefinition, type AuthoredCardFields } from '../../lib/utils/card-definition.js';
|
|
57
|
+
export { changeMatrixEditor, dropMatrixEditorField, matrixEditorCatalogFromFields, } from '../../lib/matrix-table/matrix-editor.js';
|
|
58
|
+
export * from './filter-applicability.js';
|
|
59
|
+
export * from './semantic-auto-join-card.js';
|
|
60
|
+
export * from './filter-reach-preview.js';
|
|
61
|
+
export * from './filter-reach-copy.js';
|
|
@@ -1,40 +1,13 @@
|
|
|
1
|
-
import { TDashboard
|
|
1
|
+
import { TDashboard } from '../../../lib/types/common-types.js';
|
|
2
|
+
import { DashboardOperation, DashboardOperationResult, OperationContext } from './operation-types.js';
|
|
3
|
+
export type { CardUpdate, CreatedEntity, DashboardOperation, DashboardOperationResult, DashboardRuntimeEffect, FrameCommit, FramePlacement, OperationContext, OperationDescription, OperationFailureCode, } from './operation-types.js';
|
|
2
4
|
/**
|
|
3
5
|
* Edits to a dashboard as operations on one pure reducer (analytics agent
|
|
4
|
-
* Plan 1
|
|
5
|
-
*
|
|
6
|
-
* server
|
|
7
|
-
*
|
|
6
|
+
* Plan 1 AG-D14; MCP dashboard editing SPEC 3.3, 3.8). The one writer of the
|
|
7
|
+
* saved document for these edits: the editor stores, the change resolver's
|
|
8
|
+
* dry run and the server's apply all call it. It writes only the document; it
|
|
9
|
+
* returns what it created, one plain sentence per change, and the runtime
|
|
10
|
+
* effects a live editor applies to its own state (DE-D49). It never mints ids
|
|
11
|
+
* and never reads the clock (S-INV-1).
|
|
8
12
|
*/
|
|
9
|
-
|
|
10
|
-
export type DashboardFramePlacement = 'start' | 'end' | {
|
|
11
|
-
beside: string;
|
|
12
|
-
};
|
|
13
|
-
export type DashboardOperation = {
|
|
14
|
-
op: 'frame.add';
|
|
15
|
-
sheetId: string;
|
|
16
|
-
/** The frame with its cards, ids included. */
|
|
17
|
-
frame: TFrame;
|
|
18
|
-
/** Default `end`. */
|
|
19
|
-
placement?: DashboardFramePlacement;
|
|
20
|
-
};
|
|
21
|
-
export type DashboardOperationFailureCode = 'sheet_not_found'
|
|
22
|
-
/** A document sheet places cards through its document, not its grid. */
|
|
23
|
-
| 'sheet_not_a_grid' | 'frame_id_taken';
|
|
24
|
-
export type DashboardOperationResult = {
|
|
25
|
-
ok: true;
|
|
26
|
-
dashboard: TDashboard;
|
|
27
|
-
} | {
|
|
28
|
-
ok: false;
|
|
29
|
-
failedAt: {
|
|
30
|
-
index: number;
|
|
31
|
-
op: DashboardOperation['op'];
|
|
32
|
-
code: DashboardOperationFailureCode;
|
|
33
|
-
message: string;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Applies the operations in order, all or nothing. Never changes its input:
|
|
38
|
-
* the result shares every sheet it did not touch.
|
|
39
|
-
*/
|
|
40
|
-
export declare function applyDashboardOperations(dashboard: TDashboard, operations: DashboardOperation[]): DashboardOperationResult;
|
|
13
|
+
export declare function applyDashboardOperations(dashboard: TDashboard, operations: readonly DashboardOperation[], context: OperationContext): DashboardOperationResult;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { EmbeddedFilterDashboardInput, TDashboard, TFrame } from '../../../lib/types/common-types.js';
|
|
2
|
+
import { FilterSettingsChange, FilterValueEffect } from '../../../lib/dashboard-inputs/filter-settings.js';
|
|
3
|
+
import { DashboardFilterBoundCardApplication } from '../dashboard-filter-mapping-types.js';
|
|
4
|
+
import { Field } from '../../../lib/types/explorer-types.js';
|
|
5
|
+
import { TChartType } from '../../../lib/charts/types.js';
|
|
6
|
+
import { CalendarContext } from '../../report-runtime-context/index.js';
|
|
7
|
+
import { CardQueryPart, StatedLabel } from '../changes/card-query-part.js';
|
|
8
|
+
import { FramePlacement } from '../../layouts/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* The resolved operations the dashboard reducer applies (MCP dashboard
|
|
11
|
+
* editing SPEC 3.3, 3.8). Every id an operation creates is in it; the reducer
|
|
12
|
+
* never generates ids and never reads the clock (S-INV-1).
|
|
13
|
+
*/
|
|
14
|
+
/** Where a new frame goes on its sheet, by intent (responsive layouts SPEC §2.4). Absent: placed by kind. */
|
|
15
|
+
export type { FramePlacement };
|
|
16
|
+
export type CardUpdate =
|
|
17
|
+
/** Inline title and description edits; `description: null` removes it. */
|
|
18
|
+
{
|
|
19
|
+
kind: 'rename';
|
|
20
|
+
title?: string;
|
|
21
|
+
description?: string | null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A type transition: the editor's `changeCardType`, then the layout resize.
|
|
25
|
+
* `catalog` is the loaded column catalog a Matrix crossing needs; `newIds`
|
|
26
|
+
* every id the conversion mints, in the order it asks for them (DE-D54).
|
|
27
|
+
*/
|
|
28
|
+
| {
|
|
29
|
+
kind: 'retype';
|
|
30
|
+
type: TChartType;
|
|
31
|
+
catalog?: readonly Field[];
|
|
32
|
+
newIds: string[];
|
|
33
|
+
}
|
|
34
|
+
/** A new computed part for the card's current type; presentation is carried (SPEC 3.4). */
|
|
35
|
+
| {
|
|
36
|
+
kind: 'requery';
|
|
37
|
+
query: CardQueryPart;
|
|
38
|
+
}
|
|
39
|
+
/** Labels a change states on columns it doesn't rebuild, set in place by the label owner; nothing is recompiled (DE-D61). */
|
|
40
|
+
| {
|
|
41
|
+
kind: 'relabel';
|
|
42
|
+
labels: StatedLabel[];
|
|
43
|
+
};
|
|
44
|
+
/** Everything the editor's "Done", Save & Apply and Apply Local commit persists, as one operation (DE-D13). */
|
|
45
|
+
export type FrameCommit = {
|
|
46
|
+
sheetId: string;
|
|
47
|
+
/** The edited frame as the editor built it. Apply Local passes `visualId: undefined`. */
|
|
48
|
+
frame: TFrame;
|
|
49
|
+
/** Other frames on the sheet rewritten during the edit (calculated-field renames), applied with it. */
|
|
50
|
+
rewrittenFrames?: TFrame[];
|
|
51
|
+
/** Sheet calculated fields from the edited frame, persisted on the sheet. */
|
|
52
|
+
sheetCalculatedFields?: Field[];
|
|
53
|
+
/** Dashboard calculated fields rewritten during the edit. */
|
|
54
|
+
dashboardCalculatedFields?: Field[];
|
|
55
|
+
/** True when committed from the visual editor: resize the frame's layouts if its type changed. */
|
|
56
|
+
resizeLayouts: boolean;
|
|
57
|
+
};
|
|
58
|
+
export type DashboardOperation = ({
|
|
59
|
+
op: 'card.add';
|
|
60
|
+
sheetId: string;
|
|
61
|
+
/** The frame with its cards, ids included. */
|
|
62
|
+
frame: TFrame;
|
|
63
|
+
/** By intent; absent: placed by kind (responsive layouts SPEC §4.2). */
|
|
64
|
+
placement?: FramePlacement;
|
|
65
|
+
} | {
|
|
66
|
+
op: 'card.update';
|
|
67
|
+
cardId: string;
|
|
68
|
+
update: CardUpdate;
|
|
69
|
+
} | {
|
|
70
|
+
op: 'card.remove';
|
|
71
|
+
cardId: string;
|
|
72
|
+
}
|
|
73
|
+
/** Arrange a grid sheet by kind (responsive layouts RL-D7, SPEC §4.4); `keepOrder` keeps the reading order. */
|
|
74
|
+
| {
|
|
75
|
+
op: 'layout.arrange';
|
|
76
|
+
sheetId: string;
|
|
77
|
+
keepOrder?: boolean;
|
|
78
|
+
}
|
|
79
|
+
/** The editor's whole-frame commit; never produced by the resolver. */
|
|
80
|
+
| {
|
|
81
|
+
op: 'frame.commit';
|
|
82
|
+
commit: FrameCommit;
|
|
83
|
+
}
|
|
84
|
+
/** A new filter input, ids included; its defaults are in its definition, as the editor adds one. */
|
|
85
|
+
| {
|
|
86
|
+
op: 'filter.add';
|
|
87
|
+
input: EmbeddedFilterDashboardInput;
|
|
88
|
+
}
|
|
89
|
+
/** Settings through the editor's core (`applyFilterSettingsChange`); `filterId` is the input id. */
|
|
90
|
+
| {
|
|
91
|
+
op: 'filter.update';
|
|
92
|
+
filterId: string;
|
|
93
|
+
settings: FilterSettingsChange;
|
|
94
|
+
} | {
|
|
95
|
+
op: 'filter.remove';
|
|
96
|
+
filterId: string;
|
|
97
|
+
}
|
|
98
|
+
/** The card's bound entry in the filter's mapping, built as the mapping editor builds one. */
|
|
99
|
+
| {
|
|
100
|
+
op: 'filter.bind';
|
|
101
|
+
filterId: string;
|
|
102
|
+
cardId: string;
|
|
103
|
+
binding: DashboardFilterBoundCardApplication;
|
|
104
|
+
} | {
|
|
105
|
+
op: 'filter.exclude';
|
|
106
|
+
filterId: string;
|
|
107
|
+
cardId: string;
|
|
108
|
+
}) & {
|
|
109
|
+
/** Set by the resolver: the public change this operation came from. Descriptions group by it. */
|
|
110
|
+
changeIndex?: number;
|
|
111
|
+
};
|
|
112
|
+
export type OperationContext = {
|
|
113
|
+
/** The report calendar; filter defaults resolve in it. A proposal's has a fixed anchor (DE-D59). */
|
|
114
|
+
calendar: CalendarContext | null;
|
|
115
|
+
};
|
|
116
|
+
export type CreatedEntity = {
|
|
117
|
+
kind: 'card' | 'filter';
|
|
118
|
+
id: string;
|
|
119
|
+
title: string;
|
|
120
|
+
changeIndex?: number;
|
|
121
|
+
};
|
|
122
|
+
export type OperationDescription = {
|
|
123
|
+
/** Operations with the same changeIndex share one description. */
|
|
124
|
+
changeIndex?: number;
|
|
125
|
+
/** Indexes into the operations list. */
|
|
126
|
+
operations: number[];
|
|
127
|
+
sentence: string;
|
|
128
|
+
};
|
|
129
|
+
/** What a live editor must do to its own state after an operation. The server ignores them (DE-D49). */
|
|
130
|
+
export type DashboardRuntimeEffect =
|
|
131
|
+
/** card.remove, and frame.commit dropping tabs: drop live state keyed by these cards. */
|
|
132
|
+
{
|
|
133
|
+
kind: 'cards_removed';
|
|
134
|
+
cardIds: string[];
|
|
135
|
+
}
|
|
136
|
+
/** frame.commit: re-sync inline filter runtime values from the frame before and after. */
|
|
137
|
+
| {
|
|
138
|
+
kind: 'frame_committed';
|
|
139
|
+
sheetId: string;
|
|
140
|
+
before: TFrame;
|
|
141
|
+
after: TFrame;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* filter.update: `applyFilterSettingsChange`'s value effects, unchanged. One
|
|
145
|
+
* per update, even with none: the store still re-resolves forced selections,
|
|
146
|
+
* as `saveFilterSettings` always has (ledger P3-02).
|
|
147
|
+
*/
|
|
148
|
+
| {
|
|
149
|
+
kind: 'filter_value';
|
|
150
|
+
effects: FilterValueEffect[];
|
|
151
|
+
}
|
|
152
|
+
/** filter.remove: drop the input's live values. */
|
|
153
|
+
| {
|
|
154
|
+
kind: 'input_removed';
|
|
155
|
+
inputId: string;
|
|
156
|
+
};
|
|
157
|
+
export type OperationFailureCode = 'sheet_not_found'
|
|
158
|
+
/** A document sheet places cards through its document, not its grid. */
|
|
159
|
+
| 'sheet_not_a_grid' | 'frame_id_taken' | 'frame_not_found' | 'card_not_found' | 'filter_not_found' | 'filter_id_taken'
|
|
160
|
+
/** The filter settings or mapping fail the input contract; `details.issues` has the core's issues. */
|
|
161
|
+
| 'filter_invalid'
|
|
162
|
+
/** A requery part compiled for another type than the card's. */
|
|
163
|
+
| 'query_type_mismatch'
|
|
164
|
+
/** A requery part that doesn't make a valid card (a Matrix definition the Matrix contract refuses). */
|
|
165
|
+
| 'query_invalid'
|
|
166
|
+
/** A requery would change a part of the card its change doesn't state (DE-D61). */
|
|
167
|
+
| 'query_not_kept'
|
|
168
|
+
/** A conversion asked for more ids than the operation carries. */
|
|
169
|
+
| 'ids_exhausted'
|
|
170
|
+
/** A retype across the Matrix boundary without a catalog. */
|
|
171
|
+
| 'catalog_loading';
|
|
172
|
+
export type DashboardOperationResult = {
|
|
173
|
+
ok: true;
|
|
174
|
+
dashboard: TDashboard;
|
|
175
|
+
created: CreatedEntity[];
|
|
176
|
+
/** One plain sentence per public change (or per operation without a changeIndex). */
|
|
177
|
+
descriptions: OperationDescription[];
|
|
178
|
+
runtimeEffects: DashboardRuntimeEffect[];
|
|
179
|
+
} | {
|
|
180
|
+
ok: false;
|
|
181
|
+
failedAt: {
|
|
182
|
+
index: number;
|
|
183
|
+
op: DashboardOperation['op'];
|
|
184
|
+
code: OperationFailureCode;
|
|
185
|
+
message: string;
|
|
186
|
+
fix?: string;
|
|
187
|
+
details?: Record<string, unknown>;
|
|
188
|
+
};
|
|
189
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { DashboardRelationshipReachResolver } from '../../../lib/query-context/dashboard-filter-mapping-resolution.js';
|
|
2
|
+
import { TDashboard } from '../../../lib/types/common-types.js';
|
|
3
|
+
import { FrameWidth } from '../../layouts/index.js';
|
|
4
|
+
import { NotEditableReason, OutlineCardSource } from '../changes/read-card-query.js';
|
|
5
|
+
import { CardQuery, MatrixColumns } from '../changes/dashboard-change.js';
|
|
6
|
+
import { OutlineFilter } from './outline-filters.js';
|
|
7
|
+
import { CalendarContext } from '../../report-runtime-context/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* A dashboard in the change vocabulary (MCP dashboard editing SPEC 3.6,
|
|
10
|
+
* DE-D29, DE-D34): every sheet, every card the shared traversal lists
|
|
11
|
+
* (Document-section cards included, read only), every filter, and what the
|
|
12
|
+
* viewer may do. A pure function of the hydrated dashboard and the viewer
|
|
13
|
+
* (S-INV-8): no clock, no catalog, no network.
|
|
14
|
+
*/
|
|
15
|
+
export type OutlineViewer = {
|
|
16
|
+
dashboardId: string;
|
|
17
|
+
/** `Dashboard.updatedAt`, ISO 8601; the staleness token, never called "version" (DE-D37). */
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
access: {
|
|
20
|
+
canEdit: boolean;
|
|
21
|
+
canCopy: boolean;
|
|
22
|
+
};
|
|
23
|
+
sql: boolean;
|
|
24
|
+
sheetIds?: string[];
|
|
25
|
+
cardIds?: string[];
|
|
26
|
+
/** Above this many cards (after narrowing), queries are left out. Default 50 (DE-D34). */
|
|
27
|
+
maxQueryCards?: number;
|
|
28
|
+
/** The report calendar filter defaults are read in; without one, a fixed calendar at `updatedAt` (S-INV-8). */
|
|
29
|
+
calendar?: CalendarContext;
|
|
30
|
+
/**
|
|
31
|
+
* Server side only: resolves relationship reach the way the card query
|
|
32
|
+
* does, with each card's domain preloaded (relationship filter reach RF-D15).
|
|
33
|
+
* Without one, such cards are listed under `relationshipPending`.
|
|
34
|
+
*/
|
|
35
|
+
relationshipReach?: DashboardRelationshipReachResolver;
|
|
36
|
+
};
|
|
37
|
+
export type OutlineCard = {
|
|
38
|
+
cardId: string;
|
|
39
|
+
title: string;
|
|
40
|
+
/** The public type name (DE-D43). */
|
|
41
|
+
type: string;
|
|
42
|
+
source: OutlineCardSource;
|
|
43
|
+
/** Shows a library visual; changing it makes it local (DE-D50). */
|
|
44
|
+
linkedVisualId?: string;
|
|
45
|
+
editable: true;
|
|
46
|
+
/** Absent only when the outline is truncated. */
|
|
47
|
+
query?: CardQuery;
|
|
48
|
+
matrix?: MatrixColumns;
|
|
49
|
+
} | {
|
|
50
|
+
cardId: string;
|
|
51
|
+
title: string;
|
|
52
|
+
type: string;
|
|
53
|
+
source?: OutlineCardSource;
|
|
54
|
+
linkedVisualId?: string;
|
|
55
|
+
editable: false;
|
|
56
|
+
notEditable: {
|
|
57
|
+
reason: NotEditableReason;
|
|
58
|
+
message: string;
|
|
59
|
+
detail?: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
export type OutlineSheet = {
|
|
63
|
+
sheetId: string;
|
|
64
|
+
title: string;
|
|
65
|
+
/** Cards can be added only to "dashboard" sheets. */
|
|
66
|
+
kind: 'dashboard' | 'document';
|
|
67
|
+
/** On a Document sheet, its sections' cards (never editable). */
|
|
68
|
+
cards: OutlineCard[];
|
|
69
|
+
/**
|
|
70
|
+
* Grid sheets only: the desktop layout as rows, top to bottom, from the
|
|
71
|
+
* layout engine (responsive layouts RL-D10). Always the whole sheet, even
|
|
72
|
+
* when `cardIds` narrows the cards. Absent on Document sheets.
|
|
73
|
+
*/
|
|
74
|
+
layout?: OutlineLayoutRow[];
|
|
75
|
+
};
|
|
76
|
+
/** One row of a sheet's desktop layout. A tile is a frame: its cards, active first, and its width by intent. Never coordinates (RL-INV-5). */
|
|
77
|
+
export type OutlineLayoutRow = {
|
|
78
|
+
tiles: Array<{
|
|
79
|
+
cardIds: string[];
|
|
80
|
+
width: FrameWidth;
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
export type DashboardOutline = {
|
|
84
|
+
dashboardId: string;
|
|
85
|
+
title: string;
|
|
86
|
+
updatedAt: string;
|
|
87
|
+
access: {
|
|
88
|
+
canEdit: boolean;
|
|
89
|
+
canCopy: boolean;
|
|
90
|
+
};
|
|
91
|
+
/** Every dataset a card or filter uses. */
|
|
92
|
+
datasets: Array<{
|
|
93
|
+
domainId: string;
|
|
94
|
+
datasetName: string;
|
|
95
|
+
}>;
|
|
96
|
+
sheets: OutlineSheet[];
|
|
97
|
+
filters: OutlineFilter[];
|
|
98
|
+
/** Queries left out because the dashboard has more than `maxQueryCards` cards (DE-D34). */
|
|
99
|
+
truncated?: true;
|
|
100
|
+
};
|
|
101
|
+
export declare function outlineDashboard(dashboard: TDashboard, viewer: OutlineViewer): DashboardOutline;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { TDashboard } from '../../../lib/types/common-types.js';
|
|
2
|
+
import { DashboardRelationshipReachResolver } from '../../../lib/query-context/dashboard-filter-mapping-resolution.js';
|
|
3
|
+
import { SemaphorSkippedConstraintReason } from '../../analytics-protocol/index.js';
|
|
4
|
+
import { FilterInputEntry } from '../filter-model/index.js';
|
|
5
|
+
import { CalendarContext } from '../../report-runtime-context/index.js';
|
|
6
|
+
import { FilterValue, TimeWindow } from '../changes/dashboard-change.js';
|
|
7
|
+
/**
|
|
8
|
+
* Every dashboard filter in the change vocabulary (MCP dashboard editing
|
|
9
|
+
* DE-D58, SPEC 3.6). A field filter on one semantic dataset shown on every
|
|
10
|
+
* grid sheet or a list of sheets is editable; any other filter is a
|
|
11
|
+
* read-only summary with its reach and a reason, never left out and never
|
|
12
|
+
* given invented coordinates. Reach is read the way each card runs the
|
|
13
|
+
* filter (`describeDashboardFilterCardReach`).
|
|
14
|
+
*/
|
|
15
|
+
export type FilterNotEditableReason = 'global_date' | 'not_semantic' | 'scope_not_expressible';
|
|
16
|
+
export type OutlineFilter = {
|
|
17
|
+
filterId: string;
|
|
18
|
+
label: string;
|
|
19
|
+
editable: true;
|
|
20
|
+
domainId: string;
|
|
21
|
+
datasetName: string;
|
|
22
|
+
field: string;
|
|
23
|
+
selection: 'single' | 'multiple';
|
|
24
|
+
/** The values it loads with, read through the default owner (a saved default first, else the definition). */
|
|
25
|
+
defaultValues?: FilterValue[];
|
|
26
|
+
/** The window it loads with, only when the loaded default keeps one (a day picker clamps a wider window to a day). */
|
|
27
|
+
defaultPeriod?: TimeWindow;
|
|
28
|
+
/** For a date filter, the picker a viewer gets: one day, one month, or a range. */
|
|
29
|
+
datePicker?: 'day' | 'month' | 'range';
|
|
30
|
+
/** "all": every grid sheet. */
|
|
31
|
+
sheetIds: string[] | 'all';
|
|
32
|
+
/** With "all": the sheets it leaves out ("every sheet except"); a sheet added later is reached. */
|
|
33
|
+
exceptSheetIds?: string[];
|
|
34
|
+
/** With "all": it also shows on Document sheets (their sections' cards). */
|
|
35
|
+
includesDocumentSheets?: true;
|
|
36
|
+
/** Card ids the filter applies to. */
|
|
37
|
+
reaches: string[];
|
|
38
|
+
/** Card ids excluded explicitly. */
|
|
39
|
+
excluded: string[];
|
|
40
|
+
/** In scope, not matched; with a resolver (server side), the reason relationship reach gave. */
|
|
41
|
+
notReached: Array<{
|
|
42
|
+
cardId: string;
|
|
43
|
+
title: string;
|
|
44
|
+
datasetName?: string;
|
|
45
|
+
reason?: SemaphorSkippedConstraintReason;
|
|
46
|
+
}>;
|
|
47
|
+
/** In scope, and blocked when the filter has a value: a binding the card can't run, or two fields it could take. */
|
|
48
|
+
blocked?: Array<{
|
|
49
|
+
cardId: string;
|
|
50
|
+
title: string;
|
|
51
|
+
reason: 'blocked' | 'ambiguous';
|
|
52
|
+
}>;
|
|
53
|
+
/**
|
|
54
|
+
* In scope, on another dataset of the card's domain: the server decides
|
|
55
|
+
* when the card runs, through the domain's relationships, whether the
|
|
56
|
+
* filter applies. Never counted as reached.
|
|
57
|
+
*/
|
|
58
|
+
relationshipPending?: Array<{
|
|
59
|
+
cardId: string;
|
|
60
|
+
title: string;
|
|
61
|
+
datasetName?: string;
|
|
62
|
+
}>;
|
|
63
|
+
} | {
|
|
64
|
+
filterId: string;
|
|
65
|
+
label: string;
|
|
66
|
+
editable: false;
|
|
67
|
+
kind: 'global_date' | 'field' | 'other';
|
|
68
|
+
notEditable: {
|
|
69
|
+
reason: FilterNotEditableReason;
|
|
70
|
+
message: string;
|
|
71
|
+
};
|
|
72
|
+
reaches: string[];
|
|
73
|
+
excluded: string[];
|
|
74
|
+
blocked?: Array<{
|
|
75
|
+
cardId: string;
|
|
76
|
+
title: string;
|
|
77
|
+
reason: 'blocked' | 'ambiguous';
|
|
78
|
+
}>;
|
|
79
|
+
relationshipPending?: Array<{
|
|
80
|
+
cardId: string;
|
|
81
|
+
title: string;
|
|
82
|
+
datasetName?: string;
|
|
83
|
+
}>;
|
|
84
|
+
};
|
|
85
|
+
/** Server-side readers resolve relationship reach the way the card query does (RF-D15). */
|
|
86
|
+
export type OutlineReachOptions = {
|
|
87
|
+
relationshipReach?: DashboardRelationshipReachResolver;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The calendar a summary reads defaults in: the report's, else a fixed one at
|
|
91
|
+
* the dashboard's own time, so a summary stays a pure function of its inputs.
|
|
92
|
+
* Only whether a default keeps its window is reported, never the dates it
|
|
93
|
+
* resolves to.
|
|
94
|
+
*/
|
|
95
|
+
export declare function outlineCalendar(calendar: CalendarContext | undefined, updatedAt: string | undefined): CalendarContext;
|
|
96
|
+
export declare function summarizeFilter(dashboard: TDashboard, entry: FilterInputEntry, calendar?: CalendarContext, options?: OutlineReachOptions): OutlineFilter;
|
|
97
|
+
/** Every filter on the dashboard, in the filter model's order. */
|
|
98
|
+
export declare function outlineFilters(dashboard: TDashboard, calendar?: CalendarContext, options?: OutlineReachOptions): OutlineFilter[];
|
|
99
|
+
/** One filter by its input id, or undefined. */
|
|
100
|
+
export declare function outlineFilter(dashboard: TDashboard, filterId: string, calendar?: CalendarContext, options?: OutlineReachOptions): OutlineFilter | undefined;
|