nuxt-ui-tools 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +10 -1
- package/dist/runtime/dashboard/components/block/dashboard-block-state.d.vue.ts +2 -0
- package/dist/runtime/dashboard/components/block/dashboard-block-state.vue +4 -1
- package/dist/runtime/dashboard/components/block/dashboard-block-state.vue.d.ts +2 -0
- package/dist/runtime/dashboard/components/block/dashboard-chips.d.vue.ts +20 -0
- package/dist/runtime/dashboard/components/block/dashboard-chips.vue +42 -0
- package/dist/runtime/dashboard/components/block/dashboard-chips.vue.d.ts +20 -0
- package/dist/runtime/dashboard/components/block/dashboard-series-picker.d.vue.ts +8 -0
- package/dist/runtime/dashboard/components/block/dashboard-series-picker.vue +29 -0
- package/dist/runtime/dashboard/components/block/dashboard-series-picker.vue.d.ts +8 -0
- package/dist/runtime/dashboard/components/block/dashboard-skeleton.d.vue.ts +1 -1
- package/dist/runtime/dashboard/components/block/dashboard-skeleton.vue.d.ts +1 -1
- package/dist/runtime/dashboard/components/block/dashboard-view-scope.d.vue.ts +21 -0
- package/dist/runtime/dashboard/components/block/dashboard-view-scope.vue +12 -0
- package/dist/runtime/dashboard/components/block/dashboard-view-scope.vue.d.ts +21 -0
- package/dist/runtime/dashboard/components/dashboard-alerts.vue +3 -3
- package/dist/runtime/dashboard/components/dashboard-bar-chart.d.vue.ts +14 -3
- package/dist/runtime/dashboard/components/dashboard-bar-chart.vue +30 -9
- package/dist/runtime/dashboard/components/dashboard-bar-chart.vue.d.ts +14 -3
- package/dist/runtime/dashboard/components/dashboard-bars.vue +4 -4
- package/dist/runtime/dashboard/components/dashboard-card.vue +28 -6
- package/dist/runtime/dashboard/components/dashboard-combo-chart.d.vue.ts +6 -1
- package/dist/runtime/dashboard/components/dashboard-combo-chart.vue +13 -3
- package/dist/runtime/dashboard/components/dashboard-combo-chart.vue.d.ts +6 -1
- package/dist/runtime/dashboard/components/dashboard-donut-chart.vue +5 -5
- package/dist/runtime/dashboard/components/dashboard-feed.vue +1 -1
- package/dist/runtime/dashboard/components/dashboard-filter.d.vue.ts +67 -0
- package/dist/runtime/dashboard/components/dashboard-filter.vue +134 -0
- package/dist/runtime/dashboard/components/dashboard-filter.vue.d.ts +67 -0
- package/dist/runtime/dashboard/components/dashboard-filters.d.vue.ts +49 -0
- package/dist/runtime/dashboard/components/dashboard-filters.vue +96 -0
- package/dist/runtime/dashboard/components/dashboard-filters.vue.d.ts +49 -0
- package/dist/runtime/dashboard/components/dashboard-funnel.vue +5 -5
- package/dist/runtime/dashboard/components/dashboard-gauge.vue +3 -3
- package/dist/runtime/dashboard/components/dashboard-grid.d.vue.ts +10 -3
- package/dist/runtime/dashboard/components/dashboard-grid.vue +24 -9
- package/dist/runtime/dashboard/components/dashboard-grid.vue.d.ts +10 -3
- package/dist/runtime/dashboard/components/dashboard-line-chart.d.vue.ts +14 -3
- package/dist/runtime/dashboard/components/dashboard-line-chart.vue +30 -9
- package/dist/runtime/dashboard/components/dashboard-line-chart.vue.d.ts +14 -3
- package/dist/runtime/dashboard/components/dashboard-list.d.vue.ts +3 -0
- package/dist/runtime/dashboard/components/dashboard-list.vue +18 -6
- package/dist/runtime/dashboard/components/dashboard-list.vue.d.ts +3 -0
- package/dist/runtime/dashboard/components/dashboard-page.d.vue.ts +53 -0
- package/dist/runtime/dashboard/components/dashboard-page.vue +156 -0
- package/dist/runtime/dashboard/components/dashboard-page.vue.d.ts +53 -0
- package/dist/runtime/dashboard/components/dashboard-paired-bars.vue +4 -4
- package/dist/runtime/dashboard/components/dashboard-refresh.d.vue.ts +1 -1
- package/dist/runtime/dashboard/components/dashboard-refresh.vue +1 -0
- package/dist/runtime/dashboard/components/dashboard-refresh.vue.d.ts +1 -1
- package/dist/runtime/dashboard/components/dashboard-stack-bar.vue +4 -4
- package/dist/runtime/dashboard/components/dashboard-stat.d.vue.ts +14 -2
- package/dist/runtime/dashboard/components/dashboard-stat.vue +28 -10
- package/dist/runtime/dashboard/components/dashboard-stat.vue.d.ts +14 -2
- package/dist/runtime/dashboard/components/dashboard-stats.vue +3 -3
- package/dist/runtime/dashboard/components/dashboard-table.d.vue.ts +1 -1
- package/dist/runtime/dashboard/components/dashboard-table.vue +3 -3
- package/dist/runtime/dashboard/components/dashboard-table.vue.d.ts +1 -1
- package/dist/runtime/dashboard/components/dashboard-tabs.d.vue.ts +1 -1
- package/dist/runtime/dashboard/components/dashboard-tabs.vue.d.ts +1 -1
- package/dist/runtime/dashboard/components/dashboard-total.d.vue.ts +7 -2
- package/dist/runtime/dashboard/components/dashboard-total.vue +10 -2
- package/dist/runtime/dashboard/components/dashboard-total.vue.d.ts +7 -2
- package/dist/runtime/dashboard/components/dashboard-view-tabs.d.vue.ts +33 -0
- package/dist/runtime/dashboard/components/dashboard-view-tabs.vue +66 -0
- package/dist/runtime/dashboard/components/dashboard-view-tabs.vue.d.ts +33 -0
- package/dist/runtime/dashboard/components/dashboard-widget.vue +1 -1
- package/dist/runtime/dashboard/components/filter/dashboard-filter-menu.d.vue.ts +44 -0
- package/dist/runtime/dashboard/components/filter/dashboard-filter-menu.vue +220 -0
- package/dist/runtime/dashboard/components/filter/dashboard-filter-menu.vue.d.ts +44 -0
- package/dist/runtime/dashboard/composables/use-dashboard-api.d.ts +6 -1
- package/dist/runtime/dashboard/composables/use-dashboard-api.js +29 -6
- package/dist/runtime/dashboard/composables/use-dashboard-block.d.ts +5 -4
- package/dist/runtime/dashboard/composables/use-dashboard-block.js +32 -15
- package/dist/runtime/dashboard/composables/use-dashboard-chart.d.ts +8 -1
- package/dist/runtime/dashboard/composables/use-dashboard-chart.js +16 -4
- package/dist/runtime/dashboard/composables/use-dashboard-context.d.ts +50 -0
- package/dist/runtime/dashboard/composables/use-dashboard-context.js +56 -0
- package/dist/runtime/dashboard/composables/use-dashboard-derived.js +6 -1
- package/dist/runtime/dashboard/composables/use-dashboard-filter-control.d.ts +16 -0
- package/dist/runtime/dashboard/composables/use-dashboard-filter-control.js +161 -0
- package/dist/runtime/dashboard/composables/use-dashboard-filter-scope.d.ts +37 -0
- package/dist/runtime/dashboard/composables/use-dashboard-filter-scope.js +107 -0
- package/dist/runtime/dashboard/composables/use-dashboard-format.d.ts +46 -6
- package/dist/runtime/dashboard/composables/use-dashboard-format.js +51 -8
- package/dist/runtime/dashboard/composables/use-dashboard-options.d.ts +11 -4
- package/dist/runtime/dashboard/composables/use-dashboard-options.js +33 -47
- package/dist/runtime/dashboard/composables/use-dashboard-remote-options.d.ts +8 -5
- package/dist/runtime/dashboard/composables/use-dashboard-remote-options.js +59 -70
- package/dist/runtime/dashboard/composables/use-dashboard-resource.d.ts +15 -4
- package/dist/runtime/dashboard/composables/use-dashboard-resource.js +52 -17
- package/dist/runtime/dashboard/composables/use-dashboard-scope.d.ts +10 -7
- package/dist/runtime/dashboard/composables/use-dashboard-scope.js +26 -16
- package/dist/runtime/dashboard/composables/use-dashboard-series-picker.d.ts +20 -0
- package/dist/runtime/dashboard/composables/use-dashboard-series-picker.js +30 -0
- package/dist/runtime/dashboard/composables/use-dashboard-time.d.ts +2 -0
- package/dist/runtime/dashboard/composables/use-dashboard-time.js +4 -1
- package/dist/runtime/dashboard/composables/use-dashboard-ui.d.ts +12 -2
- package/dist/runtime/dashboard/composables/use-dashboard-ui.js +3 -0
- package/dist/runtime/dashboard/composables/use-dashboard-views.d.ts +15 -3
- package/dist/runtime/dashboard/composables/use-dashboard-views.js +33 -10
- package/dist/runtime/dashboard/composables/use-dashboard.d.ts +18 -12
- package/dist/runtime/dashboard/composables/use-dashboard.js +98 -9
- package/dist/runtime/dashboard/index.d.ts +3 -1
- package/dist/runtime/dashboard/index.js +3 -1
- package/dist/runtime/dashboard/schema/index.d.ts +62 -30
- package/dist/runtime/dashboard/schema/index.js +3 -0
- package/dist/runtime/dashboard/types/blocks.d.ts +30 -4
- package/dist/runtime/dashboard/types/charts.d.ts +2 -2
- package/dist/runtime/dashboard/types/controls.d.ts +123 -0
- package/dist/runtime/dashboard/types/filters.d.ts +236 -0
- package/dist/runtime/dashboard/types/index.d.ts +3 -2
- package/dist/runtime/dashboard/types/page.d.ts +17 -0
- package/dist/runtime/dashboard/types/page.js +0 -0
- package/dist/runtime/dashboard/types/resource.d.ts +66 -28
- package/dist/runtime/dashboard/types/runtime.d.ts +39 -8
- package/dist/runtime/dashboard/types/schema.d.ts +94 -54
- package/dist/runtime/dashboard/types/ui.d.ts +78 -0
- package/dist/runtime/dashboard/utils/builders/dashboard-filters.d.ts +142 -0
- package/dist/runtime/dashboard/utils/builders/dashboard-filters.js +135 -0
- package/dist/runtime/dashboard/utils/charts.d.ts +4 -15
- package/dist/runtime/dashboard/utils/charts.js +26 -28
- package/dist/runtime/dashboard/utils/{params/codecs.d.ts → codecs.d.ts} +2 -2
- package/dist/runtime/dashboard/utils/{params/codecs.js → codecs.js} +1 -1
- package/dist/runtime/dashboard/utils/environment.d.ts +36 -0
- package/dist/runtime/dashboard/utils/environment.js +30 -0
- package/dist/runtime/dashboard/utils/filters.d.ts +44 -0
- package/dist/runtime/dashboard/utils/filters.js +62 -0
- package/dist/runtime/dashboard/utils/format.d.ts +25 -0
- package/dist/runtime/dashboard/utils/format.js +66 -0
- package/dist/runtime/dashboard/utils/grid.d.ts +17 -0
- package/dist/runtime/dashboard/utils/grid.js +14 -0
- package/dist/runtime/dashboard/utils/options.d.ts +3 -1
- package/dist/runtime/dashboard/utils/options.js +6 -0
- package/dist/runtime/dashboard/utils/remote.d.ts +7 -0
- package/dist/runtime/dashboard/utils/remote.js +14 -0
- package/dist/runtime/dashboard/utils/resource.d.ts +16 -7
- package/dist/runtime/dashboard/utils/resource.js +15 -9
- package/dist/runtime/dashboard/utils/schema.d.ts +8 -3
- package/dist/runtime/dashboard/utils/schema.js +9 -4
- package/dist/runtime/dashboard/utils/state.d.ts +11 -6
- package/dist/runtime/dashboard/utils/state.js +10 -5
- package/dist/runtime/dashboard/utils/time.d.ts +2 -0
- package/dist/runtime/dashboard/utils/time.js +11 -1
- package/dist/runtime/dashboard/utils/ui.d.ts +1 -1
- package/dist/runtime/dashboard/utils/ui.js +1 -1
- package/dist/runtime/form/components/root/form.vue +1 -1
- package/dist/runtime/form/fields/card-selection.d.ts +1 -0
- package/dist/runtime/form/fields/card-selection.js +1 -0
- package/dist/runtime/form/fields/checkbox-card/component.vue +3 -1
- package/dist/runtime/form/fields/checkbox-group/component.vue +5 -0
- package/dist/runtime/form/fields/radio/component.vue +10 -0
- package/dist/runtime/form/fields/radio-card/component.vue +3 -1
- package/dist/runtime/form/types/options.d.ts +1 -11
- package/dist/runtime/form/utils/focus.js +1 -1
- package/dist/runtime/i18n/locales/en.js +29 -0
- package/dist/runtime/i18n/locales/fr.js +29 -0
- package/dist/runtime/i18n/types.d.ts +41 -0
- package/dist/runtime/shared/styles/tokens.css +1 -1
- package/dist/runtime/shared/types/query.d.ts +8 -0
- package/dist/runtime/table/types/index.d.ts +1 -0
- package/dist/runtime/table/types/remote-options.d.ts +64 -0
- package/dist/runtime/table/types/remote-options.js +0 -0
- package/dist/runtime/table/types/source.d.ts +10 -1
- package/dist/runtime/table/utils/builders/table-source.d.ts +2 -6
- package/dist/runtime/table/utils/index.d.ts +1 -0
- package/dist/runtime/table/utils/index.js +1 -0
- package/dist/runtime/table/utils/remote-table-options.d.ts +26 -0
- package/dist/runtime/table/utils/remote-table-options.js +88 -0
- package/package.json +4 -1
- package/dist/runtime/dashboard/composables/use-dashboard-param-scope.d.ts +0 -30
- package/dist/runtime/dashboard/composables/use-dashboard-param-scope.js +0 -71
- package/dist/runtime/dashboard/types/options.d.ts +0 -46
- package/dist/runtime/dashboard/types/params.d.ts +0 -115
- package/dist/runtime/dashboard/utils/builders/dashboard-params.d.ts +0 -85
- package/dist/runtime/dashboard/utils/builders/dashboard-params.js +0 -87
- /package/dist/runtime/dashboard/types/{options.js → controls.js} +0 -0
- /package/dist/runtime/dashboard/types/{params.js → filters.js} +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const formatsByLocale = /* @__PURE__ */ new Map();
|
|
2
|
+
const numberFormats = /* @__PURE__ */ new Map();
|
|
3
|
+
const monthFormats = /* @__PURE__ */ new Map();
|
|
4
|
+
export function normalizeDashboardSpaces(text) {
|
|
5
|
+
return text.replaceAll("\u202F", "\xA0");
|
|
6
|
+
}
|
|
7
|
+
export function resolveDashboardNumberFormat(locale, options) {
|
|
8
|
+
const resolvedOptions = withCurrencyShorthand(options);
|
|
9
|
+
const key = `${locale}|${JSON.stringify(resolvedOptions)}`;
|
|
10
|
+
let format = numberFormats.get(key);
|
|
11
|
+
if (!format) {
|
|
12
|
+
format = new Intl.NumberFormat(locale, resolvedOptions);
|
|
13
|
+
numberFormats.set(key, format);
|
|
14
|
+
}
|
|
15
|
+
const resolved = format;
|
|
16
|
+
return (value) => normalizeDashboardSpaces(resolved.format(value));
|
|
17
|
+
}
|
|
18
|
+
function withCurrencyShorthand(options) {
|
|
19
|
+
if (options.currency === void 0 || options.style !== void 0) return options;
|
|
20
|
+
const digits = options.minimumFractionDigits === void 0 && options.maximumFractionDigits === void 0 ? { maximumFractionDigits: 0 } : {};
|
|
21
|
+
return { ...digits, ...options, style: "currency" };
|
|
22
|
+
}
|
|
23
|
+
export function resolveDashboardFormats(locale) {
|
|
24
|
+
const cached = formatsByLocale.get(locale);
|
|
25
|
+
if (cached) return cached;
|
|
26
|
+
const plain = resolveDashboardNumberFormat(locale, { maximumFractionDigits: 1 });
|
|
27
|
+
const compact = resolveDashboardNumberFormat(locale, {
|
|
28
|
+
maximumFractionDigits: 1,
|
|
29
|
+
notation: "compact"
|
|
30
|
+
});
|
|
31
|
+
const percent = resolveDashboardNumberFormat(locale, {
|
|
32
|
+
maximumFractionDigits: 1,
|
|
33
|
+
style: "percent"
|
|
34
|
+
});
|
|
35
|
+
const delta = resolveDashboardNumberFormat(locale, {
|
|
36
|
+
maximumFractionDigits: 1,
|
|
37
|
+
signDisplay: "exceptZero",
|
|
38
|
+
style: "percent"
|
|
39
|
+
});
|
|
40
|
+
const formats = {
|
|
41
|
+
compact,
|
|
42
|
+
decimal: plain,
|
|
43
|
+
delta: (value) => delta(value / 100),
|
|
44
|
+
integer: resolveDashboardNumberFormat(locale, { maximumFractionDigits: 0 }),
|
|
45
|
+
number: (value) => Math.abs(value) >= 1e4 ? compact(value) : plain(value),
|
|
46
|
+
percent: (value) => percent(value / 100),
|
|
47
|
+
ratio: percent,
|
|
48
|
+
signed: resolveDashboardNumberFormat(locale, {
|
|
49
|
+
maximumFractionDigits: 1,
|
|
50
|
+
signDisplay: "exceptZero"
|
|
51
|
+
})
|
|
52
|
+
};
|
|
53
|
+
formatsByLocale.set(locale, formats);
|
|
54
|
+
return formats;
|
|
55
|
+
}
|
|
56
|
+
export function formatDashboardMonth(locale, value, width = "short") {
|
|
57
|
+
const key = `${locale}|${width}`;
|
|
58
|
+
let format = monthFormats.get(key);
|
|
59
|
+
if (!format) {
|
|
60
|
+
format = new Intl.DateTimeFormat(locale, { month: width });
|
|
61
|
+
monthFormats.set(key, format);
|
|
62
|
+
}
|
|
63
|
+
const date = typeof value === "number" ? new Date(2e3, value - 1, 1) : value;
|
|
64
|
+
const text = format.format(date);
|
|
65
|
+
return text.charAt(0).toLocaleUpperCase(locale) + text.slice(1);
|
|
66
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flex item style of one grid cell. Dashboard grids are wrapping flex rows: a cell's basis is the
|
|
3
|
+
* width its `size` spans over the grid's columns (the same widths a CSS grid would give), so rows
|
|
4
|
+
* break where the column count says. When `fill` is on, a row that is not full (a block hidden
|
|
5
|
+
* because its source is disabled, or a short last row) shares the free width between its cells in
|
|
6
|
+
* proportion to their span, so no gap is left.
|
|
7
|
+
*
|
|
8
|
+
* `span` is the resolved column span, `null` for a full-row cell.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveDashboardCellStyle(params: {
|
|
11
|
+
span: number | null;
|
|
12
|
+
columns: number;
|
|
13
|
+
gap: string;
|
|
14
|
+
fill: boolean;
|
|
15
|
+
}): string;
|
|
16
|
+
/** Parses a resolved responsive token (`"8"`) into a positive integer, `null` when unset. */
|
|
17
|
+
export declare function parseDashboardSpan(value: number | string | null | undefined): number | null;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isNumber } from "../../shared/utils/predicate.js";
|
|
2
|
+
export function resolveDashboardCellStyle(params) {
|
|
3
|
+
const columns = Math.max(1, Math.round(params.columns));
|
|
4
|
+
const span = params.span === null || !Number.isFinite(params.span) ? columns : Math.min(columns, Math.max(1, Math.round(params.span)));
|
|
5
|
+
if (span >= columns) return "flex: 1 1 100%; min-width: 0";
|
|
6
|
+
const { gap } = params;
|
|
7
|
+
const basis = `calc((100% - ${columns - 1} * ${gap}) / ${columns} * ${span} + ${span - 1} * ${gap} - 0.02px)`;
|
|
8
|
+
return `flex: ${params.fill ? span : 0} 1 ${basis}; min-width: 0`;
|
|
9
|
+
}
|
|
10
|
+
export function parseDashboardSpan(value) {
|
|
11
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
12
|
+
const parsed = isNumber(value) ? value : Number.parseInt(value, 10);
|
|
13
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
14
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { DashboardOption } from '../types/index.js';
|
|
2
|
-
/** Normalizes a single or multiple
|
|
2
|
+
/** Normalizes a single or multiple filter value to its string keys, in value order. */
|
|
3
3
|
export declare function resolveDashboardOptionValues(value: unknown): string[];
|
|
4
4
|
/** Unique options by value, keeping the first occurrence. */
|
|
5
5
|
export declare function mergeDashboardOptions(...lists: readonly (readonly DashboardOption[])[]): DashboardOption[];
|
|
6
|
+
/** The label contains the search term, ignoring case and diacritics. */
|
|
7
|
+
export declare function matchesDashboardSearch(label: string, term: string): boolean;
|
|
@@ -16,3 +16,9 @@ export function mergeDashboardOptions(...lists) {
|
|
|
16
16
|
}
|
|
17
17
|
return merged;
|
|
18
18
|
}
|
|
19
|
+
function normalizeDashboardSearch(value) {
|
|
20
|
+
return value.normalize("NFD").replaceAll(/[̀-ͯ]/gu, "").toLowerCase().trim();
|
|
21
|
+
}
|
|
22
|
+
export function matchesDashboardSearch(label, term) {
|
|
23
|
+
return normalizeDashboardSearch(label).includes(normalizeDashboardSearch(term));
|
|
24
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { QueryFunctionContext, QueryKey } from '@tanstack/vue-query';
|
|
2
|
+
import type { DashboardRemoteResult } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Settles what a remote option source returned: awaits a promise, or runs a query definition's
|
|
5
|
+
* `queryFn` under the definition's own key (the page is already cached by the caller's query).
|
|
6
|
+
*/
|
|
7
|
+
export declare function runDashboardRemoteResult<TResult>(result: DashboardRemoteResult<TResult>, context: QueryFunctionContext<QueryKey, never>): Promise<TResult>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export async function runDashboardRemoteResult(result, context) {
|
|
2
|
+
if (!("queryKey" in result)) return result;
|
|
3
|
+
if (!result.queryFn) {
|
|
4
|
+
throw new Error(
|
|
5
|
+
"[dashboard] Remote option sources returning a query definition need a queryFn."
|
|
6
|
+
);
|
|
7
|
+
}
|
|
8
|
+
return result.queryFn({
|
|
9
|
+
...context,
|
|
10
|
+
direction: "forward",
|
|
11
|
+
pageParam: null,
|
|
12
|
+
queryKey: result.queryKey
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import type { ShallowRef } from 'vue';
|
|
2
2
|
import type { useDashboardResource } from '../composables/use-dashboard-resource.js';
|
|
3
3
|
import type { DashboardSourceLike, DashboardStage } from '../types/index.js';
|
|
4
|
+
import type { DashboardReadTracker } from './tracker.js';
|
|
4
5
|
export type DashboardResourceSlot = ShallowRef<ReturnType<typeof useDashboardResource> | null>;
|
|
6
|
+
type DashboardResourceFacade = DashboardSourceLike & {
|
|
7
|
+
kind: 'query';
|
|
8
|
+
stage: DashboardStage;
|
|
9
|
+
active: boolean;
|
|
10
|
+
filters: object;
|
|
11
|
+
controls: object;
|
|
12
|
+
};
|
|
5
13
|
/**
|
|
6
14
|
* Public resource object returned by `stage.query(...)`. It exists before its key is known (keys
|
|
7
15
|
* come from the object the `queries` builder returns), so it reads the resource runtime through a
|
|
8
|
-
* slot. Reads before instantiation track the slot, which keeps dependent gates reactive
|
|
16
|
+
* slot. Reads before instantiation track the slot, which keeps dependent gates reactive, and every
|
|
17
|
+
* `data` read is recorded by the tracker, so `requires` and `derive` know what they depend on.
|
|
9
18
|
*/
|
|
10
|
-
export declare function createDashboardResourceFacade(
|
|
11
|
-
kind: 'query';
|
|
19
|
+
export declare function createDashboardResourceFacade(params: {
|
|
12
20
|
stage: DashboardStage;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
21
|
+
slot: DashboardResourceSlot;
|
|
22
|
+
defaultValue: unknown;
|
|
23
|
+
tracker: DashboardReadTracker;
|
|
24
|
+
}): DashboardResourceFacade;
|
|
25
|
+
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { markRaw } from "vue";
|
|
2
2
|
const emptyFacade = markRaw({});
|
|
3
|
-
export function createDashboardResourceFacade(
|
|
4
|
-
|
|
3
|
+
export function createDashboardResourceFacade(params) {
|
|
4
|
+
const { slot, stage, tracker } = params;
|
|
5
|
+
const facade = markRaw({
|
|
5
6
|
activate() {
|
|
6
7
|
slot.value?.activate();
|
|
7
8
|
},
|
|
@@ -9,20 +10,24 @@ export function createDashboardResourceFacade(stage, slot, defaultValue) {
|
|
|
9
10
|
return slot.value?.active.value ?? false;
|
|
10
11
|
},
|
|
11
12
|
get data() {
|
|
12
|
-
|
|
13
|
+
tracker.record(facade);
|
|
14
|
+
return slot.value ? slot.value.data.value : params.defaultValue;
|
|
13
15
|
},
|
|
14
16
|
get error() {
|
|
15
|
-
return slot.value?.error.value
|
|
17
|
+
return slot.value?.error.value;
|
|
18
|
+
},
|
|
19
|
+
get controls() {
|
|
20
|
+
return slot.value?.filters.controls ?? emptyFacade;
|
|
21
|
+
},
|
|
22
|
+
get filters() {
|
|
23
|
+
return slot.value?.filters.values ?? emptyFacade;
|
|
16
24
|
},
|
|
17
25
|
get id() {
|
|
18
26
|
return slot.value?.id ?? "";
|
|
19
27
|
},
|
|
20
28
|
kind: "query",
|
|
21
|
-
get
|
|
22
|
-
return slot.value?.
|
|
23
|
-
},
|
|
24
|
-
get params() {
|
|
25
|
-
return slot.value?.widget.values ?? emptyFacade;
|
|
29
|
+
get fetching() {
|
|
30
|
+
return slot.value?.fetching.value ?? false;
|
|
26
31
|
},
|
|
27
32
|
refresh: () => slot.value?.refresh() ?? Promise.resolve(),
|
|
28
33
|
get refreshing() {
|
|
@@ -36,4 +41,5 @@ export function createDashboardResourceFacade(stage, slot, defaultValue) {
|
|
|
36
41
|
return slot.value?.updatedAt.value;
|
|
37
42
|
}
|
|
38
43
|
});
|
|
44
|
+
return facade;
|
|
39
45
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import type { DashboardSchemaLike } from '../types/index.js';
|
|
2
|
-
import type { DashboardRuntimeSchema } from '../types/runtime.js';
|
|
1
|
+
import type { DashboardFilterBuilder, DashboardFilterLike, DashboardSchemaLike } from '../types/index.js';
|
|
2
|
+
import type { DashboardRuntimeFiltersInput, DashboardRuntimeSchema } from '../types/runtime.js';
|
|
3
3
|
/**
|
|
4
4
|
* Erases the schema generics once so the runtime can invoke every builder with the contexts it
|
|
5
|
-
* creates. Views
|
|
5
|
+
* creates. Views keep the object they were declared with.
|
|
6
6
|
*/
|
|
7
7
|
export declare function resolveDashboardRuntimeSchema(schema: DashboardSchemaLike): DashboardRuntimeSchema;
|
|
8
|
+
/** Runs a scope's `filters` callback with the `f` builder. */
|
|
9
|
+
export declare function resolveDashboardFilters(params: {
|
|
10
|
+
input: DashboardRuntimeFiltersInput | undefined;
|
|
11
|
+
builder: DashboardFilterBuilder;
|
|
12
|
+
}): Record<string, DashboardFilterLike>;
|
|
8
13
|
/** Dev guard mirroring the compile-time key checks, for schemas assembled without inference. */
|
|
9
14
|
export declare function assertDashboardMemberKey(key: string, taken: ReadonlySet<string>, scope: string): void;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
const reservedKeys = /* @__PURE__ */ new Set([
|
|
2
2
|
"autoRefresh",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"controls",
|
|
4
|
+
"filtered",
|
|
5
|
+
"filters",
|
|
5
6
|
"refresh",
|
|
6
7
|
"refreshing",
|
|
8
|
+
"resetFilters",
|
|
7
9
|
"schema",
|
|
8
10
|
"state",
|
|
9
11
|
"updatedAt",
|
|
@@ -11,19 +13,22 @@ const reservedKeys = /* @__PURE__ */ new Set([
|
|
|
11
13
|
]);
|
|
12
14
|
export function resolveDashboardRuntimeSchema(schema) {
|
|
13
15
|
const input = schema;
|
|
14
|
-
const views = Object.entries(input.views
|
|
16
|
+
const views = Object.entries(input.views ?? {});
|
|
15
17
|
return {
|
|
16
18
|
autoRefresh: input.autoRefresh,
|
|
17
19
|
defaultView: input.defaultView ?? views[0]?.[0],
|
|
18
20
|
derive: input.derive,
|
|
21
|
+
filters: input.filters,
|
|
19
22
|
key: input.key,
|
|
20
23
|
label: input.label,
|
|
21
|
-
params: input.params,
|
|
22
24
|
queries: input.queries,
|
|
23
25
|
urlPrefix: input.urlPrefix,
|
|
24
26
|
views
|
|
25
27
|
};
|
|
26
28
|
}
|
|
29
|
+
export function resolveDashboardFilters(params) {
|
|
30
|
+
return params.input?.(params.builder) ?? {};
|
|
31
|
+
}
|
|
27
32
|
export function assertDashboardMemberKey(key, taken, scope) {
|
|
28
33
|
if (reservedKeys.has(key) || taken.has(key)) {
|
|
29
34
|
throw new Error(`[dashboard] "${key}" in ${scope} is reserved or already used.`);
|
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
import type { DashboardResourceState } from '../types/index.js';
|
|
1
|
+
import type { DashboardCondition, DashboardResourceState } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Combines the states of several sources the way a dependent value experiences them: any error
|
|
4
4
|
* wins, then any pending source. Idle sources were not requested (gated by `requires`, or a
|
|
5
5
|
* deferred query nobody activated), so they do not hold the value back unless all are idle.
|
|
6
|
+
* Disabled sources are not part of the dashboard: they are left out, and only when every source is
|
|
7
|
+
* disabled is the combination disabled too.
|
|
6
8
|
*/
|
|
7
9
|
export declare function combineDashboardStates(states: readonly DashboardResourceState[]): DashboardResourceState;
|
|
10
|
+
/** Whether an `enabled` condition holds. No condition always holds. */
|
|
11
|
+
export declare function resolveDashboardCondition(condition: DashboardCondition | undefined): boolean;
|
|
8
12
|
/** Oldest defined timestamp of a set of sources: they are all at least this fresh. */
|
|
9
13
|
export declare function resolveDashboardUpdatedAt(values: readonly (number | undefined)[]): number | undefined;
|
|
10
14
|
/** Refreshes sources in parallel and reports every failure at once. */
|
|
11
15
|
export declare function refreshDashboardSources(sources: readonly {
|
|
12
16
|
refresh: () => Promise<void>;
|
|
13
17
|
}[]): Promise<void>;
|
|
14
|
-
/** URL segment of the current view.
|
|
18
|
+
/** URL segment of the current view. No filter can use it while the dashboard has views. */
|
|
15
19
|
export declare const DASHBOARD_VIEW_URL_KEY = "view";
|
|
16
|
-
/** URL segment of the auto-refresh interval.
|
|
20
|
+
/** URL segment of the auto-refresh interval. No filter can use it. */
|
|
17
21
|
export declare const DASHBOARD_REFRESH_URL_KEY = "refresh";
|
|
18
22
|
/** URL key of the auto-refresh interval: `refresh`, or `<urlPrefix>.refresh`. */
|
|
19
23
|
export declare function resolveDashboardRefreshKey(urlPrefix: string | undefined): string;
|
|
20
24
|
/** Joins the non-empty segments of a URL key with dots. */
|
|
21
25
|
export declare function joinDashboardUrlKey(...segments: readonly (string | undefined)[]): string;
|
|
22
26
|
/**
|
|
23
|
-
* URL key prefix of
|
|
24
|
-
*
|
|
27
|
+
* URL key prefix of a dashboard's filters: none (`year`, `currency`), or `urlPrefix` when two
|
|
28
|
+
* dashboards share a page. Views add no segment: a filter key names the same state in every scope,
|
|
29
|
+
* so `year` declared by two views keeps its value across tabs.
|
|
25
30
|
*/
|
|
26
|
-
export declare function resolveDashboardScopePrefix(urlPrefix: string | undefined
|
|
31
|
+
export declare function resolveDashboardScopePrefix(urlPrefix: string | undefined): string;
|
|
27
32
|
/** URL key of the current view: `view`, or `<urlPrefix>.view`. */
|
|
28
33
|
export declare function resolveDashboardViewKey(urlPrefix: string | undefined): string;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
export function combineDashboardStates(states) {
|
|
2
|
-
|
|
3
|
-
if (states.
|
|
4
|
-
if (
|
|
2
|
+
const live = states.filter((state) => state !== "disabled");
|
|
3
|
+
if (live.length === 0) return states.length > 0 ? "disabled" : "ready";
|
|
4
|
+
if (live.includes("error")) return "error";
|
|
5
|
+
if (live.includes("loading")) return "loading";
|
|
6
|
+
if (live.every((state) => state === "idle")) return "idle";
|
|
5
7
|
return "ready";
|
|
6
8
|
}
|
|
9
|
+
export function resolveDashboardCondition(condition) {
|
|
10
|
+
return condition === void 0 || condition();
|
|
11
|
+
}
|
|
7
12
|
export function resolveDashboardUpdatedAt(values) {
|
|
8
13
|
let oldest;
|
|
9
14
|
for (const value of values) {
|
|
@@ -24,8 +29,8 @@ export function resolveDashboardRefreshKey(urlPrefix) {
|
|
|
24
29
|
export function joinDashboardUrlKey(...segments) {
|
|
25
30
|
return segments.filter(Boolean).join(".");
|
|
26
31
|
}
|
|
27
|
-
export function resolveDashboardScopePrefix(urlPrefix
|
|
28
|
-
return joinDashboardUrlKey(urlPrefix
|
|
32
|
+
export function resolveDashboardScopePrefix(urlPrefix) {
|
|
33
|
+
return joinDashboardUrlKey(urlPrefix);
|
|
29
34
|
}
|
|
30
35
|
export function resolveDashboardViewKey(urlPrefix) {
|
|
31
36
|
return joinDashboardUrlKey(urlPrefix, DASHBOARD_VIEW_URL_KEY);
|
|
@@ -13,5 +13,7 @@ export declare function formatDashboardDateTime(time: number, locale: string): s
|
|
|
13
13
|
* line.
|
|
14
14
|
*/
|
|
15
15
|
export declare function formatDashboardDay(time: number, now: number, locale: string): string;
|
|
16
|
+
/** The date of a page header: `Wednesday, September 23, 2026`. Capitalized, since it starts a line. */
|
|
17
|
+
export declare function formatDashboardToday(now: number, locale: string): string;
|
|
16
18
|
/** Local start of the day of a time, used as a stable group key. */
|
|
17
19
|
export declare function startOfDashboardDay(time: number): number;
|
|
@@ -19,7 +19,13 @@ function resolveTimeFormats(locale) {
|
|
|
19
19
|
year: "numeric"
|
|
20
20
|
}),
|
|
21
21
|
full: new Intl.DateTimeFormat(locale, { dateStyle: "long", timeStyle: "short" }),
|
|
22
|
-
relative: new Intl.RelativeTimeFormat(locale, { numeric: "auto", style: "short" })
|
|
22
|
+
relative: new Intl.RelativeTimeFormat(locale, { numeric: "auto", style: "short" }),
|
|
23
|
+
today: new Intl.DateTimeFormat(locale, {
|
|
24
|
+
day: "numeric",
|
|
25
|
+
month: "long",
|
|
26
|
+
weekday: "long",
|
|
27
|
+
year: "numeric"
|
|
28
|
+
})
|
|
23
29
|
};
|
|
24
30
|
formatsByLocale.set(locale, formats);
|
|
25
31
|
return formats;
|
|
@@ -50,6 +56,10 @@ export function formatDashboardDay(time, now, locale) {
|
|
|
50
56
|
const text = days < 2 ? formats.relative.format(-days, "day") : (sameYear ? formats.date : formats.dateWithYear).format(time);
|
|
51
57
|
return text.charAt(0).toLocaleUpperCase(locale) + text.slice(1);
|
|
52
58
|
}
|
|
59
|
+
export function formatDashboardToday(now, locale) {
|
|
60
|
+
const text = resolveTimeFormats(locale).today.format(now);
|
|
61
|
+
return text.charAt(0).toLocaleUpperCase(locale) + text.slice(1);
|
|
62
|
+
}
|
|
53
63
|
export function startOfDashboardDay(time) {
|
|
54
64
|
const day = new Date(time);
|
|
55
65
|
day.setHours(0, 0, 0, 0);
|
|
@@ -20,7 +20,7 @@ export declare const DASHBOARD_TABLE_CLASSES: {
|
|
|
20
20
|
* never moves, so its divider stays aligned with the card content; the highlight is a pseudo-element
|
|
21
21
|
* reaching 8px past both edges, behind the content (`isolate` keeps it inside the row).
|
|
22
22
|
*/
|
|
23
|
-
export declare const DASHBOARD_SELECTABLE_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:transition-colors has-[
|
|
23
|
+
export declare const DASHBOARD_SELECTABLE_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:transition-colors has-[>:is(button,a):hover]:before:bg-elevated/60 has-[>:is(button,a):focus-visible]:before:bg-elevated/60";
|
|
24
24
|
/**
|
|
25
25
|
* A row shown as selected (`selected` prop): the same tint as the hover, stronger, and an accent
|
|
26
26
|
* on its start edge, both drawn around the row box.
|
|
@@ -15,7 +15,7 @@ export const DASHBOARD_TABLE_CLASSES = {
|
|
|
15
15
|
th: "px-2.5 pt-0.5 pb-2 text-xs font-medium whitespace-nowrap text-dimmed first:ps-0 last:pe-0",
|
|
16
16
|
wrapper: "min-w-0 overflow-auto"
|
|
17
17
|
};
|
|
18
|
-
export const DASHBOARD_SELECTABLE_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:transition-colors has-[
|
|
18
|
+
export const DASHBOARD_SELECTABLE_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:transition-colors has-[>:is(button,a):hover]:before:bg-elevated/60 has-[>:is(button,a):focus-visible]:before:bg-elevated/60";
|
|
19
19
|
export const DASHBOARD_SELECTED_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:bg-elevated after:pointer-events-none after:absolute after:inset-y-2 after:-start-2 after:w-0.5 after:rounded-full after:bg-primary";
|
|
20
20
|
export const DASHBOARD_ROW_BUTTON = "absolute inset-y-0 -inset-x-2 cursor-pointer rounded-md outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset";
|
|
21
21
|
export const DASHBOARD_TABLE_ROW_BUTTON = "absolute inset-0 cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset";
|
|
@@ -163,7 +163,7 @@ const viewportClass = computed(
|
|
|
163
163
|
);
|
|
164
164
|
const footerClass = computed(
|
|
165
165
|
() => mergeFormUiClass(
|
|
166
|
-
isOverlayShell.value ? "flex shrink-0 items-center justify-between gap-3 border-t border-default bg-default px-[22px] pt-3.5 pb-[18px]" : "flex items-center justify-between gap-3
|
|
166
|
+
isOverlayShell.value ? "flex shrink-0 items-center justify-between gap-3 border-t border-default bg-default px-[22px] pt-3.5 pb-[18px]" : "flex items-center justify-between gap-3",
|
|
167
167
|
formUi.ui.value.root?.ui?.footer
|
|
168
168
|
)
|
|
169
169
|
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CARD_SELECTED_RING = "has-data-[state=checked]:ring-4 has-data-[state=checked]:ring-primary/20";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const CARD_SELECTED_RING = "has-data-[state=checked]:ring-4 has-data-[state=checked]:ring-primary/20";
|
|
@@ -6,6 +6,7 @@ import { useFieldControl } from "../../composables/use-field-control";
|
|
|
6
6
|
import { formOptionKey } from "../../utils/options";
|
|
7
7
|
import { isBoolean, isNumber, isString, isUndefined } from "../../utils/predicate";
|
|
8
8
|
import { mergeFormUiClass } from "../../utils/ui";
|
|
9
|
+
import { CARD_SELECTED_RING } from "../card-selection";
|
|
9
10
|
const props = defineProps({
|
|
10
11
|
field: { type: Object, required: true },
|
|
11
12
|
path: { type: Array, required: true }
|
|
@@ -38,7 +39,8 @@ const groupUi = computed(() => ({
|
|
|
38
39
|
fieldset: mergeFormUiClass(
|
|
39
40
|
controlProps.value.ui?.fieldset,
|
|
40
41
|
fieldProps.value.orientation === "horizontal" ? "flex-wrap" : void 0
|
|
41
|
-
)
|
|
42
|
+
),
|
|
43
|
+
item: mergeFormUiClass(CARD_SELECTED_RING, controlProps.value.ui?.item)
|
|
42
44
|
}));
|
|
43
45
|
function isOptionValue(value) {
|
|
44
46
|
return isString(value) || isNumber(value) || isBoolean(value);
|
|
@@ -6,6 +6,7 @@ import { useFieldControl } from "../../composables/use-field-control";
|
|
|
6
6
|
import { formOptionKey } from "../../utils/options";
|
|
7
7
|
import { isBoolean, isNumber, isString, isUndefined } from "../../utils/predicate";
|
|
8
8
|
import { mergeFormUiClass } from "../../utils/ui";
|
|
9
|
+
import { CARD_SELECTED_RING } from "../card-selection";
|
|
9
10
|
const props = defineProps({
|
|
10
11
|
field: { type: Object, required: true },
|
|
11
12
|
path: { type: Array, required: true }
|
|
@@ -38,6 +39,10 @@ const groupUi = computed(() => ({
|
|
|
38
39
|
fieldset: mergeFormUiClass(
|
|
39
40
|
controlProps.value.ui?.fieldset,
|
|
40
41
|
fieldProps.value.orientation === "horizontal" ? "flex-wrap" : void 0
|
|
42
|
+
),
|
|
43
|
+
item: mergeFormUiClass(
|
|
44
|
+
fieldProps.value.variant === "card" ? CARD_SELECTED_RING : void 0,
|
|
45
|
+
controlProps.value.ui?.item
|
|
41
46
|
)
|
|
42
47
|
}));
|
|
43
48
|
function isOptionValue(value) {
|
|
@@ -4,6 +4,8 @@ import { computed } from "vue";
|
|
|
4
4
|
import FormFieldShell from "../../components/renderer/form-field-shell.vue";
|
|
5
5
|
import { useFieldControl } from "../../composables/use-field-control";
|
|
6
6
|
import { isBoolean, isNumber, isString } from "../../utils/predicate";
|
|
7
|
+
import { mergeFormUiClass } from "../../utils/ui";
|
|
8
|
+
import { CARD_SELECTED_RING } from "../card-selection";
|
|
7
9
|
const props = defineProps({
|
|
8
10
|
field: { type: Object, required: true },
|
|
9
11
|
path: { type: Array, required: true }
|
|
@@ -23,6 +25,13 @@ const model = computed({
|
|
|
23
25
|
set: (value) => form.setValue(props.path, value)
|
|
24
26
|
});
|
|
25
27
|
const items = computed(() => [...options.items.value]);
|
|
28
|
+
const groupUi = computed(() => ({
|
|
29
|
+
...controlProps.value.ui,
|
|
30
|
+
item: mergeFormUiClass(
|
|
31
|
+
fieldProps.value.variant === "card" ? CARD_SELECTED_RING : void 0,
|
|
32
|
+
controlProps.value.ui?.item
|
|
33
|
+
)
|
|
34
|
+
}));
|
|
26
35
|
</script>
|
|
27
36
|
|
|
28
37
|
<template>
|
|
@@ -34,6 +43,7 @@ const items = computed(() => [...options.items.value]);
|
|
|
34
43
|
label-key="label"
|
|
35
44
|
description-key="description"
|
|
36
45
|
:items="items"
|
|
46
|
+
:ui="groupUi"
|
|
37
47
|
:variant="fieldProps.variant === 'table' ? 'list' : fieldProps.variant ?? 'list'"
|
|
38
48
|
:orientation="fieldProps.orientation"
|
|
39
49
|
:indicator="fieldProps.indicator"
|
|
@@ -6,6 +6,7 @@ import FormFieldShell from "../../components/renderer/form-field-shell.vue";
|
|
|
6
6
|
import { useFieldControl } from "../../composables/use-field-control";
|
|
7
7
|
import { isBoolean, isNumber, isString } from "../../utils/predicate";
|
|
8
8
|
import { mergeFormUiClass } from "../../utils/ui";
|
|
9
|
+
import { CARD_SELECTED_RING } from "../card-selection";
|
|
9
10
|
const props = defineProps({
|
|
10
11
|
field: { type: Object, required: true },
|
|
11
12
|
path: { type: Array, required: true }
|
|
@@ -30,7 +31,8 @@ const groupUi = computed(() => ({
|
|
|
30
31
|
fieldset: mergeFormUiClass(
|
|
31
32
|
controlProps.value.ui?.fieldset,
|
|
32
33
|
fieldProps.value.orientation === "horizontal" ? "flex-wrap" : void 0
|
|
33
|
-
)
|
|
34
|
+
),
|
|
35
|
+
item: mergeFormUiClass(CARD_SELECTED_RING, controlProps.value.ui?.item)
|
|
34
36
|
}));
|
|
35
37
|
</script>
|
|
36
38
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RemoteOptionsPageRequest, RemoteOptionsPagination, RemoteOptionsResult, RemoteOptionsSearch } from '../../shared/types/remote-options.js';
|
|
2
2
|
import type { FormValue } from './/index.js';
|
|
3
3
|
import type { FormFieldCallback, FormFieldCallbackParams } from './callbacks.js';
|
|
4
4
|
import type { FormQueryOptions } from './context.js';
|
|
@@ -68,12 +68,6 @@ export interface FormOptionConfig<TOption, TContext = NonNullable<unknown>, TDep
|
|
|
68
68
|
/** Disable the field while its option source has no usable data yet. */
|
|
69
69
|
disableOnLoading?: boolean;
|
|
70
70
|
}
|
|
71
|
-
/** @deprecated Use `RemoteOptionsPage` from `#ui-tools/shared`. Kept for public type compatibility. */
|
|
72
|
-
export type FormRemoteOptionsPage<TOption> = RemoteOptionsPage<TOption>;
|
|
73
|
-
/** @deprecated Use `RemoteCursorOptionsPage` from `#ui-tools/shared`. Kept for public type compatibility. */
|
|
74
|
-
export type FormRemoteCursorOptionsPage<TOption> = RemoteCursorOptionsPage<TOption>;
|
|
75
|
-
/** @deprecated Use `RemoteOptionsResult` from `#ui-tools/shared`. Kept for public type compatibility. */
|
|
76
|
-
export type FormRemoteOptionsResult<TOption> = RemoteOptionsResult<TOption>;
|
|
77
71
|
export interface FormRemoteOptionsRequest<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue = FormValue, TOption = FormValue> extends FormFieldCallbackParams<TContext, TDeps, TValue, TOption> {
|
|
78
72
|
/** Current debounced search term. Empty when the menu lists unfiltered options. */
|
|
79
73
|
search: string;
|
|
@@ -87,10 +81,6 @@ export interface FormRemoteSelectedRequest<TContext = NonNullable<unknown>, TDep
|
|
|
87
81
|
values: readonly FormOptionValue[];
|
|
88
82
|
}
|
|
89
83
|
export type FormRemoteSource<TResult> = FormQueryOptions<TResult> | Promise<TResult>;
|
|
90
|
-
/** @deprecated Use `RemoteOptionsPagination` from `#ui-tools/shared`. Kept for public type compatibility. */
|
|
91
|
-
export type FormRemotePagination = RemoteOptionsPagination;
|
|
92
|
-
/** @deprecated Use `RemoteOptionsSearch` from `#ui-tools/shared`. Kept for public type compatibility. */
|
|
93
|
-
export type FormRemoteSearch = RemoteOptionsSearch;
|
|
94
84
|
/**
|
|
95
85
|
* Remote option configuration: server-side search, pagination, and selected-value hydration.
|
|
96
86
|
*/
|
|
@@ -24,7 +24,7 @@ export async function focusFormFieldElement(fieldElement) {
|
|
|
24
24
|
focusableElement.focus({ preventScroll: true });
|
|
25
25
|
fieldElement.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
|
|
26
26
|
await waitForFocusSettle();
|
|
27
|
-
return
|
|
27
|
+
return focusableElement.ownerDocument.activeElement === focusableElement;
|
|
28
28
|
}
|
|
29
29
|
export async function focusFirstInvalidFormField(errors) {
|
|
30
30
|
for (const error of errors) {
|
|
@@ -19,6 +19,27 @@ export default defineUiToolsLocale({
|
|
|
19
19
|
series: "{label} (previous period)",
|
|
20
20
|
year: "Previous year"
|
|
21
21
|
},
|
|
22
|
+
filters: {
|
|
23
|
+
all: "All",
|
|
24
|
+
clear: "Clear {label}",
|
|
25
|
+
clearSelection: "Clear selection",
|
|
26
|
+
empty: "No results",
|
|
27
|
+
label: "Filters",
|
|
28
|
+
loadError: "Options could not be loaded",
|
|
29
|
+
loading: "Loading\u2026",
|
|
30
|
+
more: "{label} +{count}",
|
|
31
|
+
no: "No",
|
|
32
|
+
presets: "Presets",
|
|
33
|
+
reset: "Reset",
|
|
34
|
+
retry: "Retry",
|
|
35
|
+
search: "Search\u2026",
|
|
36
|
+
views: "Views",
|
|
37
|
+
yes: "Yes"
|
|
38
|
+
},
|
|
39
|
+
format: {
|
|
40
|
+
pointsOne: "{value} pt",
|
|
41
|
+
pointsOther: "{value} pts"
|
|
42
|
+
},
|
|
22
43
|
freshness: {
|
|
23
44
|
prefix: "Updated",
|
|
24
45
|
updated: "Updated {time}"
|
|
@@ -39,6 +60,14 @@ export default defineUiToolsLocale({
|
|
|
39
60
|
label: "Refresh",
|
|
40
61
|
off: "Off"
|
|
41
62
|
},
|
|
63
|
+
page: {
|
|
64
|
+
loading: "loading\u2026",
|
|
65
|
+
updated: "updated"
|
|
66
|
+
},
|
|
67
|
+
series: {
|
|
68
|
+
add: "Add",
|
|
69
|
+
remove: "Remove {label}"
|
|
70
|
+
},
|
|
42
71
|
rowActions: "Actions for {label}",
|
|
43
72
|
stat: {
|
|
44
73
|
goal: "Goal {value}"
|