@devicechain/dashboards 0.21.1 → 0.22.0-rc.1
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 +88 -7
- package/dist/channel-snapshots.d.ts +43 -0
- package/dist/connection.d.ts +27 -0
- package/dist/definition.d.ts +8 -6
- package/dist/editor-clipboard.d.ts +42 -0
- package/dist/editor-history.d.ts +30 -0
- package/dist/editor-model.d.ts +62 -13
- package/dist/grid.d.ts +53 -0
- package/dist/history.d.ts +1 -0
- package/dist/hub.d.ts +25 -0
- package/dist/index.d.ts +21 -8
- package/dist/index.js +2332 -243
- package/dist/index.js.map +4 -4
- package/dist/is-record.d.ts +1 -0
- package/dist/layout-lint.d.ts +24 -0
- package/dist/legacy-grid.d.ts +4 -0
- package/dist/legacy-window.d.ts +5 -0
- package/dist/members.d.ts +36 -0
- package/dist/option-schema.d.ts +10 -1
- package/dist/queries.d.ts +14 -0
- package/dist/recorded.d.ts +4 -0
- package/dist/reflow.d.ts +26 -0
- package/dist/resolver.d.ts +1 -0
- package/dist/same-label.d.ts +1 -0
- package/dist/slots.d.ts +2 -1
- package/dist/synthetic.d.ts +8 -4
- package/dist/time-range.d.ts +52 -0
- package/dist/types.d.ts +96 -11
- package/dist/widget-descriptor.d.ts +25 -4
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isRecord(v: unknown): v is Record<string, unknown>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DashboardDefinition, WidgetInstance } from './types';
|
|
2
|
+
import { type WidgetLayoutSpec, type WidgetSpan } from './widget-descriptor';
|
|
3
|
+
export type LayoutLintSeverity = 'error' | 'warning' | 'info';
|
|
4
|
+
export type LayoutLintCode = 'span-out-of-limits' | 'overrun-columns' | 'relative-off-canvas' | 'no-layout-declared' | 'title-duplicates-subtitle';
|
|
5
|
+
export interface LayoutFinding {
|
|
6
|
+
code: LayoutLintCode;
|
|
7
|
+
severity: LayoutLintSeverity;
|
|
8
|
+
widgetId: string;
|
|
9
|
+
message: string;
|
|
10
|
+
breakpoint?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const PUBLISH_BLOCKING_LAYOUT_CODES: readonly LayoutLintCode[];
|
|
13
|
+
export declare function blockingLayoutFindings(findings: readonly LayoutFinding[]): LayoutFinding[];
|
|
14
|
+
export interface SpanLimits {
|
|
15
|
+
minSpan?: Partial<WidgetSpan>;
|
|
16
|
+
maxSpan?: Partial<WidgetSpan>;
|
|
17
|
+
}
|
|
18
|
+
export interface LayoutLintOptions {
|
|
19
|
+
columns: number;
|
|
20
|
+
spanLimitsOf: (widget: WidgetInstance) => SpanLimits | undefined;
|
|
21
|
+
}
|
|
22
|
+
export declare function spanLimitsOfLayout(layout: WidgetLayoutSpec | undefined): SpanLimits | undefined;
|
|
23
|
+
export declare const RELATIVE_PROBE_CELLS: (minCellSize: number) => number[];
|
|
24
|
+
export declare function lintLayout(def: DashboardDefinition, options: LayoutLintOptions): LayoutFinding[];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const GRID_SCHEMA_VERSION = 2;
|
|
2
|
+
export declare const LEGACY_REFERENCE_WIDTH = 1366;
|
|
3
|
+
export declare function storedSchemaVersion(raw: Record<string, unknown>): number;
|
|
4
|
+
export declare function convertLegacyDefinition(raw: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { MeasurementBucket } from './queries';
|
|
2
|
+
import type { MeasurementSample } from './types';
|
|
3
|
+
export interface MemberRef {
|
|
4
|
+
token: string;
|
|
5
|
+
name: string | null;
|
|
6
|
+
}
|
|
7
|
+
export interface MemberRoster {
|
|
8
|
+
members: MemberRef[];
|
|
9
|
+
total: number;
|
|
10
|
+
unbound: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface MemberSink {
|
|
13
|
+
roster(roster: MemberRoster): void;
|
|
14
|
+
next(sample: MeasurementSample): void;
|
|
15
|
+
forbidden?(): void;
|
|
16
|
+
error?(err: unknown): void;
|
|
17
|
+
}
|
|
18
|
+
export type SeedFailure = 'forbidden' | 'failed';
|
|
19
|
+
export interface MemberBucketCriteria {
|
|
20
|
+
startTime: string;
|
|
21
|
+
endTime: string;
|
|
22
|
+
intervalSeconds: number;
|
|
23
|
+
name?: string;
|
|
24
|
+
}
|
|
25
|
+
export type MemberBucketRead = (criteria: MemberBucketCriteria) => Promise<MeasurementBucket[]>;
|
|
26
|
+
export interface MemberSeedPlan {
|
|
27
|
+
seed(deviceToken: string, read: MemberBucketRead): Promise<MemberSeed>;
|
|
28
|
+
}
|
|
29
|
+
export interface MemberSeed {
|
|
30
|
+
latest: Record<string, MeasurementSample>;
|
|
31
|
+
observed: string[];
|
|
32
|
+
unread?: string[];
|
|
33
|
+
}
|
|
34
|
+
export declare const MEMBER_SEED_CONCURRENCY = 6;
|
|
35
|
+
export declare const SEED_CANCELLED: unique symbol;
|
|
36
|
+
export declare function createLimiter(max: number): <T>(task: () => Promise<T>, cancelled?: () => boolean) => Promise<T>;
|
package/dist/option-schema.d.ts
CHANGED
|
@@ -30,7 +30,13 @@ export interface EnumOptionSpec<V extends string = string> extends OptionSpecBas
|
|
|
30
30
|
placeholder?: string;
|
|
31
31
|
placeholderId?: string;
|
|
32
32
|
}
|
|
33
|
-
export type
|
|
33
|
+
export type ListItemFieldSpec = StringOptionSpec | NumberOptionSpec | BooleanOptionSpec | EnumOptionSpec;
|
|
34
|
+
export interface ListOptionSpec extends OptionSpecBase {
|
|
35
|
+
kind: 'list';
|
|
36
|
+
item: Readonly<Record<string, ListItemFieldSpec>>;
|
|
37
|
+
maxItems?: number;
|
|
38
|
+
}
|
|
39
|
+
export type OptionSpec = StringOptionSpec | NumberOptionSpec | BooleanOptionSpec | EnumOptionSpec | ListOptionSpec;
|
|
34
40
|
export type WidgetOptionSpecs = Record<string, OptionSpec>;
|
|
35
41
|
export interface GreaterThanConstraint<K extends string = string> {
|
|
36
42
|
kind: 'greater-than';
|
|
@@ -39,6 +45,9 @@ export interface GreaterThanConstraint<K extends string = string> {
|
|
|
39
45
|
}
|
|
40
46
|
export type OptionConstraint<K extends string = string> = GreaterThanConstraint<K>;
|
|
41
47
|
export type SpecValue<S> = S extends {
|
|
48
|
+
kind: 'list';
|
|
49
|
+
item: infer I;
|
|
50
|
+
} ? OptionsOf<I>[] : S extends {
|
|
42
51
|
kind: 'enum';
|
|
43
52
|
values: readonly (infer V)[];
|
|
44
53
|
} ? V extends string ? V : never : S extends {
|
package/dist/queries.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export interface EntityRelationshipsResult {
|
|
|
6
6
|
token: string;
|
|
7
7
|
};
|
|
8
8
|
}>;
|
|
9
|
+
pagination?: {
|
|
10
|
+
totalRecords: number | null;
|
|
11
|
+
} | null;
|
|
9
12
|
};
|
|
10
13
|
}
|
|
11
14
|
export interface EntityRelationshipsVariables {
|
|
@@ -28,6 +31,13 @@ export interface DevicesByTokenVariables {
|
|
|
28
31
|
tokens: string[];
|
|
29
32
|
}
|
|
30
33
|
export declare const DEVICES_BY_TOKEN: TypedDocument<DevicesByTokenResult, DevicesByTokenVariables>;
|
|
34
|
+
export interface DeviceNamesResult {
|
|
35
|
+
devicesByToken: Array<{
|
|
36
|
+
token: string;
|
|
37
|
+
name: string | null;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
export declare const DEVICE_NAMES: TypedDocument<DeviceNamesResult, DevicesByTokenVariables>;
|
|
31
41
|
export interface EntityListResult {
|
|
32
42
|
results: Array<{
|
|
33
43
|
token: string;
|
|
@@ -56,6 +66,10 @@ export interface MeasurementBucket {
|
|
|
56
66
|
bucketStart: string;
|
|
57
67
|
name: string;
|
|
58
68
|
avg: number | null;
|
|
69
|
+
min?: number | null;
|
|
70
|
+
max?: number | null;
|
|
71
|
+
sum?: number | null;
|
|
72
|
+
count?: number;
|
|
59
73
|
}
|
|
60
74
|
export interface BucketedMeasurementsResult {
|
|
61
75
|
bucketedMeasurements: MeasurementBucket[];
|
package/dist/recorded.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AlarmStreamSink, AlarmSubscription, CommandStreamSink, CommandSubscription, DeviceResolver, LocationStreamSink, LocationSubscription, WidgetDataSource, WidgetStreamSink } from './hub';
|
|
2
2
|
import type { AnchorTarget, DatasourceSelector, EntityCandidateLister } from './types';
|
|
3
3
|
import { type BoardRecording } from './recording';
|
|
4
|
+
import type { MemberSeed, MemberSeedPlan, MemberSink } from './members';
|
|
4
5
|
export declare const RECORDED_HISTORY_WINDOW_MS: number;
|
|
5
6
|
export type RecordedChannel = 'measurements' | 'alarms' | 'locations' | 'commands';
|
|
6
7
|
export declare class NotInRecordingError extends Error {
|
|
@@ -66,12 +67,15 @@ export declare class RecordedDataSource implements WidgetDataSource {
|
|
|
66
67
|
private stale;
|
|
67
68
|
constructor(rec: BoardRecording, clock: RecordedClock, options?: RecordedSiteOptions);
|
|
68
69
|
get isStale(): boolean;
|
|
70
|
+
now(): number;
|
|
69
71
|
private onClock;
|
|
70
72
|
private iso;
|
|
71
73
|
private open;
|
|
72
74
|
private resolve;
|
|
73
75
|
private failLater;
|
|
74
76
|
subscribeWidget(datasource: DatasourceSelector, sink: WidgetStreamSink): () => void;
|
|
77
|
+
subscribeMembers(datasource: DatasourceSelector, sink: MemberSink): () => void;
|
|
78
|
+
readMemberSeeds(deviceTokens: readonly string[], _plan: MemberSeedPlan, onSeed: (deviceToken: string, seed: MemberSeed | null) => void): Promise<void>;
|
|
75
79
|
subscribeAlarms(subscription: AlarmSubscription, sink: AlarmStreamSink): () => void;
|
|
76
80
|
subscribeCommands(_subscription: CommandSubscription, sink: CommandStreamSink): () => void;
|
|
77
81
|
subscribeLocations(subscription: LocationSubscription, sink: LocationStreamSink): () => void;
|
package/dist/reflow.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SpanLimits } from './layout-lint';
|
|
2
|
+
import type { CanvasGrid, DashboardDefinition, GridPlacement, WidgetInstance } from './types';
|
|
3
|
+
export declare function liveColumns(grid: CanvasGrid, containerWidth: number, authored: number, scale?: number): number;
|
|
4
|
+
export interface ReflowItem {
|
|
5
|
+
id: string;
|
|
6
|
+
placement: GridPlacement;
|
|
7
|
+
limits?: SpanLimits;
|
|
8
|
+
}
|
|
9
|
+
export declare const STACK_BELOW_WIDTH = 600;
|
|
10
|
+
export declare function reflowGrid(items: readonly ReflowItem[], columns: number, options?: {
|
|
11
|
+
stack?: boolean;
|
|
12
|
+
}): Map<string, GridPlacement>;
|
|
13
|
+
export interface LayoutShape {
|
|
14
|
+
breakpoint: string;
|
|
15
|
+
columns: number;
|
|
16
|
+
reflowed: boolean;
|
|
17
|
+
stacked: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function layoutShape(canvas: Pick<DashboardDefinition['canvas'], 'grid' | 'breakpoints'>, containerWidth: number, scale?: number): LayoutShape;
|
|
20
|
+
export interface EffectiveLayout extends LayoutShape {
|
|
21
|
+
grid: Map<string, GridPlacement>;
|
|
22
|
+
}
|
|
23
|
+
export declare function effectiveLayout(def: DashboardDefinition, containerWidth: number, options?: {
|
|
24
|
+
scale?: number;
|
|
25
|
+
limitsOf?: (w: WidgetInstance) => SpanLimits | undefined;
|
|
26
|
+
}): EffectiveLayout;
|
package/dist/resolver.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sameLabel(a: string | null | undefined, b: string | null | undefined): boolean;
|
package/dist/slots.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type AnchorTarget, type DashboardDefinition, type LocationSelection, type SlotBinding, type SlotScope, type WidgetInstance } from './types';
|
|
1
|
+
import { type AnchorTarget, type DashboardDefinition, type LocationSelection, type SlotBinding, type SlotDefinition, type SlotScope, type WidgetInstance } from './types';
|
|
2
2
|
export declare function sameBinding(a: SlotBinding | undefined, b: SlotBinding | undefined): boolean;
|
|
3
|
+
export declare function nextSlotName(slots: Record<string, SlotDefinition>): string;
|
|
3
4
|
export declare function migrateToSlots(def: DashboardDefinition): DashboardDefinition;
|
|
4
5
|
export declare function bindWidgetSlot(def: DashboardDefinition, widgetId: string, binding: SlotBinding, measurements: string[], location?: LocationSelection): DashboardDefinition;
|
|
5
6
|
export declare function clearWidgetDatasource(def: DashboardDefinition, widgetId: string): DashboardDefinition;
|
package/dist/synthetic.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import type { HistoryWindow } from './history';
|
|
2
|
+
import type { MemberSeed, MemberSeedPlan, MemberSink } from './members';
|
|
3
|
+
import type { MeasurementBucket } from './queries';
|
|
1
4
|
import type { AlarmStreamSink, AlarmSubscription, CommandDispatch, CommandStreamSink, CommandSubscription, LocationStreamSink, LocationSubscription, WidgetActions, WidgetDataSource, WidgetStreamSink } from './hub';
|
|
2
5
|
import type { DatasourceSelector } from './types';
|
|
3
6
|
export type SyntheticGenerator = 'sine' | 'ramp' | 'random-walk';
|
|
4
|
-
export declare const SYNTHETIC_GENERATORS: ReadonlyArray<
|
|
5
|
-
value: SyntheticGenerator;
|
|
6
|
-
label: string;
|
|
7
|
-
}>;
|
|
7
|
+
export declare const SYNTHETIC_GENERATORS: ReadonlyArray<SyntheticGenerator>;
|
|
8
8
|
export interface SyntheticDataSourceConfig {
|
|
9
9
|
generator?: SyntheticGenerator;
|
|
10
10
|
intervalMs?: number;
|
|
@@ -31,6 +31,10 @@ export declare class SyntheticDataSource implements WidgetDataSource, WidgetActi
|
|
|
31
31
|
acknowledgeAlarm(): Promise<void>;
|
|
32
32
|
clearAlarm(): Promise<void>;
|
|
33
33
|
sendCommand(): Promise<CommandDispatch>;
|
|
34
|
+
bucketMeasurements(datasource: DatasourceSelector, window: HistoryWindow): Promise<MeasurementBucket[]>;
|
|
35
|
+
private previewMembers;
|
|
36
|
+
subscribeMembers(datasource: DatasourceSelector, sink: MemberSink): () => void;
|
|
37
|
+
readMemberSeeds(deviceTokens: readonly string[], _plan: MemberSeedPlan, onSeed: (deviceToken: string, seed: MemberSeed | null) => void): Promise<void>;
|
|
34
38
|
disposeAll(): void;
|
|
35
39
|
private valueFor;
|
|
36
40
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { DashboardDefinition } from './types';
|
|
2
|
+
export declare const TIME_RANGE_PRESETS: readonly [{
|
|
3
|
+
readonly id: '15m';
|
|
4
|
+
readonly seconds: number;
|
|
5
|
+
}, {
|
|
6
|
+
readonly id: '1h';
|
|
7
|
+
readonly seconds: number;
|
|
8
|
+
}, {
|
|
9
|
+
readonly id: '6h';
|
|
10
|
+
readonly seconds: number;
|
|
11
|
+
}, {
|
|
12
|
+
readonly id: '24h';
|
|
13
|
+
readonly seconds: number;
|
|
14
|
+
}, {
|
|
15
|
+
readonly id: '7d';
|
|
16
|
+
readonly seconds: number;
|
|
17
|
+
}];
|
|
18
|
+
export type TimeRangePresetId = (typeof TIME_RANGE_PRESETS)[number]['id'];
|
|
19
|
+
export declare const DEFAULT_TIME_RANGE_SECONDS: number;
|
|
20
|
+
export declare const MIN_TIME_RANGE_SECONDS = 60;
|
|
21
|
+
export declare const MAX_TIME_RANGE_SECONDS: number;
|
|
22
|
+
export declare function isValidSpanSeconds(v: unknown): v is number;
|
|
23
|
+
export interface TimeRangeState {
|
|
24
|
+
spanSeconds: number;
|
|
25
|
+
paused: boolean;
|
|
26
|
+
pausedAt?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function initialTimeRange(defaultSeconds: number | undefined, link?: {
|
|
29
|
+
spanSeconds?: number;
|
|
30
|
+
paused?: boolean;
|
|
31
|
+
}, now?: number): TimeRangeState;
|
|
32
|
+
export declare function pauseRange(state: TimeRangeState, now: number): TimeRangeState;
|
|
33
|
+
export declare function resumeRange(state: TimeRangeState): TimeRangeState;
|
|
34
|
+
export declare function withSpan(state: TimeRangeState, spanSeconds: number): TimeRangeState;
|
|
35
|
+
export declare function rangeEnd(state: TimeRangeState, now: number): number;
|
|
36
|
+
export interface RangeWindow {
|
|
37
|
+
startTime: string;
|
|
38
|
+
endTime: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function rangeWindow(state: TimeRangeState, now: number): RangeWindow;
|
|
41
|
+
export declare const MAX_SEED_BUCKETS = 240;
|
|
42
|
+
export declare function bucketSecondsFor(spanSeconds: number): number;
|
|
43
|
+
export declare function seedBucketCount(spanSeconds: number): number;
|
|
44
|
+
export declare function parseRangeParam(value: string | null | undefined): number | undefined;
|
|
45
|
+
export declare function parsePausedParam(value: string | null | undefined): boolean;
|
|
46
|
+
export declare function timeRangeFromSearch(search: string): {
|
|
47
|
+
spanSeconds?: number;
|
|
48
|
+
paused?: boolean;
|
|
49
|
+
};
|
|
50
|
+
export declare function presetIdOf(spanSeconds: number): TimeRangePresetId | undefined;
|
|
51
|
+
export declare function spanLabel(spanSeconds: number): string;
|
|
52
|
+
export declare function setBoardTimeRange(def: DashboardDefinition, defaultSeconds: number | undefined): DashboardDefinition;
|
package/dist/types.d.ts
CHANGED
|
@@ -49,20 +49,77 @@ export interface UnboundSelector {
|
|
|
49
49
|
location?: LocationSelection;
|
|
50
50
|
}
|
|
51
51
|
export type DatasourceSelector = DeviceSelector | AnchorSelector | DevicesSelector | RelatedTraversalSelector | SlotSelector | UnboundSelector;
|
|
52
|
-
export declare const WIDGET_TYPES: readonly ['timeseries-chart', 'latest-card', 'gauge', 'table', 'label', 'image', 'alarm-table', 'alarm-count', 'command-button', 'entity-selector', 'map'];
|
|
52
|
+
export declare const WIDGET_TYPES: readonly ['timeseries-chart', 'latest-card', 'gauge', 'table', 'label', 'image', 'alarm-table', 'alarm-count', 'command-button', 'entity-selector', 'map', 'linear-gauge', 'level-gauge', 'battery', 'status-light', 'signal-bars', 'compass', 'progress-ring', 'command-slider', 'command-toggle', 'stat-card', 'bar-chart', 'pie-chart', 'fleet-table'];
|
|
53
53
|
export type WidgetType = (typeof WIDGET_TYPES)[number];
|
|
54
|
-
export
|
|
54
|
+
export declare const PLACEMENT_ANCHORS: readonly ['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right'];
|
|
55
|
+
export type PlacementAnchor = (typeof PLACEMENT_ANCHORS)[number];
|
|
56
|
+
export declare const PLACEMENT_MODES: readonly ['grid', 'relative'];
|
|
57
|
+
export type PlacementMode = (typeof PLACEMENT_MODES)[number];
|
|
58
|
+
export declare const RESERVED_PLACEMENT_MODES: readonly ['pinned', 'sticky'];
|
|
59
|
+
export interface GridPlacement {
|
|
60
|
+
mode: 'grid';
|
|
55
61
|
col: number;
|
|
56
|
-
colSpan: number;
|
|
57
62
|
row: number;
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
cols: number;
|
|
64
|
+
rows: number;
|
|
65
|
+
}
|
|
66
|
+
export type RelativeSize = {
|
|
67
|
+
cols: number;
|
|
68
|
+
rows: number;
|
|
69
|
+
} | {
|
|
70
|
+
fill: 'host';
|
|
71
|
+
};
|
|
72
|
+
export interface RelativePlacement {
|
|
73
|
+
mode: 'relative';
|
|
74
|
+
host: string;
|
|
75
|
+
anchor: PlacementAnchor;
|
|
76
|
+
self?: PlacementAnchor;
|
|
60
77
|
offset?: {
|
|
61
78
|
x: number;
|
|
62
79
|
y: number;
|
|
63
80
|
};
|
|
81
|
+
size: RelativeSize;
|
|
82
|
+
layer?: number;
|
|
83
|
+
}
|
|
84
|
+
export type Placement = GridPlacement | RelativePlacement;
|
|
85
|
+
export type WidgetLayout = Record<string, Placement>;
|
|
86
|
+
export declare const THEME_COLOR_TOKENS: readonly ['background', 'foreground', 'card', 'card-foreground', 'muted', 'muted-foreground', 'primary', 'primary-foreground', 'border', 'destructive', 'chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5', 'sev-critical', 'sev-major', 'sev-minor', 'sev-warning'];
|
|
87
|
+
export type ThemeColorToken = (typeof THEME_COLOR_TOKENS)[number];
|
|
88
|
+
export declare const SPACE_TOKEN_PX: {
|
|
89
|
+
readonly 'space-0': 0;
|
|
90
|
+
readonly 'space-1': 4;
|
|
91
|
+
readonly 'space-2': 8;
|
|
92
|
+
readonly 'space-3': 12;
|
|
93
|
+
readonly 'space-4': 16;
|
|
94
|
+
};
|
|
95
|
+
export type SpaceTokenName = keyof typeof SPACE_TOKEN_PX;
|
|
96
|
+
export declare const FRAME_VARIANTS: readonly ['card', 'flat', 'none'];
|
|
97
|
+
export type FrameVariant = (typeof FRAME_VARIANTS)[number];
|
|
98
|
+
export declare const FRAME_RADII: readonly ['none', 'sm', 'md', 'lg'];
|
|
99
|
+
export type FrameRadius = (typeof FRAME_RADII)[number];
|
|
100
|
+
export declare const FRAME_BORDER_WIDTHS: readonly [0, 1, 2, 3];
|
|
101
|
+
export type FrameBorderWidth = (typeof FRAME_BORDER_WIDTHS)[number];
|
|
102
|
+
export declare const FRAME_HEADERS: readonly ['auto', 'show', 'hide'];
|
|
103
|
+
export type FrameHeader = (typeof FRAME_HEADERS)[number];
|
|
104
|
+
export interface FrameBorder {
|
|
105
|
+
width?: FrameBorderWidth;
|
|
106
|
+
radius?: FrameRadius;
|
|
107
|
+
color?: ThemeColorToken;
|
|
108
|
+
}
|
|
109
|
+
export interface WidgetFrameSpec {
|
|
110
|
+
variant?: FrameVariant;
|
|
111
|
+
border?: FrameBorder;
|
|
112
|
+
padding?: SpaceTokenName;
|
|
113
|
+
background?: ThemeColorToken | 'transparent';
|
|
114
|
+
header?: FrameHeader;
|
|
115
|
+
}
|
|
116
|
+
export interface ResolvedFrame {
|
|
117
|
+
variant: FrameVariant;
|
|
118
|
+
border: Required<FrameBorder>;
|
|
119
|
+
padding: SpaceTokenName;
|
|
120
|
+
background: ThemeColorToken | 'transparent';
|
|
121
|
+
header: FrameHeader;
|
|
64
122
|
}
|
|
65
|
-
export type WidgetLayout = Record<string, WidgetBox>;
|
|
66
123
|
export declare const UNKNOWN_WIDGET_TYPE = "unknown-widget";
|
|
67
124
|
export type UnknownWidgetType = typeof UNKNOWN_WIDGET_TYPE;
|
|
68
125
|
export interface WidgetImplementationRef {
|
|
@@ -78,6 +135,7 @@ export interface KnownWidgetInstance {
|
|
|
78
135
|
layout: WidgetLayout;
|
|
79
136
|
datasource?: DatasourceSelector;
|
|
80
137
|
options?: Record<string, unknown>;
|
|
138
|
+
frame?: WidgetFrameSpec;
|
|
81
139
|
raw?: undefined;
|
|
82
140
|
reason?: undefined;
|
|
83
141
|
}
|
|
@@ -88,6 +146,7 @@ export interface ExtensionWidgetInstance {
|
|
|
88
146
|
layout: WidgetLayout;
|
|
89
147
|
datasource?: DatasourceSelector;
|
|
90
148
|
options?: Record<string, unknown>;
|
|
149
|
+
frame?: WidgetFrameSpec;
|
|
91
150
|
raw?: undefined;
|
|
92
151
|
reason?: undefined;
|
|
93
152
|
}
|
|
@@ -105,6 +164,7 @@ export interface UnknownWidgetInstance {
|
|
|
105
164
|
widget?: undefined;
|
|
106
165
|
datasource?: undefined;
|
|
107
166
|
options?: undefined;
|
|
167
|
+
frame?: undefined;
|
|
108
168
|
}
|
|
109
169
|
export type WidgetInstance = KnownWidgetInstance | ExtensionWidgetInstance | UnknownWidgetInstance;
|
|
110
170
|
export type ResolvedWidgetInstance = KnownWidgetInstance | ExtensionWidgetInstance;
|
|
@@ -112,25 +172,43 @@ export interface CanvasBackground {
|
|
|
112
172
|
color?: string | null;
|
|
113
173
|
imageUrl?: string | null;
|
|
114
174
|
}
|
|
175
|
+
export type GridLength = number | SpaceTokenName;
|
|
115
176
|
export interface CanvasGrid {
|
|
116
177
|
columns: number;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
178
|
+
minCellSize: number;
|
|
179
|
+
gutter: GridLength | {
|
|
180
|
+
x: GridLength;
|
|
181
|
+
y: GridLength;
|
|
182
|
+
};
|
|
183
|
+
padding: GridLength | {
|
|
184
|
+
top: GridLength;
|
|
185
|
+
right: GridLength;
|
|
186
|
+
bottom: GridLength;
|
|
187
|
+
left: GridLength;
|
|
120
188
|
};
|
|
121
|
-
rowHeight: number;
|
|
122
189
|
}
|
|
123
190
|
export type CanvasSizing = 'fill' | {
|
|
124
191
|
width: number;
|
|
125
192
|
} | {
|
|
126
193
|
height: number;
|
|
127
194
|
};
|
|
128
|
-
export type
|
|
195
|
+
export type BreakpointSpec = number | {
|
|
196
|
+
minWidth: number;
|
|
197
|
+
columns: number;
|
|
198
|
+
};
|
|
199
|
+
export type Breakpoints = Record<string, BreakpointSpec>;
|
|
200
|
+
export declare const CANVAS_DENSITIES: readonly ['compact', 'comfortable', 'wall'];
|
|
201
|
+
export type CanvasDensity = (typeof CANVAS_DENSITIES)[number];
|
|
202
|
+
export declare const DEFAULT_CANVAS_DENSITY: CanvasDensity;
|
|
203
|
+
export declare const DENSITY_SCALE: Readonly<Record<CanvasDensity, number>>;
|
|
204
|
+
export declare function isCanvasDensity(value: unknown): value is CanvasDensity;
|
|
129
205
|
export interface Canvas {
|
|
130
206
|
background?: CanvasBackground;
|
|
207
|
+
density?: CanvasDensity;
|
|
131
208
|
grid: CanvasGrid;
|
|
132
209
|
sizing: CanvasSizing;
|
|
133
210
|
breakpoints: Breakpoints;
|
|
211
|
+
frame?: WidgetFrameSpec;
|
|
134
212
|
}
|
|
135
213
|
export type SlotBinding = {
|
|
136
214
|
kind: 'device';
|
|
@@ -163,12 +241,19 @@ export interface SelectionTarget {
|
|
|
163
241
|
slot: string;
|
|
164
242
|
binding: SlotBinding;
|
|
165
243
|
}
|
|
244
|
+
export declare const CURRENT_SCHEMA_VERSION = 3;
|
|
245
|
+
export interface BoardTimeRange {
|
|
246
|
+
defaultSeconds: number;
|
|
247
|
+
}
|
|
166
248
|
export interface DashboardDefinition {
|
|
167
249
|
schemaVersion: number;
|
|
168
250
|
title: string;
|
|
169
251
|
canvas: Canvas;
|
|
170
252
|
widgets: WidgetInstance[];
|
|
171
253
|
slots?: Record<string, SlotDefinition>;
|
|
254
|
+
timeRange?: BoardTimeRange;
|
|
255
|
+
convertedFrom?: number;
|
|
256
|
+
convertedWindows?: string[];
|
|
172
257
|
}
|
|
173
258
|
export interface MeasurementSample {
|
|
174
259
|
id: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { AlarmStreamState, CommandStreamState, LocationStreamState, MeasurementStreamState } from './channel-snapshots';
|
|
1
|
+
import type { AggregateStreamState, AlarmStreamState, CommandStreamState, LocationStreamState, MeasurementStreamState } from './channel-snapshots';
|
|
2
2
|
import type { DefaultsOf, OptionConstraint, OptionKeysOfKind, WidgetOptionSpecs } from './option-schema';
|
|
3
3
|
import { type WidgetType } from './types';
|
|
4
|
-
export type WidgetChannel = 'measurement' | 'alarm' | 'control' | 'selection' | 'location' | 'none';
|
|
5
|
-
export type ChannelSnapshot<C extends WidgetChannel> = C extends 'measurement' ? MeasurementStreamState : C extends 'alarm' ? AlarmStreamState : C extends 'control' ? CommandStreamState : C extends 'location' ? LocationStreamState : null;
|
|
4
|
+
export type WidgetChannel = 'measurement' | 'alarm' | 'control' | 'selection' | 'location' | 'aggregate' | 'none';
|
|
5
|
+
export type ChannelSnapshot<C extends WidgetChannel> = C extends 'measurement' ? MeasurementStreamState : C extends 'alarm' ? AlarmStreamState : C extends 'control' ? CommandStreamState : C extends 'location' ? LocationStreamState : C extends 'aggregate' ? AggregateStreamState : null;
|
|
6
6
|
export type BuiltinWidgetId = WidgetType;
|
|
7
7
|
export type NamespacedWidgetId = `${string}/${string}`;
|
|
8
8
|
export type WidgetId = BuiltinWidgetId | NamespacedWidgetId;
|
|
@@ -41,8 +41,14 @@ export interface AckOptionRef<S extends WidgetOptionSpecs = WidgetOptionSpecs> {
|
|
|
41
41
|
default?: 'true' | 'false';
|
|
42
42
|
}
|
|
43
43
|
type PageSize<S extends WidgetOptionSpecs> = ConstBinding<number> | NumberOptionRef<S>;
|
|
44
|
-
export type ChannelBindingPolicy<C extends WidgetChannel, S extends WidgetOptionSpecs = WidgetOptionSpecs> = C extends '
|
|
44
|
+
export type ChannelBindingPolicy<C extends WidgetChannel, S extends WidgetOptionSpecs = WidgetOptionSpecs> = C extends 'aggregate' ? {
|
|
45
|
+
windowSeconds?: NumberOptionRef<S>;
|
|
46
|
+
} : C extends 'measurement' ? {
|
|
45
47
|
window?: NumberOptionRef<S>;
|
|
48
|
+
windowSeconds?: NumberOptionRef<S>;
|
|
49
|
+
members?: ConstBinding<true> | (StringOptionRef<S> & {
|
|
50
|
+
equals: string;
|
|
51
|
+
});
|
|
46
52
|
} : C extends 'alarm' ? {
|
|
47
53
|
pageSize: PageSize<S>;
|
|
48
54
|
state?: StringOptionRef<S>;
|
|
@@ -72,6 +78,19 @@ export interface WidgetDisplay {
|
|
|
72
78
|
titleId?: string;
|
|
73
79
|
categoryId?: string;
|
|
74
80
|
}
|
|
81
|
+
export interface WidgetSpan {
|
|
82
|
+
cols: number;
|
|
83
|
+
rows: number;
|
|
84
|
+
}
|
|
85
|
+
export type WidgetResizeMode = 'both' | 'horizontal' | 'vertical' | 'none';
|
|
86
|
+
export interface WidgetLayoutSpec {
|
|
87
|
+
defaultSpan: WidgetSpan;
|
|
88
|
+
minSpan?: WidgetSpan;
|
|
89
|
+
maxSpan?: WidgetSpan;
|
|
90
|
+
resize?: WidgetResizeMode;
|
|
91
|
+
}
|
|
92
|
+
export declare function pinnedAxes(mode: WidgetResizeMode | undefined): readonly ('cols' | 'rows')[];
|
|
93
|
+
export declare const FALLBACK_DEFAULT_SPAN: Readonly<WidgetSpan>;
|
|
75
94
|
export declare const SDK_API_VERSION = 1;
|
|
76
95
|
export interface WidgetDescriptor<C extends WidgetChannel = WidgetChannel, S extends WidgetOptionSpecs = WidgetOptionSpecs> {
|
|
77
96
|
id: WidgetId;
|
|
@@ -86,6 +105,8 @@ export interface WidgetDescriptor<C extends WidgetChannel = WidgetChannel, S ext
|
|
|
86
105
|
constraints?: readonly OptionConstraint<OptionKeysOfKind<S, 'number'>>[];
|
|
87
106
|
defaults: DefaultsOf<S>;
|
|
88
107
|
interactions: InteractionsFor<C>;
|
|
108
|
+
freshness?: true;
|
|
109
|
+
layout?: WidgetLayoutSpec;
|
|
89
110
|
}
|
|
90
111
|
export declare function defineWidgetDescriptor<const C extends WidgetChannel, const S extends WidgetOptionSpecs>(descriptor: WidgetDescriptor<C, S>): WidgetDescriptor<C, S>;
|
|
91
112
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devicechain/dashboards",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0-rc.1",
|
|
4
4
|
"description": "DeviceChain dashboard runtime — the DashboardHub (telemetry subscription multiplexing over the client wire, plus the alarm, command and location channels) and the dashboard-definition, selector, slot, and binding-manifest types.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"devicechain",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"@graphql-typed-document-node/core": "^3.2.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@devicechain/client": "0.
|
|
49
|
+
"@devicechain/client": "0.22.0-rc.1",
|
|
50
50
|
"graphql": "^16.0.0 || ^17.0.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@devicechain/client": "0.
|
|
53
|
+
"@devicechain/client": "0.22.0-rc.1",
|
|
54
54
|
"@types/node": "^26.6.5",
|
|
55
55
|
"graphql": "^17.0.2",
|
|
56
56
|
"typescript": "~7.0.2",
|