@xenosystem/blocks 0.13.9 → 0.13.11
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/data/index.d.ts +141 -21
- package/dist/data/index.js +368 -277
- package/package.json +3 -3
package/dist/data/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PanelModule, PanelManifest, BlockDeclaration, LogSink } from '@xenosystem/block-sdk';
|
|
2
2
|
import * as _xenosystem_data_core from '@xenosystem/data-core';
|
|
3
3
|
import { XenoColumn, XenoQuery, XenoResultSet, XenoValue, XenoRow, XenoAggFn, XenoValueFormat, XenoFilterGroup, XenoColumnRole, XenoSchemaCatalog, XenoFilter, XenoSourceSchema } from '@xenosystem/data-core';
|
|
4
|
-
import { ReactNode } from 'react';
|
|
4
|
+
import { ReactNode, ReactElement } from 'react';
|
|
5
5
|
import { C as ConnectorExecuteInput, a as ConnectorExecuteOutput, b as ConnectorsPanelState, S as SubstrateFacilities, c as ConnectorsViewState, d as XenoConnection, e as XenoCredentialFormSpec, f as XenoCredentialResult, g as XenoConnectionStatus, P as PushdownSplit, h as XenoConnectorQueryRequest, i as XenoRestPaging, j as XenoConnectorFetch, k as XenoResolverErrorCode, l as XenoConnectorFileReader, X as XenoSqlEngine, m as ConnectorTransport, n as XenoCredentialField } from '../transport-B1cdciP8.js';
|
|
6
6
|
export { B as BrowserFetchOptions, o as ConnectorTransportError, p as SECRET_HEADER_NAMES, q as XenoConnectionConfig, r as XenoConnectionHealth, s as XenoConnectionKind, t as XenoConnectionState, u as XenoConnectorCapabilities, v as XenoCredentialSubmission, w as XenoFetchRequest, x as XenoFetchResponse, y as XenoFileReadRequest, z as XenoFileReadResponse, A as XenoRefreshPolicy, D as XenoSqlTable, E as browserFetch, F as classifyBrowserFetchFailure, G as defaultCapabilitiesFor, H as errorResult, I as evaluateSupport, J as facilitiesOf, K as normalizePaging, L as secretHeaderNames } from '../transport-B1cdciP8.js';
|
|
7
7
|
|
|
@@ -1107,25 +1107,79 @@ declare function buildChartData(result: XenoResultSet, encoding: XenoChartEncodi
|
|
|
1107
1107
|
declare function rowsForMark(result: XenoResultSet, encoding: XenoChartEncoding, label: string, seriesId?: string): string[];
|
|
1108
1108
|
|
|
1109
1109
|
/**
|
|
1110
|
-
* The Chart panel
|
|
1110
|
+
* The Chart panel AS A DECLARATION — the thirteenth declared block.
|
|
1111
1111
|
*
|
|
1112
|
-
*
|
|
1113
|
-
*
|
|
1114
|
-
*
|
|
1112
|
+
* Everything drawn is data: the chart-type control, the partial / aggregating badges and the export
|
|
1113
|
+
* button in the toolbar, the four body states (error, no data, nothing to plot, no renderer), the
|
|
1114
|
+
* status bar. The PLOT is the one thing a declaration cannot hold — `chart/Plot` is the runtime-bound
|
|
1115
|
+
* unit: the element the host's renderer (Chart.js or another) draws the marks into, re-rendered
|
|
1116
|
+
* from the controller's data and highlights. The panel ships the model; the host ships the marks.
|
|
1117
|
+
*/
|
|
1118
|
+
|
|
1119
|
+
declare const CHART_TYPE_LABELS: Record<string, string>;
|
|
1120
|
+
declare const DEFAULT_CHART_OPTIONS: ChartRenderOptions;
|
|
1121
|
+
interface ChartViewModel {
|
|
1122
|
+
types: {
|
|
1123
|
+
value: string;
|
|
1124
|
+
label: string;
|
|
1125
|
+
}[];
|
|
1126
|
+
type: string;
|
|
1127
|
+
partial: boolean;
|
|
1128
|
+
aggregating: boolean;
|
|
1129
|
+
aggregatingHint?: string;
|
|
1130
|
+
errorMessage?: string;
|
|
1131
|
+
errored: boolean;
|
|
1132
|
+
empty: boolean;
|
|
1133
|
+
emptyHint: string;
|
|
1134
|
+
unplottable: boolean;
|
|
1135
|
+
encodingProblem?: string;
|
|
1136
|
+
noRenderer: boolean;
|
|
1137
|
+
plot: boolean;
|
|
1138
|
+
countLabel?: string;
|
|
1139
|
+
highlightLabel?: string;
|
|
1140
|
+
}
|
|
1141
|
+
type ChartUiIntent = {
|
|
1142
|
+
kind: 'type';
|
|
1143
|
+
type: XenoChartType;
|
|
1144
|
+
} | {
|
|
1145
|
+
kind: 'export';
|
|
1146
|
+
};
|
|
1147
|
+
interface ChartViewOptions {
|
|
1148
|
+
emptyHint?: string;
|
|
1149
|
+
}
|
|
1150
|
+
/** Derive the view from the live controller — the runtime calls this on every draw. */
|
|
1151
|
+
declare function chartViewState(c: ChartController, options?: ChartViewOptions): ChartViewModel;
|
|
1152
|
+
declare function applyChartUi(c: ChartController, intent: ChartUiIntent): void;
|
|
1153
|
+
declare const chartViewManifest: PanelManifest;
|
|
1154
|
+
declare const BEHAVIOURS$2: {
|
|
1155
|
+
'data/chartPanelView': (inputs: Record<string, unknown>) => ChartViewModel;
|
|
1156
|
+
};
|
|
1157
|
+
/** The runtime-bound unit: the plot surface the host renderer draws into. */
|
|
1158
|
+
declare const CHART_RUNTIME_UNITS: readonly ["chart/Plot"];
|
|
1159
|
+
declare const CHART_DECLARATION: BlockDeclaration;
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* The Chart panel view — the CODE VIEW of `CHART_DECLARATION`, drawing the same `ChartViewModel`
|
|
1163
|
+
* byte-identical (the equivalence suite holds the two together). The one thing this file owns that
|
|
1164
|
+
* the declaration cannot is `chart/Plot`: the element the host renderer draws the marks into.
|
|
1115
1165
|
*
|
|
1116
|
-
*
|
|
1117
|
-
*
|
|
1118
|
-
* was meant to avoid.
|
|
1166
|
+
* Composes `@xenosystem/components/chrome`; the host must ensure `@xenosystem/workbench/primitives.css` is
|
|
1167
|
+
* present.
|
|
1119
1168
|
*
|
|
1120
1169
|
* @module
|
|
1121
1170
|
*/
|
|
1122
1171
|
|
|
1123
1172
|
/** Props for {@link ChartPanelView}. */
|
|
1124
|
-
interface ChartPanelViewProps {
|
|
1173
|
+
interface ChartPanelViewProps extends ChartViewOptions {
|
|
1125
1174
|
controller: ChartController;
|
|
1126
1175
|
options?: Partial<ChartRenderOptions>;
|
|
1127
|
-
emptyHint?: string;
|
|
1128
1176
|
}
|
|
1177
|
+
/** `chart/Plot` — the plot surface. The runtime registers it bound to its controller and render options. */
|
|
1178
|
+
declare function ChartPlot({ controller, options }: {
|
|
1179
|
+
controller: ChartController;
|
|
1180
|
+
options?: Partial<ChartRenderOptions>;
|
|
1181
|
+
}): ReactElement;
|
|
1182
|
+
declare function chartRuntimeComponents(controller: ChartController, options?: Partial<ChartRenderOptions>): Record<(typeof CHART_RUNTIME_UNITS)[number], React.ComponentType<any>>;
|
|
1129
1183
|
/** The Chart panel view. */
|
|
1130
1184
|
declare function ChartPanelView({ controller, options, emptyHint }: ChartPanelViewProps): ReactNode;
|
|
1131
1185
|
|
|
@@ -1401,18 +1455,59 @@ declare const METRICS_PANEL_ID = "xeno.core.metrics";
|
|
|
1401
1455
|
declare const metricsManifest: PanelManifest;
|
|
1402
1456
|
|
|
1403
1457
|
/**
|
|
1404
|
-
* The Metrics panel
|
|
1458
|
+
* The Metrics panel AS A DECLARATION — the twelfth declared block: KPI tiles over a data-core result.
|
|
1405
1459
|
*
|
|
1406
|
-
*
|
|
1407
|
-
*
|
|
1408
|
-
*
|
|
1409
|
-
*
|
|
1410
|
-
*
|
|
1460
|
+
* Everything drawn is data: the range control and partial badge in the toolbar (only when ranges
|
|
1461
|
+
* exist), the error and empty states, a `TileGrid` of `StatTile`s — each with its level badge, its
|
|
1462
|
+
* display value (an em dash for a partial null, never a zero), a `Delta` toned by the metric's
|
|
1463
|
+
* direction, the partial note, the `Sparkline` — and the status bar. A tile activates as a real
|
|
1464
|
+
* button (`StatTile.onActivate`). No runtime-bound unit.
|
|
1411
1465
|
*/
|
|
1412
1466
|
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1467
|
+
interface MetricsViewTile {
|
|
1468
|
+
id: string;
|
|
1469
|
+
label: string;
|
|
1470
|
+
title?: string;
|
|
1471
|
+
value: string;
|
|
1472
|
+
level: string;
|
|
1473
|
+
hasLevel: boolean;
|
|
1474
|
+
tone: 'error' | 'warning';
|
|
1475
|
+
hasDelta: boolean;
|
|
1476
|
+
delta: number;
|
|
1477
|
+
deltaTone: 'good' | 'bad' | 'neutral';
|
|
1478
|
+
partial: boolean;
|
|
1479
|
+
hasSpark: boolean;
|
|
1480
|
+
spark: number[];
|
|
1481
|
+
sparkLabel: string;
|
|
1482
|
+
}
|
|
1483
|
+
interface MetricsViewModel {
|
|
1484
|
+
hasRanges: boolean;
|
|
1485
|
+
ranges: {
|
|
1486
|
+
value: string;
|
|
1487
|
+
label: string;
|
|
1488
|
+
}[];
|
|
1489
|
+
rangeId: string;
|
|
1490
|
+
partial: boolean;
|
|
1491
|
+
partialHint: string;
|
|
1492
|
+
errorMessage?: string;
|
|
1493
|
+
errored: boolean;
|
|
1494
|
+
empty: boolean;
|
|
1495
|
+
emptyHint: string;
|
|
1496
|
+
ready: boolean;
|
|
1497
|
+
layout: 'grid' | 'row' | 'list';
|
|
1498
|
+
columns: number;
|
|
1499
|
+
tiles: MetricsViewTile[];
|
|
1500
|
+
countLabel: string;
|
|
1501
|
+
partialLabel?: string;
|
|
1502
|
+
}
|
|
1503
|
+
type MetricsUiIntent = {
|
|
1504
|
+
kind: 'range';
|
|
1505
|
+
rangeId: string;
|
|
1506
|
+
} | {
|
|
1507
|
+
kind: 'activate';
|
|
1508
|
+
metricId: string;
|
|
1509
|
+
};
|
|
1510
|
+
interface MetricsViewOptions {
|
|
1416
1511
|
layout?: 'grid' | 'row' | 'list';
|
|
1417
1512
|
columns?: number;
|
|
1418
1513
|
sparkline?: boolean;
|
|
@@ -1420,8 +1515,33 @@ interface MetricsPanelViewProps {
|
|
|
1420
1515
|
emptyHint?: string;
|
|
1421
1516
|
partialHint?: string;
|
|
1422
1517
|
}
|
|
1518
|
+
/** Derive the view from the live controller — the runtime calls this on every draw. */
|
|
1519
|
+
declare function metricsViewState(c: MetricsController, options?: MetricsViewOptions): MetricsViewModel;
|
|
1520
|
+
declare function applyMetricsUi(c: MetricsController, intent: MetricsUiIntent): void;
|
|
1521
|
+
declare const metricsViewManifest: PanelManifest;
|
|
1522
|
+
declare const BEHAVIOURS$1: {
|
|
1523
|
+
'data/metricsPanelView': (inputs: Record<string, unknown>) => MetricsViewModel;
|
|
1524
|
+
};
|
|
1525
|
+
declare const METRICS_RUNTIME_UNITS: readonly [];
|
|
1526
|
+
declare const METRICS_DECLARATION: BlockDeclaration;
|
|
1527
|
+
|
|
1528
|
+
/**
|
|
1529
|
+
* The Metrics panel view — the CODE VIEW of `METRICS_DECLARATION`, drawing the same
|
|
1530
|
+
* `MetricsViewModel` byte-identical (the equivalence suite holds the two together). No runtime-bound
|
|
1531
|
+
* unit; every intent goes through `applyMetricsUi`.
|
|
1532
|
+
*
|
|
1533
|
+
* Composes `@xenosystem/components/chrome`; the host must ensure `@xenosystem/workbench/primitives.css` is
|
|
1534
|
+
* present.
|
|
1535
|
+
*
|
|
1536
|
+
* @module
|
|
1537
|
+
*/
|
|
1538
|
+
|
|
1539
|
+
/** Props for {@link MetricsPanelView}. */
|
|
1540
|
+
interface MetricsPanelViewProps extends MetricsViewOptions {
|
|
1541
|
+
controller: MetricsController;
|
|
1542
|
+
}
|
|
1423
1543
|
/** The Metrics panel view. */
|
|
1424
|
-
declare function MetricsPanelView({ controller,
|
|
1544
|
+
declare function MetricsPanelView({ controller, ...options }: MetricsPanelViewProps): ReactNode;
|
|
1425
1545
|
|
|
1426
1546
|
/**
|
|
1427
1547
|
* The `xeno.core.fields` contract — the query AUTHOR.
|
|
@@ -3381,4 +3501,4 @@ interface ConnectorsPanelViewProps {
|
|
|
3381
3501
|
/** The Connectors panel view. */
|
|
3382
3502
|
declare function ConnectorsPanelView({ controller, emptyHint, }: ConnectorsPanelViewProps): ReactNode;
|
|
3383
3503
|
|
|
3384
|
-
export { AGENT_HIDDEN_COMMANDS, ALL_AGGREGATES, ALL_CHART_TYPES, type BuildChartOptions, type BuildSelectOptions, type BuildSelectResult, CHART_EMPTY_FILL, CHART_PALETTE_STEPS, CHART_PANEL_ID, CONNECTORS_PANEL_ID, type CellAddress, ChartController, type ChartControllerOptions, type ChartHostBridge, type ChartPanelState, ChartPanelView, type ChartPanelViewProps, type ChartRenderContext, type ChartRenderInput, type ChartRenderOptions, type ChartRenderer, type ChartViewState, type ColumnLayout, type ColumnWindow, ConnectorExecuteInput, ConnectorExecuteOutput, ConnectorTransport, ConnectorsController, type ConnectorsControllerOptions, type ConnectorsHostBridge, ConnectorsPanelState, ConnectorsPanelView, type ConnectorsPanelViewProps, type ConnectorsRenderContext, ConnectorsViewState, type CreateChartPanelOptions, type CreateConnectorExecutorOptions, type CreateConnectorsPanelOptions, type CreateFieldsPanelOptions, type CreateMetricsPanelOptions, type CreateTablePanelOptions, type CredentialDraft, type CredentialErrors, DEFAULT_COLUMN_WIDTH, DEFAULT_PAGE_SIZE, DEFAULT_RANGES, type DeltaDirection, EMPTY_LAYOUT, EXPIRY_SKEW_MS, type ExecuteError, BEHAVIOURS as FIELDS_BEHAVIOURS, FIELDS_DECLARATION, FIELDS_PANEL_ID, FIELDS_RUNTIME_UNITS, FieldsController, type FieldsControllerOptions, type FieldsHostBridge, type FieldsPanelState, FieldsPanelView, type FieldsPanelViewProps, type FieldsRenderContext, type FieldsUiIntent, type FieldsViewColumn, type FieldsViewEntry, type FieldsViewFilter, type FieldsViewModel, type FieldsViewOptions, type FieldsViewShelf, type FieldsViewState, type HostSqlResolver, IMPLEMENTED_VIEW_MODES, type LoopbackRequest, type LoopbackVerdict, METRICS_PANEL_ID, MIN_COLUMN_WIDTH, MONO_FILL_PALETTE, MONO_PALETTE, MetricsController, type MetricsControllerOptions, type MetricsHostBridge, type MetricsPanelState, MetricsPanelView, type MetricsPanelViewProps, type MetricsRenderContext, type MetricsViewState, type NumericConstraints, type OAuthStateRecord, type OAuthStateStore, type OAuthStateStoreOptions, type ParseCsvOptions, type ParseResult, type ParsedCsv, type PkcePair, PushdownSplit, type RefreshCoordinator, type ResolvedColumn, SHELF_PRESETS, type StoredOAuthToken, SubstrateFacilities, TABLE_PANEL_ID, TableController, type TableControllerOptions, type TableHostBridge, type TablePanelState, TablePanelView, type TablePanelViewProps, type TableRenderContext, type TableViewMode, type TableViewState, type TokenEndpointResponse, type VirtualWindow, type XenoAlertLevel, type XenoCalculatedFieldRequest, type XenoCellEdit, type XenoChartData, type XenoChartDrillDown, type XenoChartEncoding, type XenoChartExportRequest, type XenoChartHighlight, type XenoChartSeries, type XenoChartType, XenoConnection, XenoConnectionStatus, XenoConnectorFetch, XenoConnectorFileReader, XenoConnectorQueryRequest, XenoCredentialField, XenoCredentialFormSpec, XenoCredentialResult, type XenoFieldStat, type XenoMetricAlert, type XenoMetricRange, type XenoMetricSpec, type XenoMetricThreshold, type XenoMetricValue, XenoResolverErrorCode, XenoRestPaging, type XenoRowActivate, type XenoShelfEntry, type XenoShelfSpec, XenoSqlEngine, applyFieldsUi, applyPrecision, base64Url, breachSideOf, buildChartData, buildRestUrl, buildSelect, chartManifest, chartPanel, clamp, classifyHttpStatus, coerceCsvValues, columnIndexAt, columnsOf, compileForHost, computeColumnWindow, computeWindow, connectorsManifest, connectorsPanel, constraintsOfColumn, createChartPanel, createConnectorExecutor, createConnectorsPanel, createFieldsPanel, createMetricsPanel, createOAuthStateStore, createPkcePair, createRefreshCoordinator, createTablePanel, credentialSpecProblem, defaultAggregateFor, defaultEncoding, deltaToneOf, emptyFilterGroup, entityOf, escapeLikePattern, executeCsvFile, executeDuckDb, executeGraphql, executeJsonFile, executeRest, executeSql, extractJsonPath, extractRows, fieldsManifest, fieldsPanel, fieldsViewManifest, fieldsViewState, firstGraphqlError, frozenWidth, getChartRenderer, isCategorical, isFieldVisible, isFilled, isLeafFilter, isLoopbackHost, isSafeTableName, mergeRefreshResponse, metricsManifest, metricsPanel, moveCell, moveColumn, needsRefresh, nextPageToken, normalizeLayout, normalizeNumeric, offerableAggregates, offerableFilterOps, parseCsv, parseJsonBody, parseJsonPath, parseLinkHeader, parseNumeric, pruneHiddenValues, queriesEqual, quoteIdent, quoteLiteral, redirectUriFor, renderFilterGroup, resolveChartColors, resolveColumns, rowsForMark, scrollLeftToReveal, scrollTopToReveal, setChartRenderer, setColumnVisible, setColumnWidth, setFrozenCount, sniffDelimiter, suggestedShelfFor, tableManifest, tablePanel, toChartJsConfig, toExecuteError, totalWidth, uniqueTableName, unsupportedMessage, validateCredentialDraft, validateEncoding, validateLoopbackRequest, visibleFields };
|
|
3504
|
+
export { AGENT_HIDDEN_COMMANDS, ALL_AGGREGATES, ALL_CHART_TYPES, type BuildChartOptions, type BuildSelectOptions, type BuildSelectResult, BEHAVIOURS$2 as CHART_BEHAVIOURS, CHART_DECLARATION, CHART_EMPTY_FILL, CHART_PALETTE_STEPS, CHART_PANEL_ID, CHART_RUNTIME_UNITS, CHART_TYPE_LABELS, CONNECTORS_PANEL_ID, type CellAddress, ChartController, type ChartControllerOptions, type ChartHostBridge, type ChartPanelState, ChartPanelView, type ChartPanelViewProps, ChartPlot, type ChartRenderContext, type ChartRenderInput, type ChartRenderOptions, type ChartRenderer, type ChartUiIntent, type ChartViewModel, type ChartViewOptions, type ChartViewState, type ColumnLayout, type ColumnWindow, ConnectorExecuteInput, ConnectorExecuteOutput, ConnectorTransport, ConnectorsController, type ConnectorsControllerOptions, type ConnectorsHostBridge, ConnectorsPanelState, ConnectorsPanelView, type ConnectorsPanelViewProps, type ConnectorsRenderContext, ConnectorsViewState, type CreateChartPanelOptions, type CreateConnectorExecutorOptions, type CreateConnectorsPanelOptions, type CreateFieldsPanelOptions, type CreateMetricsPanelOptions, type CreateTablePanelOptions, type CredentialDraft, type CredentialErrors, DEFAULT_CHART_OPTIONS, DEFAULT_COLUMN_WIDTH, DEFAULT_PAGE_SIZE, DEFAULT_RANGES, type DeltaDirection, EMPTY_LAYOUT, EXPIRY_SKEW_MS, type ExecuteError, BEHAVIOURS as FIELDS_BEHAVIOURS, FIELDS_DECLARATION, FIELDS_PANEL_ID, FIELDS_RUNTIME_UNITS, FieldsController, type FieldsControllerOptions, type FieldsHostBridge, type FieldsPanelState, FieldsPanelView, type FieldsPanelViewProps, type FieldsRenderContext, type FieldsUiIntent, type FieldsViewColumn, type FieldsViewEntry, type FieldsViewFilter, type FieldsViewModel, type FieldsViewOptions, type FieldsViewShelf, type FieldsViewState, type HostSqlResolver, IMPLEMENTED_VIEW_MODES, type LoopbackRequest, type LoopbackVerdict, BEHAVIOURS$1 as METRICS_BEHAVIOURS, METRICS_DECLARATION, METRICS_PANEL_ID, METRICS_RUNTIME_UNITS, MIN_COLUMN_WIDTH, MONO_FILL_PALETTE, MONO_PALETTE, MetricsController, type MetricsControllerOptions, type MetricsHostBridge, type MetricsPanelState, MetricsPanelView, type MetricsPanelViewProps, type MetricsRenderContext, type MetricsUiIntent, type MetricsViewModel, type MetricsViewOptions, type MetricsViewState, type MetricsViewTile, type NumericConstraints, type OAuthStateRecord, type OAuthStateStore, type OAuthStateStoreOptions, type ParseCsvOptions, type ParseResult, type ParsedCsv, type PkcePair, PushdownSplit, type RefreshCoordinator, type ResolvedColumn, SHELF_PRESETS, type StoredOAuthToken, SubstrateFacilities, TABLE_PANEL_ID, TableController, type TableControllerOptions, type TableHostBridge, type TablePanelState, TablePanelView, type TablePanelViewProps, type TableRenderContext, type TableViewMode, type TableViewState, type TokenEndpointResponse, type VirtualWindow, type XenoAlertLevel, type XenoCalculatedFieldRequest, type XenoCellEdit, type XenoChartData, type XenoChartDrillDown, type XenoChartEncoding, type XenoChartExportRequest, type XenoChartHighlight, type XenoChartSeries, type XenoChartType, XenoConnection, XenoConnectionStatus, XenoConnectorFetch, XenoConnectorFileReader, XenoConnectorQueryRequest, XenoCredentialField, XenoCredentialFormSpec, XenoCredentialResult, type XenoFieldStat, type XenoMetricAlert, type XenoMetricRange, type XenoMetricSpec, type XenoMetricThreshold, type XenoMetricValue, XenoResolverErrorCode, XenoRestPaging, type XenoRowActivate, type XenoShelfEntry, type XenoShelfSpec, XenoSqlEngine, applyChartUi, applyFieldsUi, applyMetricsUi, applyPrecision, base64Url, breachSideOf, buildChartData, buildRestUrl, buildSelect, chartManifest, chartPanel, chartRuntimeComponents, chartViewManifest, chartViewState, clamp, classifyHttpStatus, coerceCsvValues, columnIndexAt, columnsOf, compileForHost, computeColumnWindow, computeWindow, connectorsManifest, connectorsPanel, constraintsOfColumn, createChartPanel, createConnectorExecutor, createConnectorsPanel, createFieldsPanel, createMetricsPanel, createOAuthStateStore, createPkcePair, createRefreshCoordinator, createTablePanel, credentialSpecProblem, defaultAggregateFor, defaultEncoding, deltaToneOf, emptyFilterGroup, entityOf, escapeLikePattern, executeCsvFile, executeDuckDb, executeGraphql, executeJsonFile, executeRest, executeSql, extractJsonPath, extractRows, fieldsManifest, fieldsPanel, fieldsViewManifest, fieldsViewState, firstGraphqlError, frozenWidth, getChartRenderer, isCategorical, isFieldVisible, isFilled, isLeafFilter, isLoopbackHost, isSafeTableName, mergeRefreshResponse, metricsManifest, metricsPanel, metricsViewManifest, metricsViewState, moveCell, moveColumn, needsRefresh, nextPageToken, normalizeLayout, normalizeNumeric, offerableAggregates, offerableFilterOps, parseCsv, parseJsonBody, parseJsonPath, parseLinkHeader, parseNumeric, pruneHiddenValues, queriesEqual, quoteIdent, quoteLiteral, redirectUriFor, renderFilterGroup, resolveChartColors, resolveColumns, rowsForMark, scrollLeftToReveal, scrollTopToReveal, setChartRenderer, setColumnVisible, setColumnWidth, setFrozenCount, sniffDelimiter, suggestedShelfFor, tableManifest, tablePanel, toChartJsConfig, toExecuteError, totalWidth, uniqueTableName, unsupportedMessage, validateCredentialDraft, validateEncoding, validateLoopbackRequest, visibleFields };
|
package/dist/data/index.js
CHANGED
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
} from "../chunk-W4PTX2Y4.js";
|
|
12
12
|
import {
|
|
13
13
|
ChevronGlyph,
|
|
14
|
-
DownloadGlyph,
|
|
15
14
|
PlugGlyph,
|
|
16
15
|
RefreshGlyph,
|
|
17
16
|
SortAscGlyph,
|
|
@@ -198,8 +197,8 @@ function moveCell(from, delta, bounds) {
|
|
|
198
197
|
}
|
|
199
198
|
|
|
200
199
|
// src/data/table/numeric.ts
|
|
201
|
-
function parseNumeric(
|
|
202
|
-
const trimmed = String(
|
|
200
|
+
function parseNumeric(text4) {
|
|
201
|
+
const trimmed = String(text4).trim();
|
|
203
202
|
if (trimmed.length === 0) return { ok: false, reason: "empty" };
|
|
204
203
|
const match = /^[+-]?(\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/.exec(trimmed);
|
|
205
204
|
if (!match) return { ok: false, reason: "nan" };
|
|
@@ -553,11 +552,11 @@ var TableController = class {
|
|
|
553
552
|
return true;
|
|
554
553
|
}
|
|
555
554
|
/** Update the in-flight draft. Emits `editPreview` only when `livePreview` is on. */
|
|
556
|
-
updateDraft(
|
|
555
|
+
updateDraft(text4) {
|
|
557
556
|
if (!this.editing) return;
|
|
558
|
-
this.editing = { ...this.editing, draft:
|
|
557
|
+
this.editing = { ...this.editing, draft: text4 };
|
|
559
558
|
if (this.livePreview) {
|
|
560
|
-
const parsed = this.parseDraft(this.editing.columnId,
|
|
559
|
+
const parsed = this.parseDraft(this.editing.columnId, text4);
|
|
561
560
|
if (parsed.ok) {
|
|
562
561
|
this.host.emit("editPreview", this.buildEdit(this.editing, parsed.value));
|
|
563
562
|
}
|
|
@@ -609,12 +608,12 @@ var TableController = class {
|
|
|
609
608
|
};
|
|
610
609
|
}
|
|
611
610
|
/** Parse a draft according to the column's declared type. */
|
|
612
|
-
parseDraft(columnId,
|
|
611
|
+
parseDraft(columnId, text4) {
|
|
613
612
|
const column = this.columnById(columnId);
|
|
614
|
-
const trimmed =
|
|
613
|
+
const trimmed = text4.trim();
|
|
615
614
|
if (column?.type === "number" || column?.type === "integer" || column?.type === "duration") {
|
|
616
615
|
if (trimmed === "") return { ok: true, value: null };
|
|
617
|
-
const parsed = parseNumeric(
|
|
616
|
+
const parsed = parseNumeric(text4);
|
|
618
617
|
if (!parsed.ok) return { ok: false, reason: parsed.reason };
|
|
619
618
|
return { ok: true, value: normalizeNumeric(parsed.value, constraintsOfColumn(column)) };
|
|
620
619
|
}
|
|
@@ -631,7 +630,7 @@ var TableController = class {
|
|
|
631
630
|
value: trimmed === "" ? [] : trimmed.split(",").map((part) => part.trim()).filter(Boolean)
|
|
632
631
|
};
|
|
633
632
|
}
|
|
634
|
-
return { ok: true, value: trimmed === "" ? null :
|
|
633
|
+
return { ok: true, value: trimmed === "" ? null : text4 };
|
|
635
634
|
}
|
|
636
635
|
rowById(rowId) {
|
|
637
636
|
return this.result?.rows.find((r) => r.id === rowId);
|
|
@@ -2205,16 +2204,7 @@ var chartManifest = {
|
|
|
2205
2204
|
|
|
2206
2205
|
// src/data/chart/react/ChartPanelView.tsx
|
|
2207
2206
|
import { useEffect as useEffect2, useRef as useRef2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2208
|
-
import {
|
|
2209
|
-
Badge as Badge2,
|
|
2210
|
-
EmptyState as EmptyState2,
|
|
2211
|
-
ErrorState as ErrorState2,
|
|
2212
|
-
IconButton as IconButton2,
|
|
2213
|
-
SegmentedControl as SegmentedControl2,
|
|
2214
|
-
StatusBar as StatusBar2,
|
|
2215
|
-
Toolbar as Toolbar2,
|
|
2216
|
-
ToolbarGroup as ToolbarGroup2
|
|
2217
|
-
} from "@xenosystem/components/chrome";
|
|
2207
|
+
import { Badge as Badge2, Column, EmptyState as EmptyState2, ErrorState as ErrorState2, IconButton as IconButton2, PlotSurface, SegmentedControl as SegmentedControl2, StatusBar as StatusBar2, Toolbar as Toolbar2, ToolbarGroup as ToolbarGroup2 } from "@xenosystem/components/chrome";
|
|
2218
2208
|
|
|
2219
2209
|
// src/data/chart/renderer.ts
|
|
2220
2210
|
var renderer = null;
|
|
@@ -2268,19 +2258,102 @@ function shade(index) {
|
|
|
2268
2258
|
return MONO_PALETTE[index % MONO_PALETTE.length];
|
|
2269
2259
|
}
|
|
2270
2260
|
|
|
2261
|
+
// src/data/chart/declaration.ts
|
|
2262
|
+
var CHART_TYPE_LABELS = { bar: "Bar", horizontalBar: "H-Bar", line: "Line", area: "Area", scatter: "Scatter", pie: "Pie", doughnut: "Ring" };
|
|
2263
|
+
var DEFAULT_CHART_OPTIONS = { showLegend: true, showGrid: true, showTooltip: true, stacked: false, smoothing: 0 };
|
|
2264
|
+
function chartViewState(c, options = {}) {
|
|
2265
|
+
const s = c.getState();
|
|
2266
|
+
const errored = !!s.errorMessage;
|
|
2267
|
+
const empty = !errored && s.empty;
|
|
2268
|
+
const unplottable = !errored && !empty && !!s.encodingProblem;
|
|
2269
|
+
const noRenderer = !errored && !empty && !unplottable && !getChartRenderer();
|
|
2270
|
+
return {
|
|
2271
|
+
types: s.allowedTypes.map((t) => ({ value: t, label: CHART_TYPE_LABELS[t] ?? t })),
|
|
2272
|
+
type: s.encoding.type,
|
|
2273
|
+
partial: s.partial,
|
|
2274
|
+
aggregating: !!s.data?.tooDense,
|
|
2275
|
+
aggregatingHint: s.data?.tooDense ? `${s.data.tooDense.points} points exceeds the ${s.data.tooDense.limit} plot limit \u2014 an aggregated query was requested.` : void 0,
|
|
2276
|
+
errorMessage: s.errorMessage ?? void 0,
|
|
2277
|
+
errored,
|
|
2278
|
+
empty,
|
|
2279
|
+
emptyHint: options.emptyHint ?? "Wire a result into this chart to plot it.",
|
|
2280
|
+
unplottable,
|
|
2281
|
+
encodingProblem: s.encodingProblem ?? void 0,
|
|
2282
|
+
noRenderer,
|
|
2283
|
+
plot: !errored && !empty && !unplottable && !noRenderer,
|
|
2284
|
+
countLabel: s.data ? `${s.data.series.length} series \xB7 ${s.data.labels.length} points` : void 0,
|
|
2285
|
+
highlightLabel: s.highlightedRowIds.length > 0 ? `${s.highlightedRowIds.length} highlighted` : void 0
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
function applyChartUi(c, intent) {
|
|
2289
|
+
switch (intent.kind) {
|
|
2290
|
+
case "type":
|
|
2291
|
+
c.setType(intent.type);
|
|
2292
|
+
break;
|
|
2293
|
+
case "export":
|
|
2294
|
+
c.requestExport("png");
|
|
2295
|
+
break;
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
var chartViewManifest = {
|
|
2299
|
+
id: chartManifest.id,
|
|
2300
|
+
version: "1.0.0",
|
|
2301
|
+
title: "Chart",
|
|
2302
|
+
category: "data",
|
|
2303
|
+
layout: { slot: "center" },
|
|
2304
|
+
inputs: [{ id: "view", type: "object", label: "View state", description: "The ChartViewModel the runtime derives from the controller on every draw." }],
|
|
2305
|
+
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind: type | export, \u2026 } \u2014 applied by the runtime to the controller." }],
|
|
2306
|
+
commands: []
|
|
2307
|
+
};
|
|
2308
|
+
var EMPTY = { types: [], type: "bar", partial: false, aggregating: false, errored: false, empty: true, emptyHint: "Wire a result into this chart to plot it.", unplottable: false, noRenderer: false, plot: false };
|
|
2309
|
+
var BEHAVIOURS = {
|
|
2310
|
+
"data/chartPanelView": (inputs) => inputs.view ?? EMPTY
|
|
2311
|
+
};
|
|
2312
|
+
var CHART_RUNTIME_UNITS = ["chart/Plot"];
|
|
2313
|
+
var text = (b) => ({ component: "text", props: { text: b } });
|
|
2314
|
+
var ui = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
|
|
2315
|
+
var CHART_DECLARATION = {
|
|
2316
|
+
format: "xeno.block@1",
|
|
2317
|
+
manifest: chartViewManifest,
|
|
2318
|
+
behaviour: "data/chartPanelView",
|
|
2319
|
+
composition: {
|
|
2320
|
+
component: "chrome/Column",
|
|
2321
|
+
children: [
|
|
2322
|
+
{
|
|
2323
|
+
component: "chrome/Toolbar",
|
|
2324
|
+
props: {
|
|
2325
|
+
left: { node: { component: "chrome/SegmentedControl", props: { size: { value: "sm" }, label: { value: "Chart type" }, options: { input: "view.types" }, value: { input: "view.type" } }, on: { onChange: ui("type", { type: { arg: "" } }) } } },
|
|
2326
|
+
right: {
|
|
2327
|
+
node: {
|
|
2328
|
+
component: "chrome/ToolbarGroup",
|
|
2329
|
+
props: { end: { value: true } },
|
|
2330
|
+
children: [
|
|
2331
|
+
{ component: "chrome/Badge", when: { input: "view.partial" }, props: { tone: { value: "warning" }, title: { value: "Some measures have not synced yet." } }, children: [text({ value: "partial" })] },
|
|
2332
|
+
{ component: "chrome/Badge", when: { input: "view.aggregating" }, props: { tone: { value: "warning" }, title: { input: "view.aggregatingHint" } }, children: [text({ value: "aggregating" })] },
|
|
2333
|
+
{ component: "chrome/IconButton", props: { icon: { node: { component: "icons/Download" } }, label: { value: "Export chart" } }, on: { onClick: ui("export") } }
|
|
2334
|
+
]
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
},
|
|
2339
|
+
{ component: "chrome/ErrorState", when: { input: "view.errored" }, props: { title: { value: "Could not load data" }, message: { input: "view.errorMessage" } } },
|
|
2340
|
+
{ component: "chrome/EmptyState", when: { input: "view.empty" }, props: { title: { value: "No data" }, hint: { input: "view.emptyHint" } } },
|
|
2341
|
+
{ component: "chrome/EmptyState", when: { input: "view.unplottable" }, props: { title: { value: "Nothing to plot" }, hint: { input: "view.encodingProblem" } } },
|
|
2342
|
+
{ component: "chrome/EmptyState", when: { input: "view.noRenderer" }, props: { title: { value: "No renderer installed" }, hint: { value: "Call setChartRenderer() with a Chart.js (or other) renderer \u2014 the panel ships the model, the host ships the marks." } } },
|
|
2343
|
+
{ component: "chart/Plot", when: { input: "view.plot" } },
|
|
2344
|
+
{ component: "chrome/StatusBar", props: { left: { input: "view.countLabel" }, right: { input: "view.highlightLabel" } } }
|
|
2345
|
+
]
|
|
2346
|
+
}
|
|
2347
|
+
};
|
|
2348
|
+
|
|
2271
2349
|
// src/data/chart/react/ChartPanelView.tsx
|
|
2272
2350
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2273
|
-
var
|
|
2274
|
-
|
|
2275
|
-
showGrid: true,
|
|
2276
|
-
showTooltip: true,
|
|
2277
|
-
stacked: false,
|
|
2278
|
-
smoothing: 0
|
|
2279
|
-
};
|
|
2280
|
-
function ChartPanelView({ controller, options, emptyHint }) {
|
|
2351
|
+
var DownloadGlyph = ICONS["icons/Download"];
|
|
2352
|
+
function ChartPlot({ controller, options }) {
|
|
2281
2353
|
const state = useSyncExternalStore2(controller.subscribe, controller.getState, controller.getState);
|
|
2282
2354
|
const plotRef = useRef2(null);
|
|
2283
|
-
const resolved = { ...
|
|
2355
|
+
const resolved = { ...DEFAULT_CHART_OPTIONS, ...options };
|
|
2356
|
+
const resolvedKey = JSON.stringify(resolved);
|
|
2284
2357
|
useEffect2(() => {
|
|
2285
2358
|
const element = plotRef.current;
|
|
2286
2359
|
const renderer2 = getChartRenderer();
|
|
@@ -2293,83 +2366,38 @@ function ChartPanelView({ controller, options, emptyHint }) {
|
|
|
2293
2366
|
highlightedRowIds: state.highlightedRowIds,
|
|
2294
2367
|
onMarkActivate: (label, seriesId) => controller.activateMark(label, seriesId)
|
|
2295
2368
|
});
|
|
2296
|
-
}, [state.data, state.highlightedRowIds, controller,
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
),
|
|
2310
|
-
right: /* @__PURE__ */ jsxs2(ToolbarGroup2, { end: true, children: [
|
|
2311
|
-
state.partial ? /* @__PURE__ */ jsx2(Badge2, { tone: "warning", title: "Some measures have not synced yet.", children: "partial" }) : null,
|
|
2312
|
-
state.data?.tooDense ? /* @__PURE__ */ jsx2(
|
|
2313
|
-
Badge2,
|
|
2314
|
-
{
|
|
2315
|
-
tone: "warning",
|
|
2316
|
-
title: `${state.data.tooDense.points} points exceeds the ${state.data.tooDense.limit} plot limit \u2014 an aggregated query was requested.`,
|
|
2317
|
-
children: "aggregating"
|
|
2318
|
-
}
|
|
2319
|
-
) : null,
|
|
2320
|
-
/* @__PURE__ */ jsx2(
|
|
2321
|
-
IconButton2,
|
|
2322
|
-
{
|
|
2323
|
-
icon: /* @__PURE__ */ jsx2(DownloadGlyph, {}),
|
|
2324
|
-
label: "Export chart",
|
|
2325
|
-
onClick: () => controller.requestExport("png")
|
|
2326
|
-
}
|
|
2327
|
-
)
|
|
2328
|
-
] })
|
|
2329
|
-
}
|
|
2330
|
-
);
|
|
2331
|
-
const body = (() => {
|
|
2332
|
-
if (state.errorMessage) {
|
|
2333
|
-
return /* @__PURE__ */ jsx2(ErrorState2, { title: "Could not load data", message: state.errorMessage });
|
|
2334
|
-
}
|
|
2335
|
-
if (state.empty) {
|
|
2336
|
-
return /* @__PURE__ */ jsx2(EmptyState2, { title: "No data", hint: emptyHint ?? "Wire a result into this chart to plot it." });
|
|
2337
|
-
}
|
|
2338
|
-
if (state.encodingProblem) {
|
|
2339
|
-
return /* @__PURE__ */ jsx2(EmptyState2, { title: "Nothing to plot", hint: state.encodingProblem });
|
|
2340
|
-
}
|
|
2341
|
-
if (!getChartRenderer()) {
|
|
2342
|
-
return /* @__PURE__ */ jsx2(
|
|
2343
|
-
EmptyState2,
|
|
2344
|
-
{
|
|
2345
|
-
title: "No renderer installed",
|
|
2346
|
-
hint: "Call setChartRenderer() with a Chart.js (or other) renderer \u2014 the panel ships the model, the host ships the marks."
|
|
2347
|
-
}
|
|
2348
|
-
);
|
|
2349
|
-
}
|
|
2350
|
-
return /* @__PURE__ */ jsx2("div", { ref: plotRef, style: { flex: "1 1 0", minHeight: 0, position: "relative" } });
|
|
2351
|
-
})();
|
|
2352
|
-
return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
|
|
2353
|
-
toolbar,
|
|
2354
|
-
body,
|
|
2369
|
+
}, [state.data, state.highlightedRowIds, controller, resolvedKey]);
|
|
2370
|
+
return /* @__PURE__ */ jsx2(PlotSurface, { ref: plotRef, label: "Chart" });
|
|
2371
|
+
}
|
|
2372
|
+
function chartRuntimeComponents(controller, options) {
|
|
2373
|
+
return {
|
|
2374
|
+
"chart/Plot": () => /* @__PURE__ */ jsx2(ChartPlot, { controller, options })
|
|
2375
|
+
};
|
|
2376
|
+
}
|
|
2377
|
+
function ChartPanelView({ controller, options, emptyHint }) {
|
|
2378
|
+
useSyncExternalStore2(controller.subscribe, controller.getState, controller.getState);
|
|
2379
|
+
const view = chartViewState(controller, { emptyHint });
|
|
2380
|
+
const ui4 = (intent) => applyChartUi(controller, intent);
|
|
2381
|
+
return /* @__PURE__ */ jsxs2(Column, { children: [
|
|
2355
2382
|
/* @__PURE__ */ jsx2(
|
|
2356
|
-
|
|
2383
|
+
Toolbar2,
|
|
2357
2384
|
{
|
|
2358
|
-
left:
|
|
2359
|
-
right:
|
|
2385
|
+
left: /* @__PURE__ */ jsx2(SegmentedControl2, { size: "sm", label: "Chart type", options: view.types, value: view.type, onChange: (type) => ui4({ kind: "type", type }) }),
|
|
2386
|
+
right: /* @__PURE__ */ jsxs2(ToolbarGroup2, { end: true, children: [
|
|
2387
|
+
view.partial ? /* @__PURE__ */ jsx2(Badge2, { tone: "warning", title: "Some measures have not synced yet.", children: "partial" }) : null,
|
|
2388
|
+
view.aggregating ? /* @__PURE__ */ jsx2(Badge2, { tone: "warning", title: view.aggregatingHint, children: "aggregating" }) : null,
|
|
2389
|
+
/* @__PURE__ */ jsx2(IconButton2, { icon: /* @__PURE__ */ jsx2(DownloadGlyph, {}), label: "Export chart", onClick: () => ui4({ kind: "export" }) })
|
|
2390
|
+
] })
|
|
2360
2391
|
}
|
|
2361
|
-
)
|
|
2392
|
+
),
|
|
2393
|
+
view.errored ? /* @__PURE__ */ jsx2(ErrorState2, { title: "Could not load data", message: view.errorMessage }) : null,
|
|
2394
|
+
view.empty ? /* @__PURE__ */ jsx2(EmptyState2, { title: "No data", hint: view.emptyHint }) : null,
|
|
2395
|
+
view.unplottable ? /* @__PURE__ */ jsx2(EmptyState2, { title: "Nothing to plot", hint: view.encodingProblem }) : null,
|
|
2396
|
+
view.noRenderer ? /* @__PURE__ */ jsx2(EmptyState2, { title: "No renderer installed", hint: "Call setChartRenderer() with a Chart.js (or other) renderer \u2014 the panel ships the model, the host ships the marks." }) : null,
|
|
2397
|
+
view.plot ? /* @__PURE__ */ jsx2(ChartPlot, { controller, options }) : null,
|
|
2398
|
+
/* @__PURE__ */ jsx2(StatusBar2, { left: view.countLabel, right: view.highlightLabel })
|
|
2362
2399
|
] });
|
|
2363
2400
|
}
|
|
2364
|
-
var LABELS = {
|
|
2365
|
-
bar: "Bar",
|
|
2366
|
-
horizontalBar: "H-Bar",
|
|
2367
|
-
line: "Line",
|
|
2368
|
-
area: "Area",
|
|
2369
|
-
scatter: "Scatter",
|
|
2370
|
-
pie: "Pie",
|
|
2371
|
-
doughnut: "Ring"
|
|
2372
|
-
};
|
|
2373
2401
|
|
|
2374
2402
|
// src/data/chart/panel.ts
|
|
2375
2403
|
function createChartPanel(options = {}) {
|
|
@@ -2912,138 +2940,185 @@ var metricsManifest = {
|
|
|
2912
2940
|
import { useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
2913
2941
|
import {
|
|
2914
2942
|
Badge as Badge3,
|
|
2943
|
+
Column as Column2,
|
|
2944
|
+
Delta,
|
|
2915
2945
|
EmptyState as EmptyState3,
|
|
2916
2946
|
ErrorState as ErrorState3,
|
|
2917
2947
|
ScrollArea as ScrollArea2,
|
|
2918
2948
|
SegmentedControl as SegmentedControl3,
|
|
2919
2949
|
Sparkline,
|
|
2950
|
+
Stack,
|
|
2920
2951
|
StatTile,
|
|
2921
2952
|
StatusBar as StatusBar3,
|
|
2953
|
+
Text,
|
|
2954
|
+
TileGrid,
|
|
2922
2955
|
Toolbar as Toolbar3
|
|
2923
2956
|
} from "@xenosystem/components/chrome";
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
{
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2957
|
+
|
|
2958
|
+
// src/data/metrics/declaration.ts
|
|
2959
|
+
function metricsViewState(c, options = {}) {
|
|
2960
|
+
const s = c.getState();
|
|
2961
|
+
const sparkline = options.sparkline ?? true;
|
|
2962
|
+
const showDelta = options.showDelta ?? true;
|
|
2963
|
+
const partialHint = options.partialHint ?? "Some measures have not finished syncing.";
|
|
2964
|
+
const errored = !!s.errorMessage;
|
|
2965
|
+
const empty = !errored && s.metrics.length === 0;
|
|
2966
|
+
return {
|
|
2967
|
+
hasRanges: s.ranges.length > 0,
|
|
2968
|
+
ranges: s.ranges.map((r) => ({ value: r.id, label: r.label })),
|
|
2969
|
+
rangeId: s.rangeId ?? s.ranges[0]?.id ?? "",
|
|
2970
|
+
partial: s.partial,
|
|
2971
|
+
partialHint,
|
|
2972
|
+
errorMessage: s.errorMessage ?? void 0,
|
|
2973
|
+
errored,
|
|
2974
|
+
empty,
|
|
2975
|
+
emptyHint: options.emptyHint ?? "Configure a metric, or wire a result into this panel.",
|
|
2976
|
+
ready: !errored && !empty,
|
|
2977
|
+
layout: options.layout ?? "grid",
|
|
2978
|
+
columns: options.columns ?? 4,
|
|
2979
|
+
tiles: s.metrics.map((metric) => {
|
|
2980
|
+
const level = metric.level === "critical" ? "error" : metric.level === "warn" ? "warning" : void 0;
|
|
2981
|
+
const hasDelta = showDelta && metric.delta !== void 0;
|
|
2982
|
+
const hasSpark = sparkline && !!metric.spark && metric.spark.length > 1;
|
|
2983
|
+
return {
|
|
2984
|
+
id: metric.spec.id,
|
|
2985
|
+
label: metric.spec.label,
|
|
2986
|
+
title: metric.spec.description,
|
|
2987
|
+
// A partial result shows an em dash, never a zero — a zero is a lie the user cannot detect.
|
|
2988
|
+
value: metric.partial && metric.value === null ? "\u2014" : metric.display,
|
|
2989
|
+
level: String(metric.level),
|
|
2990
|
+
hasLevel: level !== void 0,
|
|
2991
|
+
tone: level ?? "warning",
|
|
2992
|
+
hasDelta,
|
|
2993
|
+
delta: metric.delta ?? 0,
|
|
2994
|
+
deltaTone: metric.deltaTone,
|
|
2995
|
+
partial: metric.partial === true,
|
|
2996
|
+
hasSpark,
|
|
2997
|
+
spark: hasSpark ? metric.spark : [],
|
|
2998
|
+
sparkLabel: `${metric.spec.label} trend`
|
|
2999
|
+
};
|
|
3000
|
+
}),
|
|
3001
|
+
countLabel: `${s.metrics.length} metric${s.metrics.length === 1 ? "" : "s"}`,
|
|
3002
|
+
partialLabel: s.partial ? partialHint : void 0
|
|
3003
|
+
};
|
|
3004
|
+
}
|
|
3005
|
+
function applyMetricsUi(c, intent) {
|
|
3006
|
+
switch (intent.kind) {
|
|
3007
|
+
case "range":
|
|
3008
|
+
c.setRange(intent.rangeId);
|
|
3009
|
+
break;
|
|
3010
|
+
case "activate":
|
|
3011
|
+
c.activate(intent.metricId);
|
|
3012
|
+
break;
|
|
2971
3013
|
}
|
|
2972
|
-
const gridStyle = layout === "grid" ? { display: "grid", gridTemplateColumns: `repeat(${Math.max(1, columns)}, minmax(0, 1fr))`, gap: 6 } : layout === "row" ? { display: "flex", gap: 6, overflowX: "auto" } : { display: "flex", flexDirection: "column", gap: 6 };
|
|
2973
|
-
return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
|
|
2974
|
-
toolbar,
|
|
2975
|
-
/* @__PURE__ */ jsx3(ScrollArea2, { children: /* @__PURE__ */ jsx3("div", { style: { ...gridStyle, padding: 6 }, children: state.metrics.map((metric) => /* @__PURE__ */ jsx3(
|
|
2976
|
-
Tile,
|
|
2977
|
-
{
|
|
2978
|
-
metric,
|
|
2979
|
-
sparkline,
|
|
2980
|
-
showDelta,
|
|
2981
|
-
partialHint,
|
|
2982
|
-
onActivate: () => controller.activate(metric.spec.id)
|
|
2983
|
-
},
|
|
2984
|
-
metric.spec.id
|
|
2985
|
-
)) }) }),
|
|
2986
|
-
/* @__PURE__ */ jsx3(
|
|
2987
|
-
StatusBar3,
|
|
2988
|
-
{
|
|
2989
|
-
left: `${state.metrics.length} metric${state.metrics.length === 1 ? "" : "s"}`,
|
|
2990
|
-
right: state.partial ? partialHint : void 0
|
|
2991
|
-
}
|
|
2992
|
-
)
|
|
2993
|
-
] });
|
|
2994
3014
|
}
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3015
|
+
var metricsViewManifest = {
|
|
3016
|
+
id: metricsManifest.id,
|
|
3017
|
+
version: "1.0.0",
|
|
3018
|
+
title: "Metrics",
|
|
3019
|
+
category: "data",
|
|
3020
|
+
layout: { slot: "center" },
|
|
3021
|
+
inputs: [{ id: "view", type: "object", label: "View state", description: "The MetricsViewModel the runtime derives from the controller on every draw." }],
|
|
3022
|
+
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind: range | activate, \u2026 } \u2014 applied by the runtime to the controller." }],
|
|
3023
|
+
commands: []
|
|
3024
|
+
};
|
|
3025
|
+
var EMPTY2 = { hasRanges: false, ranges: [], rangeId: "", partial: false, partialHint: "", errored: false, empty: true, emptyHint: "Configure a metric, or wire a result into this panel.", ready: false, layout: "grid", columns: 4, tiles: [], countLabel: "0 metrics" };
|
|
3026
|
+
var BEHAVIOURS2 = {
|
|
3027
|
+
"data/metricsPanelView": (inputs) => inputs.view ?? EMPTY2
|
|
3028
|
+
};
|
|
3029
|
+
var METRICS_RUNTIME_UNITS = [];
|
|
3030
|
+
var text2 = (b) => ({ component: "text", props: { text: b } });
|
|
3031
|
+
var ui2 = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
|
|
3032
|
+
var METRICS_DECLARATION = {
|
|
3033
|
+
format: "xeno.block@1",
|
|
3034
|
+
manifest: metricsViewManifest,
|
|
3035
|
+
behaviour: "data/metricsPanelView",
|
|
3036
|
+
composition: {
|
|
3037
|
+
component: "chrome/Column",
|
|
3038
|
+
children: [
|
|
3039
|
+
{
|
|
3040
|
+
component: "chrome/Toolbar",
|
|
3041
|
+
when: { input: "view.hasRanges" },
|
|
3042
|
+
props: {
|
|
3043
|
+
left: { node: { component: "chrome/SegmentedControl", props: { size: { value: "sm" }, label: { value: "Range" }, options: { input: "view.ranges" }, value: { input: "view.rangeId" } }, on: { onChange: ui2("range", { rangeId: { arg: "" } }) } } },
|
|
3044
|
+
right: { node: { component: "chrome/Badge", when: { input: "view.partial" }, props: { tone: { value: "warning" }, title: { input: "view.partialHint" } }, children: [text2({ value: "partial" })] } }
|
|
3013
3045
|
}
|
|
3014
3046
|
},
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
"span",
|
|
3047
|
+
{ component: "chrome/ErrorState", when: { input: "view.errored" }, props: { title: { value: "Could not load metrics" }, message: { input: "view.errorMessage" } } },
|
|
3048
|
+
{ component: "chrome/EmptyState", when: { input: "view.empty" }, props: { title: { value: "No metrics" }, hint: { input: "view.emptyHint" } } },
|
|
3049
|
+
{
|
|
3050
|
+
component: "chrome/ScrollArea",
|
|
3051
|
+
when: { input: "view.ready" },
|
|
3052
|
+
children: [
|
|
3053
|
+
{
|
|
3054
|
+
component: "chrome/TileGrid",
|
|
3055
|
+
props: { layout: { input: "view.layout" }, columns: { input: "view.columns" } },
|
|
3056
|
+
children: [
|
|
3026
3057
|
{
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3058
|
+
component: "chrome/StatTile",
|
|
3059
|
+
each: { input: "view.tiles", key: "id" },
|
|
3060
|
+
props: {
|
|
3061
|
+
title: { item: "title" },
|
|
3062
|
+
label: { item: "label" },
|
|
3063
|
+
value: { item: "value" },
|
|
3064
|
+
icon: { node: { component: "chrome/Badge", when: { item: "hasLevel" }, props: { tone: { item: "tone" } }, children: [text2({ item: "level" })] } },
|
|
3065
|
+
sub: {
|
|
3066
|
+
node: {
|
|
3067
|
+
component: "chrome/Stack",
|
|
3068
|
+
props: { direction: { value: "row" }, pad: { value: "none" } },
|
|
3069
|
+
children: [
|
|
3070
|
+
{ component: "chrome/Delta", when: { item: "hasDelta" }, props: { value: { item: "delta" }, tone: { item: "deltaTone" } } },
|
|
3071
|
+
{ component: "chrome/Text", when: { item: "partial" }, props: { role: { value: "meta" } }, children: [text2({ input: "view.partialHint" })] },
|
|
3072
|
+
{ component: "chrome/Sparkline", when: { item: "hasSpark" }, props: { data: { item: "spark" }, label: { item: "sparkLabel" } } }
|
|
3073
|
+
]
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3031
3076
|
},
|
|
3032
|
-
|
|
3033
|
-
metric.delta > 0 ? "\u25B2" : "\u25BC",
|
|
3034
|
-
" ",
|
|
3035
|
-
Math.abs(metric.delta * 100).toFixed(1),
|
|
3036
|
-
"%"
|
|
3037
|
-
]
|
|
3077
|
+
on: { onActivate: ui2("activate", { metricId: { item: "id" } }) }
|
|
3038
3078
|
}
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3079
|
+
]
|
|
3080
|
+
}
|
|
3081
|
+
]
|
|
3082
|
+
},
|
|
3083
|
+
{ component: "chrome/StatusBar", when: { input: "view.ready" }, props: { left: { input: "view.countLabel" }, right: { input: "view.partialLabel" } } }
|
|
3084
|
+
]
|
|
3085
|
+
}
|
|
3086
|
+
};
|
|
3087
|
+
|
|
3088
|
+
// src/data/metrics/react/MetricsPanelView.tsx
|
|
3089
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3090
|
+
function MetricsPanelView({ controller, ...options }) {
|
|
3091
|
+
useSyncExternalStore3(controller.subscribe, controller.getState, controller.getState);
|
|
3092
|
+
const view = metricsViewState(controller, options);
|
|
3093
|
+
const ui4 = (intent) => applyMetricsUi(controller, intent);
|
|
3094
|
+
return /* @__PURE__ */ jsxs3(Column2, { children: [
|
|
3095
|
+
view.hasRanges ? /* @__PURE__ */ jsx3(
|
|
3096
|
+
Toolbar3,
|
|
3097
|
+
{
|
|
3098
|
+
left: /* @__PURE__ */ jsx3(SegmentedControl3, { size: "sm", label: "Range", options: view.ranges, value: view.rangeId, onChange: (rangeId) => ui4({ kind: "range", rangeId }) }),
|
|
3099
|
+
right: view.partial ? /* @__PURE__ */ jsx3(Badge3, { tone: "warning", title: view.partialHint, children: "partial" }) : null
|
|
3100
|
+
}
|
|
3101
|
+
) : null,
|
|
3102
|
+
view.errored ? /* @__PURE__ */ jsx3(ErrorState3, { title: "Could not load metrics", message: view.errorMessage }) : null,
|
|
3103
|
+
view.empty ? /* @__PURE__ */ jsx3(EmptyState3, { title: "No metrics", hint: view.emptyHint }) : null,
|
|
3104
|
+
view.ready ? /* @__PURE__ */ jsx3(ScrollArea2, { children: /* @__PURE__ */ jsx3(TileGrid, { layout: view.layout, columns: view.columns, children: view.tiles.map((tile) => /* @__PURE__ */ jsx3(
|
|
3105
|
+
StatTile,
|
|
3106
|
+
{
|
|
3107
|
+
title: tile.title,
|
|
3108
|
+
label: tile.label,
|
|
3109
|
+
value: tile.value,
|
|
3110
|
+
icon: tile.hasLevel ? /* @__PURE__ */ jsx3(Badge3, { tone: tile.tone, children: tile.level }) : null,
|
|
3111
|
+
sub: /* @__PURE__ */ jsxs3(Stack, { direction: "row", pad: "none", children: [
|
|
3112
|
+
tile.hasDelta ? /* @__PURE__ */ jsx3(Delta, { value: tile.delta, tone: tile.deltaTone }) : null,
|
|
3113
|
+
tile.partial ? /* @__PURE__ */ jsx3(Text, { role: "meta", children: view.partialHint }) : null,
|
|
3114
|
+
tile.hasSpark ? /* @__PURE__ */ jsx3(Sparkline, { data: tile.spark, label: tile.sparkLabel }) : null
|
|
3115
|
+
] }),
|
|
3116
|
+
onActivate: () => ui4({ kind: "activate", metricId: tile.id })
|
|
3117
|
+
},
|
|
3118
|
+
tile.id
|
|
3119
|
+
)) }) }) : null,
|
|
3120
|
+
view.ready ? /* @__PURE__ */ jsx3(StatusBar3, { left: view.countLabel, right: view.partialLabel }) : null
|
|
3121
|
+
] });
|
|
3047
3122
|
}
|
|
3048
3123
|
|
|
3049
3124
|
// src/data/metrics/panel.ts
|
|
@@ -3240,7 +3315,7 @@ function emptyFilterGroup() {
|
|
|
3240
3315
|
function offerableFilterOps(column, sourceOps = []) {
|
|
3241
3316
|
const common = ["eq", "ne", "isEmpty", "isNotEmpty", "in", "notIn"];
|
|
3242
3317
|
const ordered = ["gt", "gte", "lt", "lte", "between"];
|
|
3243
|
-
const
|
|
3318
|
+
const text4 = ["contains", "notContains", "startsWith", "endsWith"];
|
|
3244
3319
|
const temporal = ["relative"];
|
|
3245
3320
|
let ops = [...common];
|
|
3246
3321
|
switch (column?.type) {
|
|
@@ -3258,10 +3333,10 @@ function offerableFilterOps(column, sourceOps = []) {
|
|
|
3258
3333
|
case "url":
|
|
3259
3334
|
case "select":
|
|
3260
3335
|
case "multiselect":
|
|
3261
|
-
ops = [...ops, ...
|
|
3336
|
+
ops = [...ops, ...text4];
|
|
3262
3337
|
break;
|
|
3263
3338
|
default:
|
|
3264
|
-
ops = [...ops, ...
|
|
3339
|
+
ops = [...ops, ...text4, ...ordered];
|
|
3265
3340
|
}
|
|
3266
3341
|
if (sourceOps.length === 0) return ops;
|
|
3267
3342
|
return ops.filter((op) => sourceOps.includes(op));
|
|
@@ -3892,7 +3967,7 @@ var fieldsManifest = {
|
|
|
3892
3967
|
import { useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
3893
3968
|
import {
|
|
3894
3969
|
Badge as Badge4,
|
|
3895
|
-
Column,
|
|
3970
|
+
Column as Column3,
|
|
3896
3971
|
EmptyState as EmptyState4,
|
|
3897
3972
|
IconButton as IconButton3,
|
|
3898
3973
|
Note,
|
|
@@ -4027,13 +4102,13 @@ var fieldsViewManifest = {
|
|
|
4027
4102
|
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, \u2026 } \u2014 applied by the runtime to the controller." }],
|
|
4028
4103
|
commands: []
|
|
4029
4104
|
};
|
|
4030
|
-
var
|
|
4031
|
-
var
|
|
4032
|
-
"data/fieldsPanelView": (inputs) => inputs.view ??
|
|
4105
|
+
var EMPTY3 = { hasColumns: false, noColumns: true, sampled: false, manualApply: false, applyDisabled: true, columns: [], shelves: [], filters: [], filterCount: 0, hasFilters: false, noFilters: true, combinator: "and", countLabel: "0 fields" };
|
|
4106
|
+
var BEHAVIOURS3 = {
|
|
4107
|
+
"data/fieldsPanelView": (inputs) => inputs.view ?? EMPTY3
|
|
4033
4108
|
};
|
|
4034
4109
|
var FIELDS_RUNTIME_UNITS = [];
|
|
4035
|
-
var
|
|
4036
|
-
var
|
|
4110
|
+
var text3 = (b) => ({ component: "text", props: { text: b } });
|
|
4111
|
+
var ui3 = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
|
|
4037
4112
|
var removeButton = (label, on) => ({
|
|
4038
4113
|
component: "chrome/IconButton",
|
|
4039
4114
|
props: { size: { value: "sm" }, icon: { node: { component: "icons/Close", props: { size: { value: 11 } } } }, label },
|
|
@@ -4054,14 +4129,14 @@ var FIELDS_DECLARATION = {
|
|
|
4054
4129
|
{
|
|
4055
4130
|
component: "chrome/Toolbar",
|
|
4056
4131
|
props: {
|
|
4057
|
-
left: { node: { component: "chrome/Badge", when: { input: "view.sampled" }, props: { tone: { value: "warning" }, title: { input: "view.sampleWarning" } }, children: [
|
|
4132
|
+
left: { node: { component: "chrome/Badge", when: { input: "view.sampled" }, props: { tone: { value: "warning" }, title: { input: "view.sampleWarning" } }, children: [text3({ value: "sampled schema" })] } },
|
|
4058
4133
|
right: {
|
|
4059
4134
|
node: {
|
|
4060
4135
|
component: "chrome/ToolbarGroup",
|
|
4061
4136
|
props: { end: { value: true } },
|
|
4062
4137
|
children: [
|
|
4063
|
-
{ component: "chrome/TextButton", on: { onClick:
|
|
4064
|
-
{ component: "chrome/TextButton", when: { input: "view.manualApply" }, props: { strong: { value: true }, disabled: { input: "view.applyDisabled" } }, on: { onClick:
|
|
4138
|
+
{ component: "chrome/TextButton", on: { onClick: ui3("autoAssign") }, children: [text3({ value: "Auto-assign" })] },
|
|
4139
|
+
{ component: "chrome/TextButton", when: { input: "view.manualApply" }, props: { strong: { value: true }, disabled: { input: "view.applyDisabled" } }, on: { onClick: ui3("apply") }, children: [text3({ value: "Apply" })] }
|
|
4065
4140
|
]
|
|
4066
4141
|
}
|
|
4067
4142
|
}
|
|
@@ -4081,8 +4156,8 @@ var FIELDS_DECLARATION = {
|
|
|
4081
4156
|
{
|
|
4082
4157
|
component: "chrome/Row",
|
|
4083
4158
|
each: { input: "view.columns", key: "id" },
|
|
4084
|
-
props: { label: { item: "name" }, meta: { item: "role" }, selected: { item: "focused" }, trailing: { node: { component: "chrome/Badge", when: { item: "stat" }, props: { title: { item: "statTitle" } }, children: [
|
|
4085
|
-
on: { onClick:
|
|
4159
|
+
props: { label: { item: "name" }, meta: { item: "role" }, selected: { item: "focused" }, trailing: { node: { component: "chrome/Badge", when: { item: "stat" }, props: { title: { item: "statTitle" } }, children: [text3({ item: "stat" })] } } },
|
|
4160
|
+
on: { onClick: ui3("focus", { columnId: { item: "id" } }) }
|
|
4086
4161
|
}
|
|
4087
4162
|
]
|
|
4088
4163
|
}
|
|
@@ -4091,9 +4166,9 @@ var FIELDS_DECLARATION = {
|
|
|
4091
4166
|
{
|
|
4092
4167
|
component: "chrome/Section",
|
|
4093
4168
|
each: { input: "view.shelves", key: "id" },
|
|
4094
|
-
props: { title: { item: "label" }, flush: { value: true }, badge: { node: { component: "chrome/Badge", when: { item: "hasEntries" }, children: [
|
|
4169
|
+
props: { title: { item: "label" }, flush: { value: true }, badge: { node: { component: "chrome/Badge", when: { item: "hasEntries" }, children: [text3({ item: "count" })] } } },
|
|
4095
4170
|
children: [
|
|
4096
|
-
{ component: "chrome/Note", when: { item: "empty" }, children: [
|
|
4171
|
+
{ component: "chrome/Note", when: { item: "empty" }, children: [text3({ item: "hint" })] },
|
|
4097
4172
|
{
|
|
4098
4173
|
component: "chrome/RowList",
|
|
4099
4174
|
when: { item: "hasEntries" },
|
|
@@ -4108,13 +4183,13 @@ var FIELDS_DECLARATION = {
|
|
|
4108
4183
|
node: {
|
|
4109
4184
|
component: "fragment",
|
|
4110
4185
|
children: [
|
|
4111
|
-
{ component: "chrome/Select", when: { item: "aggregated" }, props: { size: { value: "sm" }, label: { value: "Aggregate" }, options: { item: "aggregates" }, value: { item: "fn" } }, on: { onChange:
|
|
4112
|
-
{ component: "chrome/TextButton", when: { item: "sortable" }, on: { onClick:
|
|
4113
|
-
{ component: "chrome/Badge", when: { item: "granularity" }, children: [
|
|
4186
|
+
{ component: "chrome/Select", when: { item: "aggregated" }, props: { size: { value: "sm" }, label: { value: "Aggregate" }, options: { item: "aggregates" }, value: { item: "fn" } }, on: { onChange: ui3("aggregate", { shelfId: { item: "shelfId" }, columnId: { item: "columnId" }, fn: { arg: "" } }) } },
|
|
4187
|
+
{ component: "chrome/TextButton", when: { item: "sortable" }, on: { onClick: ui3("direction", { shelfId: { item: "shelfId" }, columnId: { item: "columnId" } }) }, children: [text3({ item: "direction" })] },
|
|
4188
|
+
{ component: "chrome/Badge", when: { item: "granularity" }, children: [text3({ item: "granularity" })] }
|
|
4114
4189
|
]
|
|
4115
4190
|
}
|
|
4116
4191
|
},
|
|
4117
|
-
trailing: { node: removeButton({ item: "removeLabel" },
|
|
4192
|
+
trailing: { node: removeButton({ item: "removeLabel" }, ui3("remove", { shelfId: { item: "shelfId" }, columnId: { item: "columnId" } })) }
|
|
4118
4193
|
}
|
|
4119
4194
|
}
|
|
4120
4195
|
]
|
|
@@ -4126,11 +4201,11 @@ var FIELDS_DECLARATION = {
|
|
|
4126
4201
|
props: {
|
|
4127
4202
|
title: { value: "Filters" },
|
|
4128
4203
|
flush: { value: true },
|
|
4129
|
-
badge: { node: { component: "chrome/Badge", when: { input: "view.hasFilters" }, children: [
|
|
4130
|
-
actions: { node: { component: "chrome/IconButton", props: { size: { value: "sm" }, icon: { node: { component: "icons/Plus", props: { size: { value: 11 } } } }, label: { value: "Add filter" } }, on: { onClick:
|
|
4204
|
+
badge: { node: { component: "chrome/Badge", when: { input: "view.hasFilters" }, children: [text3({ input: "view.filterCount" })] } },
|
|
4205
|
+
actions: { node: { component: "chrome/IconButton", props: { size: { value: "sm" }, icon: { node: { component: "icons/Plus", props: { size: { value: 11 } } } }, label: { value: "Add filter" } }, on: { onClick: ui3("addFilter") } } }
|
|
4131
4206
|
},
|
|
4132
4207
|
children: [
|
|
4133
|
-
{ component: "chrome/Note", when: { input: "view.noFilters" }, children: [
|
|
4208
|
+
{ component: "chrome/Note", when: { input: "view.noFilters" }, children: [text3({ value: "No filters. Everything passes." })] },
|
|
4134
4209
|
{
|
|
4135
4210
|
component: "chrome/RowList",
|
|
4136
4211
|
when: { input: "view.hasFilters" },
|
|
@@ -4140,8 +4215,8 @@ var FIELDS_DECLARATION = {
|
|
|
4140
4215
|
each: { input: "view.filters", key: "key" },
|
|
4141
4216
|
props: {
|
|
4142
4217
|
label: { item: "label" },
|
|
4143
|
-
meta: { node: { component: "chrome/Select", when: { item: "leaf" }, props: { size: { value: "sm" }, label: { value: "Operator" }, options: { item: "ops" }, value: { item: "op" } }, on: { onChange:
|
|
4144
|
-
trailing: { node: removeButton({ item: "removeLabel" },
|
|
4218
|
+
meta: { node: { component: "chrome/Select", when: { item: "leaf" }, props: { size: { value: "sm" }, label: { value: "Operator" }, options: { item: "ops" }, value: { item: "op" } }, on: { onChange: ui3("filterOp", { index: { item: "index" }, op: { arg: "" } }) } } },
|
|
4219
|
+
trailing: { node: removeButton({ item: "removeLabel" }, ui3("removeFilter", { index: { item: "index" } })) }
|
|
4145
4220
|
}
|
|
4146
4221
|
}
|
|
4147
4222
|
]
|
|
@@ -4150,8 +4225,8 @@ var FIELDS_DECLARATION = {
|
|
|
4150
4225
|
component: "chrome/Toolbar",
|
|
4151
4226
|
props: {
|
|
4152
4227
|
divided: { value: false },
|
|
4153
|
-
left: { node: { component: "chrome/SegmentedControl", props: { size: { value: "sm" }, label: { value: "Combinator" }, options: { value: COMBINATORS }, value: { input: "view.combinator" } }, on: { onChange:
|
|
4154
|
-
right: { node: { component: "chrome/TextButton", on: { onClick:
|
|
4228
|
+
left: { node: { component: "chrome/SegmentedControl", props: { size: { value: "sm" }, label: { value: "Combinator" }, options: { value: COMBINATORS }, value: { input: "view.combinator" } }, on: { onChange: ui3("combinator", { combinator: { arg: "" } }) } } },
|
|
4229
|
+
right: { node: { component: "chrome/TextButton", on: { onClick: ui3("addGroup") }, children: [text3({ value: "+ group" })] } }
|
|
4155
4230
|
}
|
|
4156
4231
|
}
|
|
4157
4232
|
]
|
|
@@ -4173,18 +4248,18 @@ var COMBINATORS2 = [{ value: "and", label: "All" }, { value: "or", label: "Any"
|
|
|
4173
4248
|
function FieldsPanelView({ controller, showStats, manualApply }) {
|
|
4174
4249
|
useSyncExternalStore4(controller.subscribe, controller.getState, controller.getState);
|
|
4175
4250
|
const view = fieldsViewState(controller, { showStats, manualApply });
|
|
4176
|
-
const
|
|
4251
|
+
const ui4 = (intent) => applyFieldsUi(controller, intent);
|
|
4177
4252
|
if (view.noColumns) {
|
|
4178
4253
|
return /* @__PURE__ */ jsx4(EmptyState4, { title: "No fields", hint: "Connect a source \u2014 its columns appear here, ready to drop onto a shelf." });
|
|
4179
4254
|
}
|
|
4180
|
-
return /* @__PURE__ */ jsxs4(
|
|
4255
|
+
return /* @__PURE__ */ jsxs4(Column3, { children: [
|
|
4181
4256
|
/* @__PURE__ */ jsx4(
|
|
4182
4257
|
Toolbar4,
|
|
4183
4258
|
{
|
|
4184
4259
|
left: view.sampled ? /* @__PURE__ */ jsx4(Badge4, { tone: "warning", title: view.sampleWarning, children: "sampled schema" }) : null,
|
|
4185
4260
|
right: /* @__PURE__ */ jsxs4(ToolbarGroup3, { end: true, children: [
|
|
4186
|
-
/* @__PURE__ */ jsx4(TextButton, { onClick: () =>
|
|
4187
|
-
view.manualApply ? /* @__PURE__ */ jsx4(TextButton, { strong: true, disabled: view.applyDisabled, onClick: () =>
|
|
4261
|
+
/* @__PURE__ */ jsx4(TextButton, { onClick: () => ui4({ kind: "autoAssign" }), children: "Auto-assign" }),
|
|
4262
|
+
view.manualApply ? /* @__PURE__ */ jsx4(TextButton, { strong: true, disabled: view.applyDisabled, onClick: () => ui4({ kind: "apply" }), children: "Apply" }) : null
|
|
4188
4263
|
] })
|
|
4189
4264
|
}
|
|
4190
4265
|
),
|
|
@@ -4196,7 +4271,7 @@ function FieldsPanelView({ controller, showStats, manualApply }) {
|
|
|
4196
4271
|
meta: column.role,
|
|
4197
4272
|
selected: column.focused,
|
|
4198
4273
|
trailing: column.stat ? /* @__PURE__ */ jsx4(Badge4, { title: column.statTitle, children: column.stat }) : null,
|
|
4199
|
-
onClick: () =>
|
|
4274
|
+
onClick: () => ui4({ kind: "focus", columnId: column.id })
|
|
4200
4275
|
},
|
|
4201
4276
|
column.id
|
|
4202
4277
|
)) }) }),
|
|
@@ -4208,11 +4283,11 @@ function FieldsPanelView({ controller, showStats, manualApply }) {
|
|
|
4208
4283
|
label: entry.label,
|
|
4209
4284
|
dimmed: entry.suggested,
|
|
4210
4285
|
meta: /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
4211
|
-
entry.aggregated ? /* @__PURE__ */ jsx4(Select, { size: "sm", label: "Aggregate", options: entry.aggregates, value: entry.fn, onChange: (fn) =>
|
|
4212
|
-
entry.sortable ? /* @__PURE__ */ jsx4(TextButton, { onClick: () =>
|
|
4286
|
+
entry.aggregated ? /* @__PURE__ */ jsx4(Select, { size: "sm", label: "Aggregate", options: entry.aggregates, value: entry.fn, onChange: (fn) => ui4({ kind: "aggregate", shelfId: entry.shelfId, columnId: entry.columnId, fn }) }) : null,
|
|
4287
|
+
entry.sortable ? /* @__PURE__ */ jsx4(TextButton, { onClick: () => ui4({ kind: "direction", shelfId: entry.shelfId, columnId: entry.columnId }), children: entry.direction }) : null,
|
|
4213
4288
|
entry.granularity ? /* @__PURE__ */ jsx4(Badge4, { children: entry.granularity }) : null
|
|
4214
4289
|
] }),
|
|
4215
|
-
trailing: /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(CloseGlyph, { size: 11 }), label: entry.removeLabel, onClick: () =>
|
|
4290
|
+
trailing: /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(CloseGlyph, { size: 11 }), label: entry.removeLabel, onClick: () => ui4({ kind: "remove", shelfId: entry.shelfId, columnId: entry.columnId }) })
|
|
4216
4291
|
},
|
|
4217
4292
|
entry.columnId
|
|
4218
4293
|
)) }) : null
|
|
@@ -4223,15 +4298,15 @@ function FieldsPanelView({ controller, showStats, manualApply }) {
|
|
|
4223
4298
|
title: "Filters",
|
|
4224
4299
|
flush: true,
|
|
4225
4300
|
badge: view.hasFilters ? /* @__PURE__ */ jsx4(Badge4, { children: view.filterCount }) : null,
|
|
4226
|
-
actions: /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(PlusGlyph, { size: 11 }), label: "Add filter", onClick: () =>
|
|
4301
|
+
actions: /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(PlusGlyph, { size: 11 }), label: "Add filter", onClick: () => ui4({ kind: "addFilter" }) }),
|
|
4227
4302
|
children: [
|
|
4228
4303
|
view.noFilters ? /* @__PURE__ */ jsx4(Note, { children: "No filters. Everything passes." }) : null,
|
|
4229
4304
|
view.hasFilters ? /* @__PURE__ */ jsx4(RowList, { children: view.filters.map((filter) => /* @__PURE__ */ jsx4(
|
|
4230
4305
|
Row,
|
|
4231
4306
|
{
|
|
4232
4307
|
label: filter.label,
|
|
4233
|
-
meta: filter.leaf ? /* @__PURE__ */ jsx4(Select, { size: "sm", label: "Operator", options: filter.ops, value: filter.op, onChange: (op) =>
|
|
4234
|
-
trailing: /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(CloseGlyph, { size: 11 }), label: filter.removeLabel, onClick: () =>
|
|
4308
|
+
meta: filter.leaf ? /* @__PURE__ */ jsx4(Select, { size: "sm", label: "Operator", options: filter.ops, value: filter.op, onChange: (op) => ui4({ kind: "filterOp", index: filter.index, op }) }) : null,
|
|
4309
|
+
trailing: /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(CloseGlyph, { size: 11 }), label: filter.removeLabel, onClick: () => ui4({ kind: "removeFilter", index: filter.index }) })
|
|
4235
4310
|
},
|
|
4236
4311
|
filter.key
|
|
4237
4312
|
)) }) : null,
|
|
@@ -4239,8 +4314,8 @@ function FieldsPanelView({ controller, showStats, manualApply }) {
|
|
|
4239
4314
|
Toolbar4,
|
|
4240
4315
|
{
|
|
4241
4316
|
divided: false,
|
|
4242
|
-
left: /* @__PURE__ */ jsx4(SegmentedControl4, { size: "sm", label: "Combinator", options: COMBINATORS2, value: view.combinator, onChange: (combinator) =>
|
|
4243
|
-
right: /* @__PURE__ */ jsx4(TextButton, { onClick: () =>
|
|
4317
|
+
left: /* @__PURE__ */ jsx4(SegmentedControl4, { size: "sm", label: "Combinator", options: COMBINATORS2, value: view.combinator, onChange: (combinator) => ui4({ kind: "combinator", combinator }) }),
|
|
4318
|
+
right: /* @__PURE__ */ jsx4(TextButton, { onClick: () => ui4({ kind: "addGroup" }), children: "+ group" })
|
|
4244
4319
|
}
|
|
4245
4320
|
)
|
|
4246
4321
|
]
|
|
@@ -5376,10 +5451,10 @@ function parseJsonPath(path) {
|
|
|
5376
5451
|
}
|
|
5377
5452
|
return steps;
|
|
5378
5453
|
}
|
|
5379
|
-
function findBracketEnd(
|
|
5454
|
+
function findBracketEnd(text4, start) {
|
|
5380
5455
|
let quote = null;
|
|
5381
|
-
for (let i = start + 1; i <
|
|
5382
|
-
const char =
|
|
5456
|
+
for (let i = start + 1; i < text4.length; i += 1) {
|
|
5457
|
+
const char = text4[i];
|
|
5383
5458
|
if (quote) {
|
|
5384
5459
|
if (char === "\\") i += 1;
|
|
5385
5460
|
else if (char === quote) quote = null;
|
|
@@ -5803,9 +5878,9 @@ function firstGraphqlError(errors) {
|
|
|
5803
5878
|
}
|
|
5804
5879
|
|
|
5805
5880
|
// src/data/connectors/executors/csv.ts
|
|
5806
|
-
function sniffDelimiter(
|
|
5881
|
+
function sniffDelimiter(text4) {
|
|
5807
5882
|
const candidates = [",", ";", " ", "|"];
|
|
5808
|
-
const line = firstLogicalLine(
|
|
5883
|
+
const line = firstLogicalLine(text4);
|
|
5809
5884
|
let best = ",";
|
|
5810
5885
|
let bestCount = 0;
|
|
5811
5886
|
for (const candidate of candidates) {
|
|
@@ -5827,21 +5902,21 @@ function sniffDelimiter(text2) {
|
|
|
5827
5902
|
}
|
|
5828
5903
|
return best;
|
|
5829
5904
|
}
|
|
5830
|
-
function firstLogicalLine(
|
|
5905
|
+
function firstLogicalLine(text4) {
|
|
5831
5906
|
let inQuotes = false;
|
|
5832
|
-
for (let i = 0; i <
|
|
5833
|
-
const char =
|
|
5907
|
+
for (let i = 0; i < text4.length; i += 1) {
|
|
5908
|
+
const char = text4[i];
|
|
5834
5909
|
if (char === '"') {
|
|
5835
|
-
if (inQuotes &&
|
|
5910
|
+
if (inQuotes && text4[i + 1] === '"') i += 1;
|
|
5836
5911
|
else inQuotes = !inQuotes;
|
|
5837
5912
|
} else if ((char === "\n" || char === "\r") && !inQuotes) {
|
|
5838
|
-
return
|
|
5913
|
+
return text4.slice(0, i);
|
|
5839
5914
|
}
|
|
5840
5915
|
}
|
|
5841
|
-
return
|
|
5916
|
+
return text4;
|
|
5842
5917
|
}
|
|
5843
|
-
function parseCsv(
|
|
5844
|
-
const source =
|
|
5918
|
+
function parseCsv(text4, options = {}) {
|
|
5919
|
+
const source = text4.charCodeAt(0) === 65279 ? text4.slice(1) : text4;
|
|
5845
5920
|
const delimiter = options.delimiter && options.delimiter.length > 0 ? options.delimiter : sniffDelimiter(source);
|
|
5846
5921
|
const quote = options.quote && options.quote.length > 0 ? options.quote : '"';
|
|
5847
5922
|
const hasHeader = options.hasHeader ?? true;
|
|
@@ -5876,17 +5951,17 @@ function dedupe(names) {
|
|
|
5876
5951
|
return count === 0 ? name : `${name}_${count + 1}`;
|
|
5877
5952
|
});
|
|
5878
5953
|
}
|
|
5879
|
-
function scanRecords(
|
|
5954
|
+
function scanRecords(text4, delimiter, quote) {
|
|
5880
5955
|
const records = [];
|
|
5881
5956
|
let fields = [];
|
|
5882
5957
|
let field = "";
|
|
5883
5958
|
let inQuotes = false;
|
|
5884
5959
|
let i = 0;
|
|
5885
|
-
while (i <
|
|
5886
|
-
const char =
|
|
5960
|
+
while (i < text4.length) {
|
|
5961
|
+
const char = text4[i];
|
|
5887
5962
|
if (inQuotes) {
|
|
5888
5963
|
if (char === quote) {
|
|
5889
|
-
if (
|
|
5964
|
+
if (text4[i + 1] === quote) {
|
|
5890
5965
|
field += quote;
|
|
5891
5966
|
i += 2;
|
|
5892
5967
|
continue;
|
|
@@ -5904,7 +5979,7 @@ function scanRecords(text2, delimiter, quote) {
|
|
|
5904
5979
|
i += 1;
|
|
5905
5980
|
continue;
|
|
5906
5981
|
}
|
|
5907
|
-
if (
|
|
5982
|
+
if (text4.startsWith(delimiter, i)) {
|
|
5908
5983
|
fields.push(field);
|
|
5909
5984
|
field = "";
|
|
5910
5985
|
i += delimiter.length;
|
|
@@ -5915,7 +5990,7 @@ function scanRecords(text2, delimiter, quote) {
|
|
|
5915
5990
|
records.push(fields);
|
|
5916
5991
|
fields = [];
|
|
5917
5992
|
field = "";
|
|
5918
|
-
i += char === "\r" &&
|
|
5993
|
+
i += char === "\r" && text4[i + 1] === "\n" ? 2 : 1;
|
|
5919
5994
|
continue;
|
|
5920
5995
|
}
|
|
5921
5996
|
field += char;
|
|
@@ -7052,28 +7127,37 @@ export {
|
|
|
7052
7127
|
AGENT_HIDDEN_COMMANDS,
|
|
7053
7128
|
ALL_AGGREGATES,
|
|
7054
7129
|
ALL_CHART_TYPES,
|
|
7130
|
+
BEHAVIOURS as CHART_BEHAVIOURS,
|
|
7131
|
+
CHART_DECLARATION,
|
|
7055
7132
|
CHART_EMPTY_FILL,
|
|
7056
7133
|
CHART_PALETTE_STEPS,
|
|
7057
7134
|
CHART_PANEL_ID,
|
|
7135
|
+
CHART_RUNTIME_UNITS,
|
|
7136
|
+
CHART_TYPE_LABELS,
|
|
7058
7137
|
CONNECTORS_PANEL_ID,
|
|
7059
7138
|
ChartController,
|
|
7060
7139
|
ChartPanelView,
|
|
7140
|
+
ChartPlot,
|
|
7061
7141
|
ConnectorTransportError,
|
|
7062
7142
|
ConnectorsController,
|
|
7063
7143
|
ConnectorsPanelView,
|
|
7144
|
+
DEFAULT_CHART_OPTIONS,
|
|
7064
7145
|
DEFAULT_COLUMN_WIDTH,
|
|
7065
7146
|
DEFAULT_PAGE_SIZE,
|
|
7066
7147
|
DEFAULT_RANGES,
|
|
7067
7148
|
EMPTY_LAYOUT,
|
|
7068
7149
|
EXPIRY_SKEW_MS,
|
|
7069
|
-
|
|
7150
|
+
BEHAVIOURS3 as FIELDS_BEHAVIOURS,
|
|
7070
7151
|
FIELDS_DECLARATION,
|
|
7071
7152
|
FIELDS_PANEL_ID,
|
|
7072
7153
|
FIELDS_RUNTIME_UNITS,
|
|
7073
7154
|
FieldsController,
|
|
7074
7155
|
FieldsPanelView,
|
|
7075
7156
|
IMPLEMENTED_VIEW_MODES,
|
|
7157
|
+
BEHAVIOURS2 as METRICS_BEHAVIOURS,
|
|
7158
|
+
METRICS_DECLARATION,
|
|
7076
7159
|
METRICS_PANEL_ID,
|
|
7160
|
+
METRICS_RUNTIME_UNITS,
|
|
7077
7161
|
MIN_COLUMN_WIDTH,
|
|
7078
7162
|
MONO_FILL_PALETTE,
|
|
7079
7163
|
MONO_PALETTE,
|
|
@@ -7084,7 +7168,9 @@ export {
|
|
|
7084
7168
|
TABLE_PANEL_ID,
|
|
7085
7169
|
TableController,
|
|
7086
7170
|
TablePanelView,
|
|
7171
|
+
applyChartUi,
|
|
7087
7172
|
applyFieldsUi,
|
|
7173
|
+
applyMetricsUi,
|
|
7088
7174
|
applyPrecision,
|
|
7089
7175
|
base64Url,
|
|
7090
7176
|
breachSideOf,
|
|
@@ -7094,6 +7180,9 @@ export {
|
|
|
7094
7180
|
buildSelect,
|
|
7095
7181
|
chartManifest,
|
|
7096
7182
|
chartPanel,
|
|
7183
|
+
chartRuntimeComponents,
|
|
7184
|
+
chartViewManifest,
|
|
7185
|
+
chartViewState,
|
|
7097
7186
|
clamp,
|
|
7098
7187
|
classifyBrowserFetchFailure,
|
|
7099
7188
|
classifyHttpStatus,
|
|
@@ -7150,6 +7239,8 @@ export {
|
|
|
7150
7239
|
mergeRefreshResponse,
|
|
7151
7240
|
metricsManifest,
|
|
7152
7241
|
metricsPanel,
|
|
7242
|
+
metricsViewManifest,
|
|
7243
|
+
metricsViewState,
|
|
7153
7244
|
moveCell,
|
|
7154
7245
|
moveColumn,
|
|
7155
7246
|
needsRefresh,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/blocks",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.11",
|
|
4
4
|
"description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@duckdb/duckdb-wasm": ">=1.28.0",
|
|
66
66
|
"@xenosystem/block-sdk": ">=0.3.4 <1",
|
|
67
|
-
"@xenosystem/components": ">=0.
|
|
67
|
+
"@xenosystem/components": ">=0.21.1 <1",
|
|
68
68
|
"@xenosystem/data-core": "^0.1.0",
|
|
69
69
|
"@xenosystem/elements": ">=0.0.1",
|
|
70
70
|
"@xenosystem/elements-react": ">=0.0.1",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@types/react": "^19.0.0",
|
|
82
82
|
"@types/react-dom": "^19.0.0",
|
|
83
83
|
"@xenosystem/block-sdk": "^0.3.4",
|
|
84
|
-
"@xenosystem/components": "^0.
|
|
84
|
+
"@xenosystem/components": "^0.21.1",
|
|
85
85
|
"@xenosystem/data-core": "^0.1.0",
|
|
86
86
|
"@xenosystem/elements": "0.0.1",
|
|
87
87
|
"@xenosystem/elements-react": "0.0.1",
|