@platforma-sdk/ui-vue 1.68.8 → 1.70.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/.turbo/turbo-build.log +13 -13
- package/.turbo/turbo-formatter$colon$check.log +2 -2
- package/.turbo/turbo-linter$colon$check.log +2 -2
- package/.turbo/turbo-types$colon$check.log +1 -1
- package/CHANGELOG.md +22 -0
- package/dist/components/PlAgDataTable/sources/table-source-v2.js +3 -3
- package/dist/components/PlAgDataTable/sources/table-source-v2.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.style.js +5 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.style.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.css +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.d.ts.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js +40 -23
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.js +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.js.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.style.css +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue.d.ts +9 -19
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js +22 -23
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js.map +1 -1
- package/package.json +6 -6
- package/src/components/PlAgDataTable/sources/table-source-v2.ts +10 -6
- package/src/components/PlAgGridColumnManager/PlAgGridColumnManager.vue +51 -1
- package/src/components/PlDatasetSelector/PlDatasetSelector.vue +24 -23
- package/src/components/PlDatasetSelector/__tests__/PlDatasetSelector.jsdomtest.ts +70 -72
|
@@ -1 +1 @@
|
|
|
1
|
-
.pl-dataset-selector[data-v-
|
|
1
|
+
.pl-dataset-selector[data-v-95f2adf4]{flex-direction:column;gap:12px;display:flex}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { DatasetOption,
|
|
1
|
+
import { DatasetOption, DatasetSelection } from '@platforma-sdk/model';
|
|
2
2
|
/**
|
|
3
|
-
* Select a dataset and (optionally) a filter column, emitting a
|
|
3
|
+
* Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.
|
|
4
4
|
*
|
|
5
5
|
* Behaves like {@link PlDropdownRef} when none of the offered datasets carry
|
|
6
6
|
* filter options. When the selected dataset has compatible filters, a second
|
|
7
7
|
* dropdown appears with the filters plus a "No filter" entry.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* The emitted value bundles the user's pick (`primary`) with the auto-attached
|
|
10
|
+
* `enrichments` payload from the matching `DatasetOption`. Enrichments are
|
|
11
|
+
* opaque to the UI — block authors unbundle them inside their args resolver.
|
|
12
12
|
*/
|
|
13
13
|
declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
14
|
-
modelValue?:
|
|
14
|
+
modelValue?: DatasetSelection | undefined;
|
|
15
15
|
} & {
|
|
16
16
|
/** Available datasets, each optionally carrying compatible filter choices. */
|
|
17
17
|
options?: Readonly<DatasetOption[]>;
|
|
@@ -38,14 +38,9 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
38
38
|
/** Disable all interaction. */
|
|
39
39
|
disabled?: boolean;
|
|
40
40
|
}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
41
|
-
"update:modelValue": (value:
|
|
42
|
-
__isRef: true;
|
|
43
|
-
blockId: string;
|
|
44
|
-
name: string;
|
|
45
|
-
requireEnrichments?: true | undefined;
|
|
46
|
-
}> | undefined) => any;
|
|
41
|
+
"update:modelValue": (value: DatasetSelection | undefined) => any;
|
|
47
42
|
}, string, import('vue').PublicProps, Readonly<{
|
|
48
|
-
modelValue?:
|
|
43
|
+
modelValue?: DatasetSelection | undefined;
|
|
49
44
|
} & {
|
|
50
45
|
/** Available datasets, each optionally carrying compatible filter choices. */
|
|
51
46
|
options?: Readonly<DatasetOption[]>;
|
|
@@ -72,12 +67,7 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
72
67
|
/** Disable all interaction. */
|
|
73
68
|
disabled?: boolean;
|
|
74
69
|
}> & Readonly<{
|
|
75
|
-
"onUpdate:modelValue"?: ((value:
|
|
76
|
-
__isRef: true;
|
|
77
|
-
blockId: string;
|
|
78
|
-
name: string;
|
|
79
|
-
requireEnrichments?: true | undefined;
|
|
80
|
-
}> | undefined) => any) | undefined;
|
|
70
|
+
"onUpdate:modelValue"?: ((value: DatasetSelection | undefined) => any) | undefined;
|
|
81
71
|
}>, {
|
|
82
72
|
error: undefined;
|
|
83
73
|
label: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlDatasetSelector.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PlDatasetSelector.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"names":[],"mappings":"AAuKA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAS,MAAM,sBAAsB,CAAC;AAOnF;;;;;;;;;;GAUG;;iBA2HU,gBAAgB,GAAG,SAAS;;IAlHrC,8EAA8E;cACpE,QAAQ,CAAC,aAAa,EAAE,CAAC;IACnC,wCAAwC;YAChC,MAAM;IACd,6EAA6E;aACpE,MAAM;IACf,gEAAgE;2BACzC,MAAM;IAC7B,0DAA0D;YAClD,OAAO;IACf,+CAA+C;kBACjC,MAAM;IACpB,uCAAuC;kBACzB,MAAM;IACpB,2CAA2C;wBACvB,MAAM;IAC1B,sEAAsE;oBACtD,MAAM;IACtB,mDAAmD;gBACvC,OAAO;IACnB,6CAA6C;eAClC,OAAO;IAClB,+BAA+B;eACpB,OAAO;;;;iBA2FT,gBAAgB,GAAG,SAAS;;IAlHrC,8EAA8E;cACpE,QAAQ,CAAC,aAAa,EAAE,CAAC;IACnC,wCAAwC;YAChC,MAAM;IACd,6EAA6E;aACpE,MAAM;IACf,gEAAgE;2BACzC,MAAM;IAC7B,0DAA0D;YAClD,OAAO;IACf,+CAA+C;kBACjC,MAAM;IACpB,uCAAuC;kBACzB,MAAM;IACpB,2CAA2C;wBACvB,MAAM;IAC1B,sEAAsE;oBACtD,MAAM;IACtB,mDAAmD;gBACvC,OAAO;IACnB,6CAA6C;eAClC,OAAO;IAClB,+BAA+B;eACpB,OAAO;;;;;WApBV,MAAM;iBAQA,MAAM;aAVV,QAAQ,CAAC,aAAa,EAAE,CAAC;YAI1B,MAAM;0BAEQ,MAAM;eAYjB,OAAO;cAER,OAAO;cAEP,OAAO;iBAVJ,MAAM;uBAEA,MAAM;mBAEV,MAAM;;cAvBd,MAAM,OAAO;;cAAb,MAAM,OAAO;;AAFzB,wBAqQK;AAcL,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed as e, createBlock as t, createCommentVNode as n, createElementBlock as r, createSlots as i, createVNode as a, defineComponent as o, mergeModels as s, openBlock as c, renderSlot as l, unref as u, useModel as d, useSlots as f, withCtx as p } from "vue";
|
|
2
|
-
import {
|
|
2
|
+
import { createDatasetSelection as m, createPrimaryRef as h, plRefsEqual as g } from "@platforma-sdk/model";
|
|
3
3
|
import { PlDropdown as _, PlDropdownRef as v } from "@milaboratories/uikit";
|
|
4
4
|
//#region src/components/PlDatasetSelector/PlDatasetSelector.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
@@ -32,16 +32,10 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
32
32
|
}),
|
|
33
33
|
emits: ["update:modelValue"],
|
|
34
34
|
setup(o) {
|
|
35
|
-
let s = f(), b = d(o, "modelValue"), x = o, S = e(() => {
|
|
36
|
-
let e = b.value;
|
|
37
|
-
if (e !== void 0) return h(e) ? e.column : e;
|
|
38
|
-
}), C = e(() => {
|
|
39
|
-
let e = b.value;
|
|
40
|
-
return h(e) ? e.filter : void 0;
|
|
41
|
-
}), w = e(() => {
|
|
35
|
+
let s = f(), b = d(o, "modelValue"), x = o, S = e(() => b.value?.primary.column), C = e(() => b.value?.primary.filter), w = e(() => {
|
|
42
36
|
let e = S.value;
|
|
43
|
-
if (e) return x.options?.find((t) => g(t.ref, e, !0));
|
|
44
|
-
}), T = e(() => (w.value?.filters?.length ?? 0) > 0),
|
|
37
|
+
if (e) return x.options?.find((t) => g(t.primary.ref, e, !0));
|
|
38
|
+
}), T = e(() => x.options?.map((e) => e.primary)), E = e(() => (w.value?.filters?.length ?? 0) > 0), D = e(() => {
|
|
45
39
|
let e = w.value?.filters;
|
|
46
40
|
return e ? [{
|
|
47
41
|
label: x.noFilterLabel,
|
|
@@ -50,20 +44,25 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
50
44
|
label: e.label,
|
|
51
45
|
value: e.ref
|
|
52
46
|
}))] : [];
|
|
53
|
-
}),
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
}), O = e(() => C.value ?? null);
|
|
48
|
+
function k(e, t) {
|
|
49
|
+
if (e === void 0) {
|
|
50
|
+
b.value = void 0;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
let n = x.options?.find((t) => g(t.primary.ref, e, !0));
|
|
54
|
+
b.value = m(h(e, t), n?.enrichments);
|
|
59
55
|
}
|
|
60
56
|
function A(e) {
|
|
57
|
+
k(e, void 0);
|
|
58
|
+
}
|
|
59
|
+
function j(e) {
|
|
61
60
|
let t = S.value;
|
|
62
|
-
t &&
|
|
61
|
+
t && k(t, e ?? void 0);
|
|
63
62
|
}
|
|
64
63
|
return (e, d) => (c(), r("div", y, [a(u(v), {
|
|
65
64
|
"model-value": S.value,
|
|
66
|
-
options:
|
|
65
|
+
options: T.value,
|
|
67
66
|
label: o.label,
|
|
68
67
|
helper: o.helper,
|
|
69
68
|
"loading-options-helper": o.loadingOptionsHelper,
|
|
@@ -72,7 +71,7 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
72
71
|
clearable: o.clearable,
|
|
73
72
|
required: o.required,
|
|
74
73
|
disabled: o.disabled,
|
|
75
|
-
"onUpdate:modelValue":
|
|
74
|
+
"onUpdate:modelValue": A
|
|
76
75
|
}, i({ _: 2 }, [s.tooltip ? {
|
|
77
76
|
name: "tooltip",
|
|
78
77
|
fn: p(() => [l(e.$slots, "tooltip", {}, void 0, !0)]),
|
|
@@ -88,14 +87,14 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
88
87
|
"clearable",
|
|
89
88
|
"required",
|
|
90
89
|
"disabled"
|
|
91
|
-
]),
|
|
90
|
+
]), E.value ? (c(), t(u(_), {
|
|
92
91
|
key: 0,
|
|
93
|
-
"model-value":
|
|
94
|
-
options:
|
|
92
|
+
"model-value": O.value,
|
|
93
|
+
options: D.value,
|
|
95
94
|
label: o.filterLabel,
|
|
96
95
|
placeholder: o.filterPlaceholder,
|
|
97
96
|
disabled: o.disabled,
|
|
98
|
-
"onUpdate:modelValue":
|
|
97
|
+
"onUpdate:modelValue": j
|
|
99
98
|
}, null, 8, [
|
|
100
99
|
"model-value",
|
|
101
100
|
"options",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlDatasetSelector.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Select a dataset and (optionally) a filter column, emitting a
|
|
1
|
+
{"version":3,"file":"PlDatasetSelector.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.\n *\n * Behaves like {@link PlDropdownRef} when none of the offered datasets carry\n * filter options. When the selected dataset has compatible filters, a second\n * dropdown appears with the filters plus a \"No filter\" entry.\n *\n * The emitted value bundles the user's pick (`primary`) with the auto-attached\n * `enrichments` payload from the matching `DatasetOption`. Enrichments are\n * opaque to the UI — block authors unbundle them inside their args resolver.\n */\nexport default {\n name: \"PlDatasetSelector\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport type { DatasetOption, DatasetSelection, PlRef } from \"@platforma-sdk/model\";\nimport { createDatasetSelection, createPrimaryRef, plRefsEqual } from \"@platforma-sdk/model\";\nimport type { ListOption } from \"@milaboratories/uikit\";\nimport { PlDropdown, PlDropdownRef } from \"@milaboratories/uikit\";\nimport { computed } from \"vue\";\n\nconst slots = defineSlots<{\n tooltip?: () => unknown;\n}>();\n\nconst model = defineModel<DatasetSelection | undefined>();\n\nconst props = withDefaults(\n defineProps<{\n /** Available datasets, each optionally carrying compatible filter choices. */\n options?: Readonly<DatasetOption[]>;\n /** Label above the dataset dropdown. */\n label?: string;\n /** Helper text below the dataset dropdown (shown when there is no error). */\n helper?: string;\n /** Helper text shown while `options` is undefined (loading). */\n loadingOptionsHelper?: string;\n /** Error message displayed below the dataset dropdown. */\n error?: unknown;\n /** Placeholder when no dataset is selected. */\n placeholder?: string;\n /** Label above the filter dropdown. */\n filterLabel?: string;\n /** Placeholder for the filter dropdown. */\n filterPlaceholder?: string;\n /** Label of the \"no filter\" entry prepended to the filter options. */\n noFilterLabel?: string;\n /** Show a clear button on the dataset dropdown. */\n clearable?: boolean;\n /** Mark the dataset dropdown as required. */\n required?: boolean;\n /** Disable all interaction. */\n disabled?: boolean;\n }>(),\n {\n options: undefined,\n label: undefined,\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n filterLabel: \"\",\n filterPlaceholder: \"...\",\n noFilterLabel: \"No filter\",\n clearable: false,\n required: false,\n disabled: false,\n },\n);\n\nconst selectedDataset = computed<PlRef | undefined>(() => model.value?.primary.column);\n\nconst selectedFilter = computed<PlRef | undefined>(() => model.value?.primary.filter);\n\nconst currentDatasetOption = computed<DatasetOption | undefined>(() => {\n const dataset = selectedDataset.value;\n if (!dataset) return undefined;\n return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));\n});\n\n// PlDropdownRef expects `Option[]`; project the primary out of each entry.\nconst primaryOptions = computed<readonly { ref: PlRef; label: string }[] | undefined>(() =>\n props.options?.map((o) => o.primary),\n);\n\nconst hasFilters = computed(() => (currentDatasetOption.value?.filters?.length ?? 0) > 0);\n\n/**\n * Filter dropdown options. The first entry (`null`) is the \"No filter\" choice —\n * null distinguishes it from `undefined` (dropdown clear button, disabled here).\n */\nconst filterOptions = computed<ListOption<PlRef | null>[]>(() => {\n const filters = currentDatasetOption.value?.filters;\n if (!filters) return [];\n return [\n { label: props.noFilterLabel, value: null } as ListOption<PlRef | null>,\n ...filters.map((f) => ({ label: f.label, value: f.ref }) as ListOption<PlRef | null>),\n ];\n});\n\nconst filterValue = computed<PlRef | null>(() => selectedFilter.value ?? null);\n\nfunction emitValue(dataset: PlRef | undefined, filter: PlRef | undefined) {\n if (dataset === undefined) {\n model.value = undefined;\n return;\n }\n // Resolve from `props.options` directly — `currentDatasetOption` may not\n // have recomputed yet when this runs synchronously inside a change handler.\n const option = props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));\n model.value = createDatasetSelection(createPrimaryRef(dataset, filter), option?.enrichments);\n}\n\nfunction onDatasetChange(dataset: PlRef | undefined) {\n emitValue(dataset, undefined);\n}\n\nfunction onFilterChange(value: PlRef | null | undefined) {\n const dataset = selectedDataset.value;\n if (!dataset) return;\n emitValue(dataset, value ?? undefined);\n}\n</script>\n\n<template>\n <div class=\"pl-dataset-selector\">\n <PlDropdownRef\n :model-value=\"selectedDataset\"\n :options=\"primaryOptions\"\n :label=\"label\"\n :helper=\"helper\"\n :loading-options-helper=\"loadingOptionsHelper\"\n :error=\"error\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n :required=\"required\"\n :disabled=\"disabled\"\n @update:model-value=\"onDatasetChange\"\n >\n <template v-if=\"slots.tooltip\" #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlDropdownRef>\n <PlDropdown\n v-if=\"hasFilters\"\n :model-value=\"filterValue\"\n :options=\"filterOptions\"\n :label=\"filterLabel\"\n :placeholder=\"filterPlaceholder\"\n :disabled=\"disabled\"\n @update:model-value=\"onFilterChange\"\n />\n </div>\n</template>\n\n<style scoped>\n.pl-dataset-selector {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n</style>\n"],"mappings":";;;;;CAaE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWR,IAAM,IAAQ,GAEV,EAEE,IAAQ,EAAyC,GAAA,aAAE,EAEnD,IAAQ,GA2CR,IAAkB,QAAkC,EAAM,OAAO,QAAQ,OAAO,EAEhF,IAAiB,QAAkC,EAAM,OAAO,QAAQ,OAAO,EAE/E,IAAuB,QAA0C;GACrE,IAAM,IAAU,EAAgB;AAC3B,SACL,QAAO,EAAM,SAAS,MAAM,MAAM,EAAY,EAAE,QAAQ,KAAK,GAAS,GAAK,CAAC;IAC5E,EAGI,IAAiB,QACrB,EAAM,SAAS,KAAK,MAAM,EAAE,QAAQ,CACrC,EAEK,IAAa,SAAgB,EAAqB,OAAO,SAAS,UAAU,KAAK,EAAE,EAMnF,IAAgB,QAA2C;GAC/D,IAAM,IAAU,EAAqB,OAAO;AAE5C,UADK,IACE,CACL;IAAE,OAAO,EAAM;IAAe,OAAO;IAAM,EAC3C,GAAG,EAAQ,KAAK,OAAO;IAAE,OAAO,EAAE;IAAO,OAAO,EAAE;IAAK,EAA8B,CACtF,GAJoB,EAAE;IAKvB,EAEI,IAAc,QAA6B,EAAe,SAAS,KAAK;EAE9E,SAAS,EAAU,GAA4B,GAA2B;AACxE,OAAI,MAAY,KAAA,GAAW;AACzB,MAAM,QAAQ,KAAA;AACd;;GAIF,IAAM,IAAS,EAAM,SAAS,MAAM,MAAM,EAAY,EAAE,QAAQ,KAAK,GAAS,GAAK,CAAC;AACpF,KAAM,QAAQ,EAAuB,EAAiB,GAAS,EAAO,EAAE,GAAQ,YAAY;;EAG9F,SAAS,EAAgB,GAA4B;AACnD,KAAU,GAAS,KAAA,EAAU;;EAG/B,SAAS,EAAe,GAAiC;GACvD,IAAM,IAAU,EAAgB;AAC3B,QACL,EAAU,GAAS,KAAS,KAAA,EAAU;;yBAKtC,EA2BM,OA3BN,GA2BM,CA1BJ,EAgBgB,EAAA,EAAA,EAAA;GAfb,eAAa,EAAA;GACb,SAAS,EAAA;GACT,OAAO,EAAA;GACP,QAAQ,EAAA;GACR,0BAAwB,EAAA;GACxB,OAAO,EAAA;GACP,aAAa,EAAA;GACb,WAAW,EAAA;GACX,UAAU,EAAA;GACV,UAAU,EAAA;GACV,uBAAoB;kBAEL,EAAM,UAAA;SAAU;eACP,CAAvB,EAAuB,EAAA,QAAA,WAAA,EAAA,EAAA,KAAA,GAAA,GAAA,CAAA,CAAA;;;;;;;;;;;;;MAInB,EAAA,SAAA,GAAA,EADR,EAQE,EAAA,EAAA,EAAA;;GANC,eAAa,EAAA;GACb,SAAS,EAAA;GACT,OAAO,EAAA;GACP,aAAa,EAAA;GACb,UAAU,EAAA;GACV,uBAAoB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.70.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"lru-cache": "^11.2.2",
|
|
27
27
|
"vue": "^3.5.24",
|
|
28
28
|
"zod": "~3.25.76",
|
|
29
|
-
"@milaboratories/pf-spec-driver": "1.3.
|
|
30
|
-
"@milaboratories/
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
29
|
+
"@milaboratories/pf-spec-driver": "1.3.7",
|
|
30
|
+
"@milaboratories/pl-model-common": "1.37.0",
|
|
31
|
+
"@platforma-sdk/model": "1.70.0",
|
|
32
|
+
"@milaboratories/uikit": "2.13.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@faker-js/faker": "^9.2.0",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"typescript": "~5.9.3",
|
|
46
46
|
"vite": "^8.0.6",
|
|
47
47
|
"vitest": "^4.1.3",
|
|
48
|
-
"@milaboratories/helpers": "1.14.1",
|
|
49
48
|
"@milaboratories/build-configs": "2.0.0",
|
|
50
49
|
"@milaboratories/ts-builder": "1.3.2",
|
|
50
|
+
"@milaboratories/helpers": "1.14.1",
|
|
51
51
|
"@milaboratories/ts-configs": "1.2.3"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
@@ -126,7 +126,7 @@ export async function calculateGridOptions({
|
|
|
126
126
|
|
|
127
127
|
// displayable column indices ordered: axes first, then columns by OrderPriority
|
|
128
128
|
const fields = sortIndicesByTypeAndPriority(
|
|
129
|
-
selectDisplayableIndices(tableSpecs, isPartitionedAxis),
|
|
129
|
+
selectDisplayableIndices(tableSpecs, isPartitionedAxis, getLabelColumnIndex),
|
|
130
130
|
tableSpecs,
|
|
131
131
|
);
|
|
132
132
|
|
|
@@ -337,8 +337,6 @@ export function makeColDef(
|
|
|
337
337
|
};
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
-
type LabelColumnLookup = (axisId: AxisId) => number;
|
|
341
|
-
|
|
342
340
|
/** Build index mapping from full tableSpecs to their position in visibleTableSpecs (missing → -1). */
|
|
343
341
|
function buildSpecsToVisibleSpecsMapping(
|
|
344
342
|
tableSpecs: PTableColumnSpec[],
|
|
@@ -370,7 +368,7 @@ function createPartitionedAxisPredicate(sheets: PlDataTableSheet[]): (axisId: Ax
|
|
|
370
368
|
function collectLabelColumnsByAxis(
|
|
371
369
|
tableSpecs: PTableColumnSpec[],
|
|
372
370
|
isPartitionedAxis: (axisId: AxisId) => boolean,
|
|
373
|
-
):
|
|
371
|
+
): (axisId: AxisId) => number {
|
|
374
372
|
const labelColumns: { axisId: AxisId; labelColumnIdx: number }[] = [];
|
|
375
373
|
for (const [i, spec] of tableSpecs.entries()) {
|
|
376
374
|
if (spec.type !== "column" || !isLabelColumnSpec(spec.spec)) continue;
|
|
@@ -390,16 +388,22 @@ function collectLabelColumnsByAxis(
|
|
|
390
388
|
function selectDisplayableIndices(
|
|
391
389
|
tableSpecs: PTableColumnSpec[],
|
|
392
390
|
isPartitionedAxis: (axisId: AxisId) => boolean,
|
|
391
|
+
getLabelColumnIndex: (axisId: AxisId) => number,
|
|
393
392
|
): number[] {
|
|
394
393
|
return tableSpecs
|
|
395
394
|
.entries()
|
|
396
395
|
.filter(([, spec]) => {
|
|
397
396
|
switch (spec.type) {
|
|
398
397
|
case "axis":
|
|
399
|
-
return
|
|
398
|
+
return (
|
|
399
|
+
// show axis if not hidden or if it has a label column
|
|
400
|
+
(!isColumnHidden(spec.spec) ? true : getLabelColumnIndex(spec.id) > -1) &&
|
|
401
|
+
!isPartitionedAxis(spec.id)
|
|
402
|
+
);
|
|
400
403
|
case "column":
|
|
401
404
|
return (
|
|
402
405
|
!isColumnHidden(spec.spec) &&
|
|
406
|
+
// hide label columns (their labeled axes are shown instead)
|
|
403
407
|
!isLabelColumnSpec(spec.spec) &&
|
|
404
408
|
!isLinkerColumnSpec(spec.spec)
|
|
405
409
|
);
|
|
@@ -429,7 +433,7 @@ function sortIndicesByTypeAndPriority(indices: number[], tableSpecs: PTableColum
|
|
|
429
433
|
function replaceAxesWithLabelColumns(
|
|
430
434
|
fields: number[],
|
|
431
435
|
tableSpecs: PTableColumnSpec[],
|
|
432
|
-
getLabelColumnIndex:
|
|
436
|
+
getLabelColumnIndex: (axisId: AxisId) => number,
|
|
433
437
|
): number[] {
|
|
434
438
|
return fields.map((i) => {
|
|
435
439
|
const spec = tableSpecs[i];
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import {
|
|
3
3
|
PlBtnGhost,
|
|
4
|
+
PlBtnSecondary,
|
|
4
5
|
PlElementList,
|
|
6
|
+
PlIcon24,
|
|
5
7
|
PlSearchField,
|
|
6
8
|
PlSlideModal,
|
|
7
9
|
usePlBlockPageTitleTeleportTarget,
|
|
@@ -45,6 +47,24 @@ const { filteredItems, segments } = useFilteredItems({
|
|
|
45
47
|
query,
|
|
46
48
|
getStrings: (item) => [item.label],
|
|
47
49
|
});
|
|
50
|
+
|
|
51
|
+
const toggleableFilteredItems = computed(() =>
|
|
52
|
+
filteredItems.value.filter((item) => item.id !== PlAgDataTableRowNumberColId),
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const allFilteredHidden = computed(
|
|
56
|
+
() =>
|
|
57
|
+
toggleableFilteredItems.value.length > 0 &&
|
|
58
|
+
toggleableFilteredItems.value.every((item) => !item.column.isVisible()),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const toggleAllFiltered = () => {
|
|
62
|
+
if (props.api.isDestroyed()) return;
|
|
63
|
+
const nextVisible = allFilteredHidden.value;
|
|
64
|
+
const cols = toggleableFilteredItems.value.map((item) => item.column);
|
|
65
|
+
if (cols.length === 0) return;
|
|
66
|
+
props.api.setColumnsVisible(cols, nextVisible);
|
|
67
|
+
};
|
|
48
68
|
</script>
|
|
49
69
|
|
|
50
70
|
<template>
|
|
@@ -54,7 +74,17 @@ const { filteredItems, segments } = useFilteredItems({
|
|
|
54
74
|
|
|
55
75
|
<PlSlideModal v-model="slideModal" :width="width" close-on-outside-click>
|
|
56
76
|
<template #title>Manage Columns</template>
|
|
57
|
-
<
|
|
77
|
+
<div :class="$style.searchRow">
|
|
78
|
+
<PlSearchField v-model="query" clearable />
|
|
79
|
+
<PlBtnSecondary
|
|
80
|
+
:class="$style.toggleAllBtn"
|
|
81
|
+
:disabled="toggleableFilteredItems.length === 0"
|
|
82
|
+
@click.stop="toggleAllFiltered"
|
|
83
|
+
>
|
|
84
|
+
<PlIcon24 v-if="allFilteredHidden" name="view-show" />
|
|
85
|
+
<PlIcon24 v-else name="view-hide" />
|
|
86
|
+
</PlBtnSecondary>
|
|
87
|
+
</div>
|
|
58
88
|
<PlElementList
|
|
59
89
|
:items="filteredItems"
|
|
60
90
|
:get-item-key="(item) => item.id"
|
|
@@ -101,4 +131,24 @@ const { filteredItems, segments } = useFilteredItems({
|
|
|
101
131
|
background-color: var(--color-active-select);
|
|
102
132
|
border-radius: 2px;
|
|
103
133
|
}
|
|
134
|
+
|
|
135
|
+
.searchRow {
|
|
136
|
+
display: flex;
|
|
137
|
+
align-items: center;
|
|
138
|
+
gap: 8px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.searchRow > :first-child {
|
|
142
|
+
flex: 1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.toggleAllBtn {
|
|
146
|
+
min-width: unset;
|
|
147
|
+
opacity: 0.2;
|
|
148
|
+
transition: opacity 0.3s;
|
|
149
|
+
|
|
150
|
+
&:hover {
|
|
151
|
+
opacity: 1;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
104
154
|
</style>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/**
|
|
3
|
-
* Select a dataset and (optionally) a filter column, emitting a
|
|
3
|
+
* Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.
|
|
4
4
|
*
|
|
5
5
|
* Behaves like {@link PlDropdownRef} when none of the offered datasets carry
|
|
6
6
|
* filter options. When the selected dataset has compatible filters, a second
|
|
7
7
|
* dropdown appears with the filters plus a "No filter" entry.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* The emitted value bundles the user's pick (`primary`) with the auto-attached
|
|
10
|
+
* `enrichments` payload from the matching `DatasetOption`. Enrichments are
|
|
11
|
+
* opaque to the UI — block authors unbundle them inside their args resolver.
|
|
12
12
|
*/
|
|
13
13
|
export default {
|
|
14
14
|
name: "PlDatasetSelector",
|
|
@@ -16,8 +16,8 @@ export default {
|
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
18
|
<script lang="ts" setup>
|
|
19
|
-
import type { DatasetOption,
|
|
20
|
-
import {
|
|
19
|
+
import type { DatasetOption, DatasetSelection, PlRef } from "@platforma-sdk/model";
|
|
20
|
+
import { createDatasetSelection, createPrimaryRef, plRefsEqual } from "@platforma-sdk/model";
|
|
21
21
|
import type { ListOption } from "@milaboratories/uikit";
|
|
22
22
|
import { PlDropdown, PlDropdownRef } from "@milaboratories/uikit";
|
|
23
23
|
import { computed } from "vue";
|
|
@@ -26,11 +26,7 @@ const slots = defineSlots<{
|
|
|
26
26
|
tooltip?: () => unknown;
|
|
27
27
|
}>();
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
* v-model value. Accepts `PrimaryRef`, plain `PlRef` (treated as unfiltered),
|
|
31
|
-
* or `undefined`. Writes always emit `PrimaryRef` or `undefined`.
|
|
32
|
-
*/
|
|
33
|
-
const model = defineModel<PrimaryRef | PlRef | undefined>();
|
|
29
|
+
const model = defineModel<DatasetSelection | undefined>();
|
|
34
30
|
|
|
35
31
|
const props = withDefaults(
|
|
36
32
|
defineProps<{
|
|
@@ -75,23 +71,21 @@ const props = withDefaults(
|
|
|
75
71
|
},
|
|
76
72
|
);
|
|
77
73
|
|
|
78
|
-
const selectedDataset = computed<PlRef | undefined>(() =>
|
|
79
|
-
const v = model.value;
|
|
80
|
-
if (v === undefined) return undefined;
|
|
81
|
-
return isPrimaryRef(v) ? v.column : v;
|
|
82
|
-
});
|
|
74
|
+
const selectedDataset = computed<PlRef | undefined>(() => model.value?.primary.column);
|
|
83
75
|
|
|
84
|
-
const selectedFilter = computed<PlRef | undefined>(() =>
|
|
85
|
-
const v = model.value;
|
|
86
|
-
return isPrimaryRef(v) ? v.filter : undefined;
|
|
87
|
-
});
|
|
76
|
+
const selectedFilter = computed<PlRef | undefined>(() => model.value?.primary.filter);
|
|
88
77
|
|
|
89
78
|
const currentDatasetOption = computed<DatasetOption | undefined>(() => {
|
|
90
79
|
const dataset = selectedDataset.value;
|
|
91
80
|
if (!dataset) return undefined;
|
|
92
|
-
return props.options?.find((o) => plRefsEqual(o.ref, dataset, true));
|
|
81
|
+
return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));
|
|
93
82
|
});
|
|
94
83
|
|
|
84
|
+
// PlDropdownRef expects `Option[]`; project the primary out of each entry.
|
|
85
|
+
const primaryOptions = computed<readonly { ref: PlRef; label: string }[] | undefined>(() =>
|
|
86
|
+
props.options?.map((o) => o.primary),
|
|
87
|
+
);
|
|
88
|
+
|
|
95
89
|
const hasFilters = computed(() => (currentDatasetOption.value?.filters?.length ?? 0) > 0);
|
|
96
90
|
|
|
97
91
|
/**
|
|
@@ -110,7 +104,14 @@ const filterOptions = computed<ListOption<PlRef | null>[]>(() => {
|
|
|
110
104
|
const filterValue = computed<PlRef | null>(() => selectedFilter.value ?? null);
|
|
111
105
|
|
|
112
106
|
function emitValue(dataset: PlRef | undefined, filter: PlRef | undefined) {
|
|
113
|
-
|
|
107
|
+
if (dataset === undefined) {
|
|
108
|
+
model.value = undefined;
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Resolve from `props.options` directly — `currentDatasetOption` may not
|
|
112
|
+
// have recomputed yet when this runs synchronously inside a change handler.
|
|
113
|
+
const option = props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));
|
|
114
|
+
model.value = createDatasetSelection(createPrimaryRef(dataset, filter), option?.enrichments);
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
function onDatasetChange(dataset: PlRef | undefined) {
|
|
@@ -128,7 +129,7 @@ function onFilterChange(value: PlRef | null | undefined) {
|
|
|
128
129
|
<div class="pl-dataset-selector">
|
|
129
130
|
<PlDropdownRef
|
|
130
131
|
:model-value="selectedDataset"
|
|
131
|
-
:options="
|
|
132
|
+
:options="primaryOptions"
|
|
132
133
|
:label="label"
|
|
133
134
|
:helper="helper"
|
|
134
135
|
:loading-options-helper="loadingOptionsHelper"
|