nuxt-ui-tools 1.1.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 +6 -3
- 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 +8 -7
- 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 +66 -77
- 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 -8
- package/dist/runtime/dashboard/utils/options.js +6 -5
- 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 +32 -1
- package/dist/runtime/i18n/locales/fr.js +32 -1
- package/dist/runtime/i18n/types.d.ts +44 -0
- package/dist/runtime/shared/styles/scrollbars.css +1 -1
- package/dist/runtime/shared/styles/tokens.css +1 -1
- package/dist/runtime/shared/types/query.d.ts +8 -0
- package/dist/runtime/shared/utils/remote-options.d.ts +10 -0
- package/dist/runtime/shared/utils/remote-options.js +6 -0
- package/dist/runtime/table/components/filters/shared/filter-option-list-end.d.vue.ts +11 -0
- package/dist/runtime/table/components/filters/shared/filter-option-list-end.vue +76 -0
- package/dist/runtime/table/components/filters/shared/filter-option-list-end.vue.d.ts +11 -0
- package/dist/runtime/table/components/filters/shared/filter-option-loading-list.d.vue.ts +3 -0
- package/dist/runtime/table/components/filters/shared/filter-option-loading-list.vue +2 -1
- package/dist/runtime/table/components/filters/shared/filter-option-loading-list.vue.d.ts +3 -0
- package/dist/runtime/table/components/filters/shared/filter-option-multiple-list.vue +1 -1
- package/dist/runtime/table/components/filters/shared/filter-option-picker-content.vue +13 -0
- package/dist/runtime/table/components/filters/shared/filter-option-single-list.d.vue.ts +2 -0
- package/dist/runtime/table/components/filters/shared/filter-option-single-list.vue +1 -1
- package/dist/runtime/table/components/filters/shared/filter-option-single-list.vue.d.ts +2 -0
- package/dist/runtime/table/components/filters/shared/filter-option-tree-content.d.vue.ts +3 -0
- package/dist/runtime/table/components/filters/shared/filter-option-tree-content.vue +2 -2
- package/dist/runtime/table/components/filters/shared/filter-option-tree-content.vue.d.ts +3 -0
- package/dist/runtime/table/components/filters/shared/filter-searchable-panel.vue +1 -0
- package/dist/runtime/table/composables/use-option-filter-editor-state.d.ts +13 -1
- package/dist/runtime/table/composables/use-option-filter-editor-state.js +6 -2
- package/dist/runtime/table/composables/use-table-filter-options.d.ts +11 -1
- package/dist/runtime/table/composables/use-table-filter-options.js +128 -17
- package/dist/runtime/table/composables/use-table-filter-selected-options.d.ts +20 -0
- package/dist/runtime/table/composables/use-table-filter-selected-options.js +99 -0
- package/dist/runtime/table/composables/use-table-filters.d.ts +5 -0
- package/dist/runtime/table/composables/use-table-filters.js +20 -1
- package/dist/runtime/table/composables/use-table-internals.d.ts +15 -0
- package/dist/runtime/table/composables/use-table-remote-filter-options.d.ts +42 -0
- package/dist/runtime/table/composables/use-table-remote-filter-options.js +102 -0
- package/dist/runtime/table/types/filters.d.ts +42 -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 +15 -1
- package/dist/runtime/table/utils/builders/table-source.d.ts +2 -6
- package/dist/runtime/table/utils/filters/options.d.ts +2 -0
- package/dist/runtime/table/utils/filters/options.js +1 -1
- package/dist/runtime/table/utils/index.d.ts +1 -0
- package/dist/runtime/table/utils/index.js +1 -0
- package/dist/runtime/table/utils/prefetch.js +21 -1
- 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
|
@@ -9,7 +9,7 @@ declare const __VLS_export: <TValue extends string | number>(__VLS_props: NonNul
|
|
|
9
9
|
full?: boolean;
|
|
10
10
|
} & {
|
|
11
11
|
/**
|
|
12
|
-
* Tab strip for dashboard cards, bound with `v-model`. Bind it to a
|
|
12
|
+
* Tab strip for dashboard cards, bound with `v-model`. Bind it to a query filter to switch what a
|
|
13
13
|
* block fetches (the tab lands in the URL, and the block refreshes in place), or to a local ref to
|
|
14
14
|
* switch between blocks: render only the active one, so the others' deferred queries stay idle.
|
|
15
15
|
*/
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { LazyTextValue } from '#ui-tools/shared/types/utils';
|
|
2
|
-
import type { DashboardTotalUi } from '../types/index.js';
|
|
2
|
+
import type { DashboardTotalUi, DashboardValueFormat } from '../types/index.js';
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
label: LazyTextValue;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Numbers go through `format` (locale number format by default); text shows as is; `null` /
|
|
7
|
+
* `undefined` show "—".
|
|
8
|
+
*/
|
|
9
|
+
value: LazyTextValue | null | undefined;
|
|
10
|
+
format?: DashboardValueFormat;
|
|
6
11
|
ui?: DashboardTotalUi;
|
|
7
12
|
};
|
|
8
13
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed } from "vue";
|
|
3
|
+
import { isNumber } from "#ui-tools/shared/utils/predicate";
|
|
3
4
|
import { resolveTextValue } from "#ui-tools/shared/utils/render";
|
|
5
|
+
import { DASHBOARD_MISSING_VALUE, useDashboardFormat } from "../composables/use-dashboard-format";
|
|
4
6
|
import { useDashboardUi } from "../composables/use-dashboard-ui";
|
|
5
7
|
import { resolveDashboardClasses } from "../utils/ui";
|
|
6
8
|
const props = defineProps({
|
|
7
9
|
label: { type: [String, Number, Function], required: true },
|
|
8
|
-
value: { type: [String, Number, Function], required: true },
|
|
10
|
+
value: { type: [String, Number, Function, null], required: true, skipCheck: true },
|
|
11
|
+
format: { type: [String, Function], required: false, skipCheck: true },
|
|
9
12
|
ui: { type: Object, required: false }
|
|
10
13
|
});
|
|
11
14
|
const appUi = useDashboardUi();
|
|
15
|
+
const formats = useDashboardFormat();
|
|
12
16
|
const label = computed(() => resolveTextValue(props.label));
|
|
13
|
-
const value = computed(() =>
|
|
17
|
+
const value = computed(() => {
|
|
18
|
+
const resolved = typeof props.value === "function" ? props.value() : props.value;
|
|
19
|
+
if (resolved === null || resolved === void 0) return DASHBOARD_MISSING_VALUE;
|
|
20
|
+
return isNumber(resolved) ? formats.resolve(props.format)(resolved) : resolveTextValue(resolved);
|
|
21
|
+
});
|
|
14
22
|
const classes = computed(
|
|
15
23
|
() => resolveDashboardClasses(
|
|
16
24
|
{
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { LazyTextValue } from '#ui-tools/shared/types/utils';
|
|
2
|
-
import type { DashboardTotalUi } from '../types/index.js';
|
|
2
|
+
import type { DashboardTotalUi, DashboardValueFormat } from '../types/index.js';
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
label: LazyTextValue;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Numbers go through `format` (locale number format by default); text shows as is; `null` /
|
|
7
|
+
* `undefined` show "—".
|
|
8
|
+
*/
|
|
9
|
+
value: LazyTextValue | null | undefined;
|
|
10
|
+
format?: DashboardValueFormat;
|
|
6
11
|
ui?: DashboardTotalUi;
|
|
7
12
|
};
|
|
8
13
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DashboardViewController, DashboardViewTabsUi } from '../types/index.js';
|
|
2
|
+
declare const __VLS_export: <TKey extends string>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<{
|
|
4
|
+
dashboard: {
|
|
5
|
+
readonly view: DashboardViewController<TKey>;
|
|
6
|
+
};
|
|
7
|
+
ui?: DashboardViewTabsUi;
|
|
8
|
+
}> & (typeof globalThis extends {
|
|
9
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
10
|
+
} ? P : {});
|
|
11
|
+
expose: (exposed: {}) => void;
|
|
12
|
+
attrs: any;
|
|
13
|
+
slots: {
|
|
14
|
+
/** Content of one tab. */
|
|
15
|
+
tab?: (props: {
|
|
16
|
+
item: {
|
|
17
|
+
value: TKey;
|
|
18
|
+
label: string;
|
|
19
|
+
};
|
|
20
|
+
active: boolean;
|
|
21
|
+
}) => unknown;
|
|
22
|
+
};
|
|
23
|
+
emit: {};
|
|
24
|
+
}>) => import("vue").VNode & {
|
|
25
|
+
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
26
|
+
};
|
|
27
|
+
declare const _default: typeof __VLS_export;
|
|
28
|
+
export default _default;
|
|
29
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
30
|
+
[K in keyof T]: T[K];
|
|
31
|
+
} : {
|
|
32
|
+
[K in keyof T as K]: T[K];
|
|
33
|
+
}) & {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, nextTick, onMounted, useTemplateRef, watch } from "vue";
|
|
3
|
+
import { useUiToolsLocale } from "#ui-tools/i18n";
|
|
4
|
+
import { useDashboardUi } from "../composables/use-dashboard-ui";
|
|
5
|
+
import { resolveDashboardClasses } from "../utils/ui";
|
|
6
|
+
const { dashboard, ui } = defineProps({
|
|
7
|
+
dashboard: { type: Object, required: true },
|
|
8
|
+
ui: { type: Object, required: false }
|
|
9
|
+
});
|
|
10
|
+
defineSlots();
|
|
11
|
+
const EDGE = 16;
|
|
12
|
+
const { t } = useUiToolsLocale();
|
|
13
|
+
const appUi = useDashboardUi();
|
|
14
|
+
const strip = useTemplateRef("strip");
|
|
15
|
+
const classes = computed(
|
|
16
|
+
() => resolveDashboardClasses(
|
|
17
|
+
{
|
|
18
|
+
root: "flex min-w-0 gap-0.5 overflow-x-auto border-b border-default [scrollbar-width:none]",
|
|
19
|
+
tab: "relative inline-flex h-10 flex-none items-center px-3 text-sm font-medium whitespace-nowrap text-muted transition-colors outline-none hover:text-default focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset data-[active]:text-highlighted data-[active]:after:absolute data-[active]:after:inset-x-2 data-[active]:after:-bottom-px data-[active]:after:h-0.5 data-[active]:after:rounded-full data-[active]:after:bg-primary"
|
|
20
|
+
},
|
|
21
|
+
appUi.value.viewTabs,
|
|
22
|
+
ui
|
|
23
|
+
)
|
|
24
|
+
);
|
|
25
|
+
function reveal(behavior) {
|
|
26
|
+
const element = strip.value;
|
|
27
|
+
const tab = element?.querySelector('[aria-current="page"]');
|
|
28
|
+
if (!element || !tab) return;
|
|
29
|
+
const bounds = element.getBoundingClientRect();
|
|
30
|
+
const box = tab.getBoundingClientRect();
|
|
31
|
+
const overflow = box.left < bounds.left + EDGE ? box.left - bounds.left - EDGE : Math.max(0, box.right - bounds.right + EDGE);
|
|
32
|
+
if (overflow) element.scrollBy({ behavior, left: overflow });
|
|
33
|
+
}
|
|
34
|
+
onMounted(() => reveal("instant"));
|
|
35
|
+
watch(
|
|
36
|
+
() => dashboard.view.current,
|
|
37
|
+
async () => {
|
|
38
|
+
await nextTick();
|
|
39
|
+
reveal("smooth");
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template>
|
|
45
|
+
<nav
|
|
46
|
+
v-if="dashboard.view.items.length > 1"
|
|
47
|
+
ref="strip"
|
|
48
|
+
:class="classes.root"
|
|
49
|
+
:aria-label="t('dashboard.filters.views')"
|
|
50
|
+
data-dashboard-view-tabs
|
|
51
|
+
>
|
|
52
|
+
<button
|
|
53
|
+
v-for="item in dashboard.view.items"
|
|
54
|
+
:key="item.value"
|
|
55
|
+
type="button"
|
|
56
|
+
:class="classes.tab"
|
|
57
|
+
:data-active="dashboard.view.current === item.value || void 0"
|
|
58
|
+
:aria-current="dashboard.view.current === item.value ? 'page' : void 0"
|
|
59
|
+
@click="dashboard.view.current = item.value"
|
|
60
|
+
>
|
|
61
|
+
<slot name="tab" :item :active="dashboard.view.current === item.value">
|
|
62
|
+
{{ item.label }}
|
|
63
|
+
</slot>
|
|
64
|
+
</button>
|
|
65
|
+
</nav>
|
|
66
|
+
</template>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DashboardViewController, DashboardViewTabsUi } from '../types/index.js';
|
|
2
|
+
declare const __VLS_export: <TKey extends string>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<{
|
|
4
|
+
dashboard: {
|
|
5
|
+
readonly view: DashboardViewController<TKey>;
|
|
6
|
+
};
|
|
7
|
+
ui?: DashboardViewTabsUi;
|
|
8
|
+
}> & (typeof globalThis extends {
|
|
9
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
10
|
+
} ? P : {});
|
|
11
|
+
expose: (exposed: {}) => void;
|
|
12
|
+
attrs: any;
|
|
13
|
+
slots: {
|
|
14
|
+
/** Content of one tab. */
|
|
15
|
+
tab?: (props: {
|
|
16
|
+
item: {
|
|
17
|
+
value: TKey;
|
|
18
|
+
label: string;
|
|
19
|
+
};
|
|
20
|
+
active: boolean;
|
|
21
|
+
}) => unknown;
|
|
22
|
+
};
|
|
23
|
+
emit: {};
|
|
24
|
+
}>) => import("vue").VNode & {
|
|
25
|
+
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
26
|
+
};
|
|
27
|
+
declare const _default: typeof __VLS_export;
|
|
28
|
+
export default _default;
|
|
29
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
30
|
+
[K in keyof T]: T[K];
|
|
31
|
+
} : {
|
|
32
|
+
[K in keyof T as K]: T[K];
|
|
33
|
+
}) & {};
|
|
@@ -15,12 +15,12 @@ const {
|
|
|
15
15
|
title: { type: [String, Number, Function], required: false },
|
|
16
16
|
subtitle: { type: [String, Number, Function], required: false },
|
|
17
17
|
size: { type: String, required: false },
|
|
18
|
-
rows: { type: String, required: false },
|
|
19
18
|
card: { type: Boolean, required: false },
|
|
20
19
|
activation: { type: String, required: false },
|
|
21
20
|
empty: { type: Object, required: false },
|
|
22
21
|
menu: { type: [Boolean, Array, Function], required: false },
|
|
23
22
|
actions: { type: Array, required: false },
|
|
23
|
+
filters: { type: Array, required: false },
|
|
24
24
|
freshness: { type: Boolean, required: false },
|
|
25
25
|
ui: { type: Object, required: false },
|
|
26
26
|
source: { type: Object, required: true },
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { DashboardFilterControl, DashboardFilterUi, DashboardOption, DashboardOptionValue } from '../../types/index.js';
|
|
2
|
+
declare const __VLS_export: <TValue, TItem extends DashboardOptionValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<{
|
|
4
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
5
|
+
classes: Required<DashboardFilterUi>;
|
|
6
|
+
/** Heading above the list. */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** What the menu lists: the options, the presets, or both (presets under the options). */
|
|
9
|
+
list?: "all" | "options" | "presets";
|
|
10
|
+
} & {
|
|
11
|
+
onPicked?: (() => any) | undefined;
|
|
12
|
+
}> & (typeof globalThis extends {
|
|
13
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
14
|
+
} ? P : {});
|
|
15
|
+
expose: (exposed: {}) => void;
|
|
16
|
+
attrs: any;
|
|
17
|
+
slots: {
|
|
18
|
+
item?: (props: {
|
|
19
|
+
item: DashboardOption<TItem>;
|
|
20
|
+
selected: boolean;
|
|
21
|
+
disabled: boolean;
|
|
22
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
23
|
+
}) => unknown;
|
|
24
|
+
header?: (props: {
|
|
25
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
26
|
+
}) => unknown;
|
|
27
|
+
footer?: (props: {
|
|
28
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
29
|
+
}) => unknown;
|
|
30
|
+
empty?: (props: {
|
|
31
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
32
|
+
}) => unknown;
|
|
33
|
+
};
|
|
34
|
+
emit: (evt: "picked") => void;
|
|
35
|
+
}>) => import("vue").VNode & {
|
|
36
|
+
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
37
|
+
};
|
|
38
|
+
declare const _default: typeof __VLS_export;
|
|
39
|
+
export default _default;
|
|
40
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
41
|
+
[K in keyof T]: T[K];
|
|
42
|
+
} : {
|
|
43
|
+
[K in keyof T as K]: T[K];
|
|
44
|
+
}) & {};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import UIcon from "@nuxt/ui/components/Icon.vue";
|
|
3
|
+
import { useEventListener } from "@vueuse/core";
|
|
4
|
+
import { computed, nextTick, useTemplateRef, watch } from "vue";
|
|
5
|
+
import { useUiToolsLocale } from "#ui-tools/i18n";
|
|
6
|
+
const PREFETCH_VIEWPORTS = 3;
|
|
7
|
+
const {
|
|
8
|
+
filter,
|
|
9
|
+
classes,
|
|
10
|
+
title,
|
|
11
|
+
list = "all"
|
|
12
|
+
} = defineProps({
|
|
13
|
+
filter: { type: Object, required: true },
|
|
14
|
+
classes: { type: Object, required: true },
|
|
15
|
+
title: { type: String, required: false },
|
|
16
|
+
list: { type: String, required: false }
|
|
17
|
+
});
|
|
18
|
+
const emit = defineEmits(["picked"]);
|
|
19
|
+
defineSlots();
|
|
20
|
+
const { t } = useUiToolsLocale();
|
|
21
|
+
const listbox = useTemplateRef("listbox");
|
|
22
|
+
const showOptions = computed(() => list !== "presets");
|
|
23
|
+
const showPresets = computed(() => list !== "options" && filter.presets.length > 0);
|
|
24
|
+
const searching = computed(() => filter.search.trim() !== "");
|
|
25
|
+
const clearRow = computed(
|
|
26
|
+
() => !filter.multiple && filter.defaultValue === void 0 && !searching.value
|
|
27
|
+
);
|
|
28
|
+
const full = computed(
|
|
29
|
+
() => filter.multiple && filter.max !== void 0 && filter.selected.length >= filter.max
|
|
30
|
+
);
|
|
31
|
+
const grid = computed(
|
|
32
|
+
() => filter.columns && filter.columns > 1 ? { gridTemplateColumns: `repeat(${filter.columns}, minmax(0, 1fr))` } : void 0
|
|
33
|
+
);
|
|
34
|
+
function pick(item) {
|
|
35
|
+
filter.toggle(item.value);
|
|
36
|
+
if (!filter.multiple) emit("picked");
|
|
37
|
+
}
|
|
38
|
+
function clear() {
|
|
39
|
+
filter.reset();
|
|
40
|
+
if (!filter.multiple) emit("picked");
|
|
41
|
+
}
|
|
42
|
+
function apply(preset) {
|
|
43
|
+
preset.apply();
|
|
44
|
+
emit("picked");
|
|
45
|
+
}
|
|
46
|
+
function loadAhead() {
|
|
47
|
+
const element = listbox.value;
|
|
48
|
+
if (!element || element.clientHeight === 0) return;
|
|
49
|
+
if (!filter.hasMore || filter.loadingMore || filter.loading || filter.error) return;
|
|
50
|
+
const remaining = element.scrollHeight - element.scrollTop - element.clientHeight;
|
|
51
|
+
if (remaining <= element.clientHeight * PREFETCH_VIEWPORTS) filter.loadMore();
|
|
52
|
+
}
|
|
53
|
+
useEventListener(listbox, "scroll", loadAhead, { passive: true });
|
|
54
|
+
watch(
|
|
55
|
+
() => [filter.items.length, filter.hasMore, filter.loadingMore],
|
|
56
|
+
async () => {
|
|
57
|
+
await nextTick();
|
|
58
|
+
loadAhead();
|
|
59
|
+
},
|
|
60
|
+
{ immediate: true }
|
|
61
|
+
);
|
|
62
|
+
function onKeydown(event) {
|
|
63
|
+
const rows = [
|
|
64
|
+
...listbox.value?.querySelectorAll("[data-filter-row]:not(:disabled)") ?? []
|
|
65
|
+
];
|
|
66
|
+
const current = rows.findIndex((row) => row === document.activeElement);
|
|
67
|
+
const target = (/* @__PURE__ */ new Map([
|
|
68
|
+
["ArrowDown", current + 1],
|
|
69
|
+
["ArrowUp", current - 1],
|
|
70
|
+
["End", rows.length - 1],
|
|
71
|
+
["Home", 0]
|
|
72
|
+
])).get(event.key);
|
|
73
|
+
if (target === void 0 || rows.length === 0) return;
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
rows[Math.max(0, Math.min(rows.length - 1, target))]?.focus();
|
|
76
|
+
}
|
|
77
|
+
function focusFirstRow(event) {
|
|
78
|
+
if (event.key !== "ArrowDown") return;
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
listbox.value?.querySelector("[data-filter-row]:not(:disabled)")?.focus();
|
|
81
|
+
}
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<template>
|
|
85
|
+
<div v-if="title" :class="classes.title">{{ title }}</div>
|
|
86
|
+
<label v-if="showOptions && filter.searchable" :class="classes.search" data-filter-search>
|
|
87
|
+
<UIcon name="i-lucide-search" class="size-3.5 flex-none text-dimmed" />
|
|
88
|
+
<input
|
|
89
|
+
v-model="filter.search"
|
|
90
|
+
type="search"
|
|
91
|
+
:placeholder="t('dashboard.filters.search')"
|
|
92
|
+
:aria-label="t('dashboard.filters.search')"
|
|
93
|
+
class="min-w-0 flex-1 border-0 bg-transparent text-[13px] outline-none placeholder:text-dimmed"
|
|
94
|
+
autocomplete="off"
|
|
95
|
+
@keydown="focusFirstRow"
|
|
96
|
+
/>
|
|
97
|
+
</label>
|
|
98
|
+
<slot name="header" :filter />
|
|
99
|
+
<div
|
|
100
|
+
v-if="showOptions"
|
|
101
|
+
ref="listbox"
|
|
102
|
+
role="listbox"
|
|
103
|
+
:aria-label="filter.label"
|
|
104
|
+
:aria-multiselectable="filter.multiple || void 0"
|
|
105
|
+
:class="[classes.list, grid && 'grid']"
|
|
106
|
+
:style="grid"
|
|
107
|
+
data-filter-list
|
|
108
|
+
@keydown="onKeydown"
|
|
109
|
+
>
|
|
110
|
+
<button
|
|
111
|
+
v-if="clearRow"
|
|
112
|
+
type="button"
|
|
113
|
+
role="option"
|
|
114
|
+
:aria-selected="filter.selected.length === 0"
|
|
115
|
+
:class="classes.item"
|
|
116
|
+
:data-selected="filter.selected.length === 0 || void 0"
|
|
117
|
+
data-filter-row
|
|
118
|
+
data-filter-clear-row
|
|
119
|
+
@click="clear"
|
|
120
|
+
>
|
|
121
|
+
<span class="truncate">{{ filter.placeholder }}</span>
|
|
122
|
+
<UIcon v-if="filter.selected.length === 0" name="i-lucide-check" :class="classes.tick" />
|
|
123
|
+
</button>
|
|
124
|
+
<button
|
|
125
|
+
v-for="item in filter.items"
|
|
126
|
+
:key="String(item.value)"
|
|
127
|
+
type="button"
|
|
128
|
+
role="option"
|
|
129
|
+
:aria-selected="filter.isSelected(item.value)"
|
|
130
|
+
:disabled="item.disabled || full && !filter.isSelected(item.value)"
|
|
131
|
+
:class="classes.item"
|
|
132
|
+
:data-selected="filter.isSelected(item.value) || void 0"
|
|
133
|
+
data-filter-row
|
|
134
|
+
@click="pick(item)"
|
|
135
|
+
>
|
|
136
|
+
<slot
|
|
137
|
+
name="item"
|
|
138
|
+
:item
|
|
139
|
+
:selected="filter.isSelected(item.value)"
|
|
140
|
+
:disabled="Boolean(item.disabled || full && !filter.isSelected(item.value))"
|
|
141
|
+
:filter
|
|
142
|
+
>
|
|
143
|
+
<span
|
|
144
|
+
v-if="filter.multiple"
|
|
145
|
+
:class="classes.check"
|
|
146
|
+
:data-checked="filter.isSelected(item.value) || void 0"
|
|
147
|
+
aria-hidden="true"
|
|
148
|
+
>
|
|
149
|
+
<UIcon name="i-lucide-check" class="size-3" />
|
|
150
|
+
</span>
|
|
151
|
+
<UIcon v-if="item.icon" :name="item.icon" class="size-3.5 flex-none text-muted" />
|
|
152
|
+
<img
|
|
153
|
+
v-else-if="item.avatar?.src"
|
|
154
|
+
:src="item.avatar.src"
|
|
155
|
+
:alt="item.avatar.alt ?? ''"
|
|
156
|
+
:class="classes.avatar"
|
|
157
|
+
/>
|
|
158
|
+
<span v-else-if="item.avatar?.text" :class="classes.avatar" aria-hidden="true">
|
|
159
|
+
{{ item.avatar.text }}
|
|
160
|
+
</span>
|
|
161
|
+
<span class="min-w-0 flex-1 truncate">{{ item.label }}</span>
|
|
162
|
+
<span v-if="item.hint" :class="classes.hint">{{ item.hint }}</span>
|
|
163
|
+
<UIcon
|
|
164
|
+
v-if="!filter.multiple && filter.isSelected(item.value)"
|
|
165
|
+
name="i-lucide-check"
|
|
166
|
+
:class="classes.tick"
|
|
167
|
+
/>
|
|
168
|
+
</slot>
|
|
169
|
+
</button>
|
|
170
|
+
<div
|
|
171
|
+
v-if="filter.loading || filter.loadingMore"
|
|
172
|
+
:class="classes.note"
|
|
173
|
+
class="col-span-full"
|
|
174
|
+
data-filter-loading
|
|
175
|
+
>
|
|
176
|
+
{{ t("dashboard.filters.loading") }}
|
|
177
|
+
</div>
|
|
178
|
+
<div v-else-if="filter.error" :class="classes.note" class="col-span-full text-error">
|
|
179
|
+
<span class="truncate">{{ t("dashboard.filters.loadError") }}</span>
|
|
180
|
+
<button
|
|
181
|
+
type="button"
|
|
182
|
+
class="ms-2 font-medium underline-offset-2 hover:underline"
|
|
183
|
+
@click="filter.refresh()"
|
|
184
|
+
>
|
|
185
|
+
{{ t("dashboard.filters.retry") }}
|
|
186
|
+
</button>
|
|
187
|
+
</div>
|
|
188
|
+
<div v-else-if="filter.items.length === 0" :class="classes.note" class="col-span-full">
|
|
189
|
+
<slot name="empty" :filter>{{ t("dashboard.filters.empty") }}</slot>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
<template v-if="showOptions && filter.multiple && filter.selected.length > 0">
|
|
193
|
+
<div :class="classes.separator" role="separator" />
|
|
194
|
+
<button type="button" :class="classes.item" data-filter-clear-selection @click="clear">
|
|
195
|
+
<UIcon name="i-lucide-x" class="size-3.5 flex-none text-muted" />
|
|
196
|
+
<span class="truncate">{{ t("dashboard.filters.clearSelection") }}</span>
|
|
197
|
+
</button>
|
|
198
|
+
</template>
|
|
199
|
+
<template v-if="showPresets">
|
|
200
|
+
<template v-if="showOptions">
|
|
201
|
+
<div :class="classes.separator" role="separator" />
|
|
202
|
+
<div :class="classes.title">{{ t("dashboard.filters.presets") }}</div>
|
|
203
|
+
</template>
|
|
204
|
+
<button
|
|
205
|
+
v-for="preset in filter.presets"
|
|
206
|
+
:key="preset.label"
|
|
207
|
+
type="button"
|
|
208
|
+
:class="classes.item"
|
|
209
|
+
:data-selected="preset.active || void 0"
|
|
210
|
+
data-filter-preset
|
|
211
|
+
@click="apply(preset)"
|
|
212
|
+
>
|
|
213
|
+
<UIcon :name="preset.icon ?? 'i-lucide-layers'" class="size-3.5 flex-none text-muted" />
|
|
214
|
+
<span class="min-w-0 flex-1 truncate">{{ preset.label }}</span>
|
|
215
|
+
<span v-if="preset.hint" :class="classes.hint">{{ preset.hint }}</span>
|
|
216
|
+
<UIcon v-if="preset.active" name="i-lucide-check" :class="classes.tick" />
|
|
217
|
+
</button>
|
|
218
|
+
</template>
|
|
219
|
+
<slot name="footer" :filter />
|
|
220
|
+
</template>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { DashboardFilterControl, DashboardFilterUi, DashboardOption, DashboardOptionValue } from '../../types/index.js';
|
|
2
|
+
declare const __VLS_export: <TValue, TItem extends DashboardOptionValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<{
|
|
4
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
5
|
+
classes: Required<DashboardFilterUi>;
|
|
6
|
+
/** Heading above the list. */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** What the menu lists: the options, the presets, or both (presets under the options). */
|
|
9
|
+
list?: "all" | "options" | "presets";
|
|
10
|
+
} & {
|
|
11
|
+
onPicked?: (() => any) | undefined;
|
|
12
|
+
}> & (typeof globalThis extends {
|
|
13
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
14
|
+
} ? P : {});
|
|
15
|
+
expose: (exposed: {}) => void;
|
|
16
|
+
attrs: any;
|
|
17
|
+
slots: {
|
|
18
|
+
item?: (props: {
|
|
19
|
+
item: DashboardOption<TItem>;
|
|
20
|
+
selected: boolean;
|
|
21
|
+
disabled: boolean;
|
|
22
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
23
|
+
}) => unknown;
|
|
24
|
+
header?: (props: {
|
|
25
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
26
|
+
}) => unknown;
|
|
27
|
+
footer?: (props: {
|
|
28
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
29
|
+
}) => unknown;
|
|
30
|
+
empty?: (props: {
|
|
31
|
+
filter: DashboardFilterControl<TValue, TItem>;
|
|
32
|
+
}) => unknown;
|
|
33
|
+
};
|
|
34
|
+
emit: (evt: "picked") => void;
|
|
35
|
+
}>) => import("vue").VNode & {
|
|
36
|
+
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
37
|
+
};
|
|
38
|
+
declare const _default: typeof __VLS_export;
|
|
39
|
+
export default _default;
|
|
40
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
41
|
+
[K in keyof T]: T[K];
|
|
42
|
+
} : {
|
|
43
|
+
[K in keyof T as K]: T[K];
|
|
44
|
+
}) & {};
|
|
@@ -5,6 +5,8 @@ import type { useDashboardViews } from './use-dashboard-views.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* Facade only: projects the owning scopes into the public dashboard object. Every runtime member is
|
|
7
7
|
* a getter over a ref owned elsewhere, so templates read plain values and `v-model` writes through.
|
|
8
|
+
*
|
|
9
|
+
* Returns the facade and the view handles by view key.
|
|
8
10
|
*/
|
|
9
11
|
export declare function useDashboardApi(params: {
|
|
10
12
|
schema: DashboardSchemaLike;
|
|
@@ -12,4 +14,7 @@ export declare function useDashboardApi(params: {
|
|
|
12
14
|
autoRefresh: WritableComputedRef<number>;
|
|
13
15
|
root: ReturnType<typeof useDashboardScope>;
|
|
14
16
|
views: ReturnType<typeof useDashboardViews> | null;
|
|
15
|
-
}):
|
|
17
|
+
}): {
|
|
18
|
+
api: import("vue").Raw<Record<string, unknown>>;
|
|
19
|
+
handles: Map<string, object>;
|
|
20
|
+
};
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
export function useDashboardApi(params) {
|
|
8
8
|
const { root, views } = params;
|
|
9
9
|
const api = Object.fromEntries(root.members);
|
|
10
|
+
const handles = /* @__PURE__ */ new Map();
|
|
10
11
|
for (const view of views?.views ?? []) {
|
|
11
12
|
const handle = Object.fromEntries(view.scope.members);
|
|
12
13
|
Object.defineProperties(handle, {
|
|
@@ -17,6 +18,9 @@ export function useDashboardApi(params) {
|
|
|
17
18
|
get active() {
|
|
18
19
|
return views?.current.value === view.key;
|
|
19
20
|
},
|
|
21
|
+
get enabled() {
|
|
22
|
+
return view.enabled.value;
|
|
23
|
+
},
|
|
20
24
|
key: view.key,
|
|
21
25
|
get label() {
|
|
22
26
|
return view.label();
|
|
@@ -27,16 +31,20 @@ export function useDashboardApi(params) {
|
|
|
27
31
|
})
|
|
28
32
|
}
|
|
29
33
|
});
|
|
30
|
-
|
|
34
|
+
const facade = markRaw(handle);
|
|
35
|
+
api[view.key] = facade;
|
|
36
|
+
handles.set(view.key, facade);
|
|
31
37
|
}
|
|
32
38
|
const openedScopes = () => [
|
|
33
39
|
root,
|
|
34
40
|
...views?.views.filter((view) => view.opened.value).map((view) => view.scope) ?? []
|
|
35
41
|
];
|
|
42
|
+
const currentView = () => views?.views.find((view) => view.key === views.current.value);
|
|
36
43
|
const visibleScopes = () => {
|
|
37
|
-
const current =
|
|
44
|
+
const current = currentView();
|
|
38
45
|
return current ? [root, current.scope] : [root];
|
|
39
46
|
};
|
|
47
|
+
const visibleFilters = () => visibleScopes().map((scope) => scope.filterScope);
|
|
40
48
|
Object.defineProperties(api, {
|
|
41
49
|
...scopeMembers(root),
|
|
42
50
|
autoRefresh: {
|
|
@@ -46,11 +54,21 @@ export function useDashboardApi(params) {
|
|
|
46
54
|
params.autoRefresh.value = Number.isFinite(seconds) ? Math.max(0, Math.round(seconds)) : 0;
|
|
47
55
|
}
|
|
48
56
|
},
|
|
57
|
+
filtered: {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
get: () => visibleFilters().some((filters) => filters.changed())
|
|
60
|
+
},
|
|
49
61
|
refresh: { enumerable: true, value: () => refreshDashboardSources(openedScopes()) },
|
|
50
62
|
refreshing: {
|
|
51
63
|
enumerable: true,
|
|
52
64
|
get: () => openedScopes().some((scope) => scope.refreshing.value)
|
|
53
65
|
},
|
|
66
|
+
resetFilters: {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
value: () => {
|
|
69
|
+
for (const filters of visibleFilters()) filters.reset();
|
|
70
|
+
}
|
|
71
|
+
},
|
|
54
72
|
schema: { enumerable: true, value: params.schema },
|
|
55
73
|
state: {
|
|
56
74
|
enumerable: true,
|
|
@@ -72,19 +90,24 @@ export function useDashboardApi(params) {
|
|
|
72
90
|
views.current.value = next;
|
|
73
91
|
},
|
|
74
92
|
get items() {
|
|
75
|
-
return views.views.
|
|
93
|
+
return views.views.flatMap(
|
|
94
|
+
(view) => view.enabled.value ? [{ label: view.label(), value: view.key }] : []
|
|
95
|
+
);
|
|
76
96
|
}
|
|
77
97
|
})
|
|
78
98
|
});
|
|
79
99
|
}
|
|
80
|
-
return markRaw(api);
|
|
100
|
+
return { api: markRaw(api), handles };
|
|
81
101
|
}
|
|
82
102
|
function scopeMembers(scope) {
|
|
103
|
+
const { filterScope } = scope;
|
|
83
104
|
return {
|
|
84
|
-
|
|
85
|
-
|
|
105
|
+
controls: { enumerable: true, value: filterScope.controls },
|
|
106
|
+
filtered: { enumerable: true, get: () => filterScope.changed() },
|
|
107
|
+
filters: { enumerable: true, value: filterScope.values },
|
|
86
108
|
refresh: { enumerable: true, value: scope.refresh },
|
|
87
109
|
refreshing: { enumerable: true, get: () => scope.refreshing.value },
|
|
110
|
+
resetFilters: { enumerable: true, value: () => filterScope.reset() },
|
|
88
111
|
state: { enumerable: true, get: () => scope.state.value },
|
|
89
112
|
updatedAt: { enumerable: true, get: () => scope.updatedAt.value }
|
|
90
113
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { ShallowRef } from 'vue';
|
|
2
2
|
import type { DashboardBlockActivation, DashboardBlockPhase, DashboardSourceLike } from '../types/index.js';
|
|
3
3
|
/**
|
|
4
|
-
* Non-visual block behaviour: reduces the source into one render phase,
|
|
5
|
-
* (on mount or when the block nears the viewport),
|
|
4
|
+
* Non-visual block behaviour: reduces the source into one render phase, hides the block while its
|
|
5
|
+
* source is `disabled`, activates deferred sources (on mount or when the block nears the viewport),
|
|
6
|
+
* and resolves the grid cell.
|
|
6
7
|
*
|
|
7
8
|
* The phase is a branch, not a mask: while a block is `idle` or `loading`, its real values are not
|
|
8
9
|
* in the DOM at all, so nothing can flash through.
|
|
@@ -12,11 +13,11 @@ export declare function useDashboardBlock(params: {
|
|
|
12
13
|
empty: () => boolean;
|
|
13
14
|
activation: () => DashboardBlockActivation | undefined;
|
|
14
15
|
size: () => string | undefined;
|
|
15
|
-
rows: () => string | undefined;
|
|
16
16
|
root: Readonly<ShallowRef<HTMLElement | null>>;
|
|
17
17
|
}): {
|
|
18
|
+
fetching: import("vue").ComputedRef<boolean>;
|
|
19
|
+
hidden: import("vue").ComputedRef<boolean>;
|
|
18
20
|
phase: import("vue").ComputedRef<DashboardBlockPhase>;
|
|
19
|
-
refreshing: import("vue").ComputedRef<boolean>;
|
|
20
21
|
retry: () => void;
|
|
21
22
|
style: import("vue").ComputedRef<string>;
|
|
22
23
|
};
|