@platforma-sdk/ui-vue 1.58.17 → 1.58.19
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 +16 -16
- 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 +9 -0
- package/dist/components/PlAdvancedFilter/FilterEditor.js.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.style.js.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.vue.d.ts.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js +1 -6
- package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js.map +1 -1
- package/dist/components/PlAdvancedFilter/types.d.ts +2 -2
- package/dist/components/PlAdvancedFilter/types.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.style.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +6 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-state-v2.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-state-v2.js +6 -4
- package/dist/components/PlAgDataTable/sources/table-state-v2.js.map +1 -1
- package/dist/components/PlAgDataTable/types.d.ts +2 -1
- package/dist/components/PlAgDataTable/types.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/types.js +10 -5
- package/dist/components/PlAgDataTable/types.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.style.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue.d.ts +3 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue.d.ts.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js +49 -50
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js.map +1 -1
- package/package.json +5 -5
- package/src/components/PlAdvancedFilter/FilterEditor.vue +18 -21
- package/src/components/PlAdvancedFilter/types.ts +6 -1
- package/src/components/PlAgDataTable/PlAgDataTableV2.vue +1 -0
- package/src/components/PlAgDataTable/sources/table-state-v2.ts +11 -8
- package/src/components/PlAgDataTable/types.ts +7 -6
- package/src/components/PlTableFilters/PlTableFiltersV2.vue +30 -28
|
@@ -1,39 +1,43 @@
|
|
|
1
1
|
import e from "../PlAdvancedFilter/PlAdvancedFilter.js";
|
|
2
2
|
import "../PlAdvancedFilter/index.js";
|
|
3
|
-
import { Fragment as t, Teleport as n, computed as r, createBlock as i, createCommentVNode as a, createElementBlock as o,
|
|
4
|
-
import { Annotation as
|
|
5
|
-
import { PlBtnGhost as
|
|
6
|
-
|
|
3
|
+
import { Fragment as t, Teleport as n, computed as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, mergeModels as d, normalizeClass as f, onMounted as p, openBlock as m, ref as h, unref as g, useModel as _, withCtx as v, withModifiers as y } from "vue";
|
|
4
|
+
import { Annotation as b, Domain as x, canonicalizeJson as S, getAxisId as C, getUniqueSourceValuesWithLabels as w, parseJson as T, readAnnotation as E, readDomain as D } from "@platforma-sdk/model";
|
|
5
|
+
import { PlBtnGhost as O, PlSlideModal as k, usePlBlockPageTitleTeleportTarget as A } from "@milaboratories/uikit";
|
|
6
|
+
import { isNil as j } from "es-toolkit";
|
|
7
|
+
var M = /* @__PURE__ */ u({
|
|
7
8
|
__name: "PlTableFiltersV2",
|
|
8
|
-
props: /* @__PURE__ */
|
|
9
|
+
props: /* @__PURE__ */ d({
|
|
10
|
+
pframeHandle: {},
|
|
11
|
+
columns: {}
|
|
12
|
+
}, {
|
|
9
13
|
modelValue: { required: !0 },
|
|
10
14
|
modelModifiers: {}
|
|
11
15
|
}),
|
|
12
16
|
emits: ["update:modelValue"],
|
|
13
|
-
setup(
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
setup(u) {
|
|
18
|
+
let d = _(u, "modelValue"), M = u, N = h(!1);
|
|
19
|
+
p(() => {
|
|
20
|
+
N.value = !0;
|
|
17
21
|
});
|
|
18
|
-
let
|
|
19
|
-
function
|
|
20
|
-
return
|
|
22
|
+
let P = A("PlTableFiltersV2"), F = h(!1), I = r(() => d.value.filters.length > 0);
|
|
23
|
+
function L(e) {
|
|
24
|
+
return S(e.type === "axis" ? {
|
|
21
25
|
type: "axis",
|
|
22
|
-
id:
|
|
26
|
+
id: C(e.spec)
|
|
23
27
|
} : {
|
|
24
28
|
type: "column",
|
|
25
29
|
id: e.id
|
|
26
30
|
});
|
|
27
31
|
}
|
|
28
|
-
let
|
|
29
|
-
let n =
|
|
32
|
+
let R = r(() => M.columns.map((e, t) => {
|
|
33
|
+
let n = L(e), r = E(e.spec, b.Label)?.trim() ?? `Unlabeled ${e.type} ${t}`, i = D(e.spec, x.Alphabet) ?? E(e.spec, b.Alphabet);
|
|
30
34
|
return {
|
|
31
35
|
id: n,
|
|
32
36
|
label: r,
|
|
33
37
|
spec: e.spec,
|
|
34
38
|
alphabet: i ?? void 0
|
|
35
39
|
};
|
|
36
|
-
})),
|
|
40
|
+
})), z = [
|
|
37
41
|
"isNA",
|
|
38
42
|
"isNotNA",
|
|
39
43
|
"greaterThan",
|
|
@@ -49,51 +53,46 @@ var k = { key: 1 }, A = /* @__PURE__ */ l({
|
|
|
49
53
|
"equal",
|
|
50
54
|
"notEqual"
|
|
51
55
|
];
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
return [];
|
|
64
|
-
}
|
|
56
|
+
function B(e) {
|
|
57
|
+
if (j(M.pframeHandle)) return console.warn("PFrame handle is not available, cannot fetch suggest options"), [];
|
|
58
|
+
let t = e.columnId, n = T(t);
|
|
59
|
+
if (n.type !== "column") throw Error("ColumnId should be of type 'column' for suggest options");
|
|
60
|
+
return w(M.pframeHandle, {
|
|
61
|
+
columnId: n.id,
|
|
62
|
+
axisIdx: e.axisIdx,
|
|
63
|
+
limit: 100,
|
|
64
|
+
searchQuery: e.searchType === "label" ? e.searchStr : void 0,
|
|
65
|
+
searchQueryValue: e.searchType === "value" ? e.searchStr : void 0
|
|
66
|
+
}).then((e) => e.values);
|
|
65
67
|
}
|
|
66
|
-
return (r,
|
|
68
|
+
return (r, u) => (m(), o(t, null, [N.value && g(P) ? (m(), i(n, {
|
|
67
69
|
key: 0,
|
|
68
|
-
to:
|
|
69
|
-
}, [
|
|
70
|
-
icon:
|
|
71
|
-
onClick:
|
|
70
|
+
to: g(P)
|
|
71
|
+
}, [l(g(O), {
|
|
72
|
+
icon: I.value ? "filter-on" : "filter",
|
|
73
|
+
onClick: u[0] ||= y((e) => F.value = !0, ["stop"])
|
|
72
74
|
}, {
|
|
73
|
-
default:
|
|
75
|
+
default: v(() => [...u[3] ||= [c(" Filters ", -1)]]),
|
|
74
76
|
_: 1
|
|
75
|
-
}, 8, ["icon"])], 8, ["to"])) : a("", !0),
|
|
76
|
-
modelValue:
|
|
77
|
-
"onUpdate:modelValue":
|
|
77
|
+
}, 8, ["icon"])], 8, ["to"])) : a("", !0), l(g(k), {
|
|
78
|
+
modelValue: F.value,
|
|
79
|
+
"onUpdate:modelValue": u[2] ||= (e) => F.value = e,
|
|
78
80
|
"close-on-outside-click": !1
|
|
79
81
|
}, {
|
|
80
|
-
title:
|
|
81
|
-
default:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
filters:
|
|
86
|
-
"
|
|
87
|
-
items: I.value,
|
|
88
|
-
"supported-filters": L,
|
|
89
|
-
"get-suggest-options": R,
|
|
82
|
+
title: v(() => [...u[4] ||= [c("Manage Filters", -1)]]),
|
|
83
|
+
default: v(() => [s("div", { class: f(r.$style.root) }, [l(g(e), {
|
|
84
|
+
filters: d.value,
|
|
85
|
+
"onUpdate:filters": u[1] ||= (e) => d.value = e,
|
|
86
|
+
items: R.value,
|
|
87
|
+
"supported-filters": z,
|
|
88
|
+
"get-suggest-options": B,
|
|
90
89
|
"enable-dnd": !1,
|
|
91
90
|
"enable-add-group-button": !0
|
|
92
|
-
}, null, 8, ["filters", "items"])], 2)
|
|
91
|
+
}, null, 8, ["filters", "items"])], 2)]),
|
|
93
92
|
_: 1
|
|
94
93
|
}, 8, ["modelValue"])], 64));
|
|
95
94
|
}
|
|
96
95
|
});
|
|
97
|
-
export {
|
|
96
|
+
export { M as default };
|
|
98
97
|
|
|
99
98
|
//# sourceMappingURL=PlTableFiltersV2.vue2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlTableFiltersV2.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../src/components/PlTableFilters/PlTableFiltersV2.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type {\n PTableColumnSpec,\n
|
|
1
|
+
{"version":3,"file":"PlTableFiltersV2.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../src/components/PlTableFilters/PlTableFiltersV2.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type {\n PTableColumnSpec,\n PlDataTableFiltersWithMeta,\n PFrameHandle,\n PTableColumnId,\n CanonicalizedJson,\n} from \"@platforma-sdk/model\";\nimport {\n canonicalizeJson,\n Annotation,\n Domain,\n readAnnotation,\n readDomain,\n getAxisId,\n getUniqueSourceValuesWithLabels,\n parseJson,\n} from \"@platforma-sdk/model\";\nimport { computed, onMounted, ref } from \"vue\";\nimport { PlBtnGhost, PlSlideModal, usePlBlockPageTitleTeleportTarget } from \"@milaboratories/uikit\";\nimport {\n PlAdvancedFilter,\n PlAdvancedFilterComponent,\n PlAdvancedFilterSupportedFilters,\n type PlAdvancedFilterItem,\n} from \"../PlAdvancedFilter\";\nimport type { PlAdvancedFilterColumnId } from \"../PlAdvancedFilter/types\";\nimport type { Nil } from \"@milaboratories/helpers\";\nimport { isNil } from \"es-toolkit\";\n\nconst model = defineModel<PlDataTableFiltersWithMeta>({ required: true });\nconst props = defineProps<{\n pframeHandle: Nil | PFrameHandle;\n columns: PTableColumnSpec[];\n}>();\n\n// Teleport for \"Filters\" button\nconst mounted = ref(false);\nonMounted(() => {\n mounted.value = true;\n});\nconst teleportTarget = usePlBlockPageTitleTeleportTarget(\"PlTableFiltersV2\");\nconst showManager = ref(false);\n\n// Check if any filters are active\nconst filtersOn = computed(() => {\n return model.value.filters.length > 0;\n});\n\nfunction makeFilterColumnId(spec: PTableColumnSpec): CanonicalizedJson<PTableColumnId> {\n const id: PTableColumnId =\n spec.type === \"axis\"\n ? { type: \"axis\", id: getAxisId(spec.spec) }\n : { type: \"column\", id: spec.id };\n return canonicalizeJson<PTableColumnId>(id);\n}\n\nconst items = computed<PlAdvancedFilterItem[]>(() => {\n return props.columns.map((col, idx) => {\n const id = makeFilterColumnId(col);\n const label =\n readAnnotation(col.spec, Annotation.Label)?.trim() ?? `Unlabeled ${col.type} ${idx}`;\n const alphabet =\n readDomain(col.spec, Domain.Alphabet) ?? readAnnotation(col.spec, Annotation.Alphabet);\n return {\n id,\n label,\n spec: col.spec,\n alphabet: alphabet ?? undefined,\n };\n });\n});\n\n// Supported filters (same set as FilterSidebar)\nconst supportedFilters = [\n \"isNA\",\n \"isNotNA\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"patternEquals\",\n \"patternNotEquals\",\n \"patternContainSubsequence\",\n \"patternNotContainSubsequence\",\n \"patternMatchesRegularExpression\",\n \"patternFuzzyContainSubsequence\",\n \"equal\",\n \"notEqual\",\n] as (typeof PlAdvancedFilterSupportedFilters)[number][];\n\nfunction handleSuggestOptions(params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchStr: string;\n searchType: \"value\" | \"label\";\n}) {\n if (isNil(props.pframeHandle)) {\n console.warn(\"PFrame handle is not available, cannot fetch suggest options\");\n return [];\n }\n\n const strId = params.columnId as CanonicalizedJson<PTableColumnId>;\n const tableColumnId = parseJson<PTableColumnId>(strId);\n\n if (tableColumnId.type !== \"column\") {\n throw new Error(\"ColumnId should be of type 'column' for suggest options\");\n }\n\n return getUniqueSourceValuesWithLabels(props.pframeHandle, {\n columnId: tableColumnId.id,\n axisIdx: params.axisIdx,\n limit: 100,\n searchQuery: params.searchType === \"label\" ? params.searchStr : undefined,\n searchQueryValue: params.searchType === \"value\" ? params.searchStr : undefined,\n }).then((v) => v.values);\n}\n</script>\n\n<template>\n <Teleport v-if=\"mounted && teleportTarget\" :to=\"teleportTarget\">\n <PlBtnGhost :icon=\"filtersOn ? 'filter-on' : 'filter'\" @click.stop=\"showManager = true\">\n Filters\n </PlBtnGhost>\n </Teleport>\n\n <PlSlideModal v-model=\"showManager\" :close-on-outside-click=\"false\">\n <template #title>Manage Filters</template>\n\n <div :class=\"$style.root\">\n <PlAdvancedFilterComponent\n v-model:filters=\"model as PlAdvancedFilter\"\n :items=\"items\"\n :supported-filters=\"supportedFilters\"\n :get-suggest-options=\"handleSuggestOptions\"\n :enable-dnd=\"false\"\n :enable-add-group-button=\"true\"\n />\n </div>\n </PlSlideModal>\n</template>\n\n<style module>\n.root {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;EA8BA,IAAM,IAAQ,EAAuC,GAAA,aAAoB,EACnE,IAAQ,GAMR,IAAU,EAAI,GAAM;AAC1B,UAAgB;AACd,KAAQ,QAAQ;IAChB;EACF,IAAM,IAAiB,EAAkC,mBAAmB,EACtE,IAAc,EAAI,GAAM,EAGxB,IAAY,QACT,EAAM,MAAM,QAAQ,SAAS,EACpC;EAEF,SAAS,EAAmB,GAA2D;AAKrF,UAAO,EAHL,EAAK,SAAS,SACV;IAAE,MAAM;IAAQ,IAAI,EAAU,EAAK,KAAK;IAAC,GACzC;IAAE,MAAM;IAAU,IAAI,EAAK;IAAI,CACM;;EAG7C,IAAM,IAAQ,QACL,EAAM,QAAQ,KAAK,GAAK,MAAQ;GACrC,IAAM,IAAK,EAAmB,EAAI,EAC5B,IACJ,EAAe,EAAI,MAAM,EAAW,MAAM,EAAE,MAAM,IAAI,aAAa,EAAI,KAAK,GAAG,KAC3E,IACJ,EAAW,EAAI,MAAM,EAAO,SAAS,IAAI,EAAe,EAAI,MAAM,EAAW,SAAS;AACxF,UAAO;IACL;IACA;IACA,MAAM,EAAI;IACV,UAAU,KAAY,KAAA;IACvB;IACD,CACF,EAGI,IAAmB;GACvB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EAED,SAAS,EAAqB,GAK3B;AACD,OAAI,EAAM,EAAM,aAAa,CAE3B,QADA,QAAQ,KAAK,+DAA+D,EACrE,EAAE;GAGX,IAAM,IAAQ,EAAO,UACf,IAAgB,EAA0B,EAAM;AAEtD,OAAI,EAAc,SAAS,SACzB,OAAU,MAAM,0DAA0D;AAG5E,UAAO,EAAgC,EAAM,cAAc;IACzD,UAAU,EAAc;IACxB,SAAS,EAAO;IAChB,OAAO;IACP,aAAa,EAAO,eAAe,UAAU,EAAO,YAAY,KAAA;IAChE,kBAAkB,EAAO,eAAe,UAAU,EAAO,YAAY,KAAA;IACtE,CAAC,CAAC,MAAM,MAAM,EAAE,OAAO;;qCAKR,EAAA,SAAW,EAAA,EAAc,IAAA,GAAA,EAAzC,EAIW,GAAA;;GAJiC,IAAI,EAAA,EAAc;MAC5D,EAEa,EAAA,EAAA,EAAA;GAFA,MAAM,EAAA,QAAS,cAAA;GAA4B,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAA,QAAW,IAAA,CAAA,OAAA,CAAA;;oBAE/E,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAFwF,aAExF,GAAA,CAAA,CAAA,CAAA;;6CAGF,EAae,EAAA,EAAA,EAAA;eAbQ,EAAA;4CAAW,QAAA;GAAG,0BAAwB;;GAChD,OAAK,QAAe,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAAd,kBAAc,GAAA,CAAA,CAAA,CAAA;oBAWzB,CATN,EASM,OAAA,EATA,OAAK,EAAEA,EAAAA,OAAO,KAAI,EAAA,EAAA,CACtB,EAOE,EAAA,EAAA,EAAA;IANQ,SAAS,EAAA;0CAAA,QAAK;IACrB,OAAO,EAAA;IACP,qBAAmB;IACnB,uBAAqB;IACrB,cAAY;IACZ,2BAAyB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.58.
|
|
3
|
+
"version": "1.58.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"lru-cache": "^11.2.2",
|
|
26
26
|
"vue": "^3.5.24",
|
|
27
27
|
"zod": "~3.23.8",
|
|
28
|
-
"@milaboratories/uikit": "2.10.
|
|
29
|
-
"@platforma-sdk/model": "1.58.
|
|
28
|
+
"@milaboratories/uikit": "2.10.42",
|
|
29
|
+
"@platforma-sdk/model": "1.58.19"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@faker-js/faker": "^9.2.0",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"typescript": "~5.9.3",
|
|
41
41
|
"vite": "8.0.0-beta.15",
|
|
42
42
|
"vitest": "^4.0.18",
|
|
43
|
-
"@milaboratories/helpers": "1.13.6",
|
|
44
|
-
"@milaboratories/ts-configs": "1.2.2",
|
|
45
43
|
"@milaboratories/build-configs": "1.5.2",
|
|
44
|
+
"@milaboratories/helpers": "1.13.7",
|
|
45
|
+
"@milaboratories/ts-configs": "1.2.2",
|
|
46
46
|
"@milaboratories/ts-builder": "1.3.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
@@ -336,27 +336,24 @@ const stringMatchesError = computed(() => {
|
|
|
336
336
|
|
|
337
337
|
<!-- bottom element - individual settings for every filter type -->
|
|
338
338
|
<div :class="$style.bottom">
|
|
339
|
-
<
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
group-position="bottom"
|
|
358
|
-
/>
|
|
359
|
-
</template>
|
|
339
|
+
<PlAutocomplete
|
|
340
|
+
v-if="filter.type === 'patternEquals' || filter.type === 'patternNotEquals'"
|
|
341
|
+
v-model="filter.value"
|
|
342
|
+
:options-search="
|
|
343
|
+
(str, type) => getSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str)
|
|
344
|
+
"
|
|
345
|
+
:clearable="true"
|
|
346
|
+
group-position="bottom"
|
|
347
|
+
/>
|
|
348
|
+
<PlAutocompleteMulti
|
|
349
|
+
v-if="filter.type === 'inSet' || filter.type === 'notInSet'"
|
|
350
|
+
v-model="filter.value"
|
|
351
|
+
:options-search="
|
|
352
|
+
(str, type) => getMultiSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str)
|
|
353
|
+
"
|
|
354
|
+
:disabled="inconsistentSourceSelected"
|
|
355
|
+
group-position="bottom"
|
|
356
|
+
/>
|
|
360
357
|
<PlNumberField v-if="isNumericFilter(filter)" v-model="filter.x" group-position="bottom" />
|
|
361
358
|
<PlNumberField v-if="isPositionFilter(filter)" v-model="filter.n" group-position="bottom" />
|
|
362
359
|
<PlTextField
|
|
@@ -5,13 +5,18 @@ import type {
|
|
|
5
5
|
FilterSpec,
|
|
6
6
|
FilterSpecLeaf,
|
|
7
7
|
PColumnSpec,
|
|
8
|
+
PTableColumnId,
|
|
8
9
|
SUniversalPColumnId,
|
|
9
10
|
} from "@platforma-sdk/model";
|
|
10
11
|
import type { SUPPORTED_FILTER_TYPES } from "./constants";
|
|
11
12
|
|
|
12
13
|
export type Operand = "or" | "and";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
// Can be any of string type, but for better type safety we use union of specific types
|
|
16
|
+
export type PlAdvancedFilterColumnId =
|
|
17
|
+
| SUniversalPColumnId
|
|
18
|
+
| CanonicalizedJson<AxisId>
|
|
19
|
+
| CanonicalizedJson<PTableColumnId>;
|
|
15
20
|
|
|
16
21
|
export type RequiredMeta = { id: number; isExpanded?: boolean };
|
|
17
22
|
|
|
@@ -533,6 +533,7 @@ watchEffect(() => {
|
|
|
533
533
|
<PlTableFiltersV2
|
|
534
534
|
v-if="!disableFiltersPanel"
|
|
535
535
|
v-model="filtersState"
|
|
536
|
+
:pframe-handle="'model' in settings ? settings?.model?.fullPframeHandle : undefined"
|
|
536
537
|
:columns="filterableColumns"
|
|
537
538
|
/>
|
|
538
539
|
<PlAgCsvExporter v-if="gridApi && showExportButton" :api="gridApi" />
|
|
@@ -48,12 +48,16 @@ export function useTableState(
|
|
|
48
48
|
const defaultState = makeDefaultState();
|
|
49
49
|
|
|
50
50
|
const sourceId = settings.value.sourceId;
|
|
51
|
-
|
|
51
|
+
const undefinedSourceId = "error" in settings.value && settings.value.error == null;
|
|
52
|
+
if (!sourceId && undefinedSourceId) return defaultState;
|
|
53
|
+
|
|
54
|
+
const suitableSourceId = sourceId ?? tableStateNormalized.value.stateCache.at(-1)?.sourceId;
|
|
55
|
+
if (!suitableSourceId) return defaultState;
|
|
52
56
|
|
|
53
57
|
const cachedState = tableStateNormalized.value.stateCache.find(
|
|
54
|
-
(entry) => entry.sourceId ===
|
|
58
|
+
(entry) => entry.sourceId === suitableSourceId,
|
|
55
59
|
);
|
|
56
|
-
if (!cachedState) return { ...defaultState, sourceId };
|
|
60
|
+
if (!cachedState) return { ...defaultState, sourceId: suitableSourceId };
|
|
57
61
|
|
|
58
62
|
return cachedState;
|
|
59
63
|
},
|
|
@@ -70,12 +74,11 @@ export function useTableState(
|
|
|
70
74
|
(entry) => entry.sourceId === state.sourceId,
|
|
71
75
|
);
|
|
72
76
|
if (stateIdx !== -1) {
|
|
73
|
-
newState.stateCache
|
|
74
|
-
} else {
|
|
75
|
-
const CacheDepth = 5;
|
|
76
|
-
newState.stateCache.push(state);
|
|
77
|
-
newState.stateCache = newState.stateCache.slice(-CacheDepth);
|
|
77
|
+
newState.stateCache.splice(stateIdx, 1);
|
|
78
78
|
}
|
|
79
|
+
const CacheDepth = 5;
|
|
80
|
+
newState.stateCache.push(state);
|
|
81
|
+
newState.stateCache = newState.stateCache.slice(-CacheDepth);
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
if (!isJsonEqual(tableStateNormalized.value, newState)) {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type PTableKey,
|
|
9
9
|
type PTableValue,
|
|
10
10
|
type OutputWithStatus,
|
|
11
|
+
type ErrorLike,
|
|
11
12
|
} from "@platforma-sdk/model";
|
|
12
13
|
import type { PTableHidden } from "./sources/common";
|
|
13
14
|
import type { ComputedRef, MaybeRefOrGetter } from "vue";
|
|
@@ -16,7 +17,7 @@ import canonicalize from "canonicalize";
|
|
|
16
17
|
import { deepClone } from "@milaboratories/helpers";
|
|
17
18
|
|
|
18
19
|
export type PlDataTableSettingsV2Base =
|
|
19
|
-
| { sourceId: null; pending: boolean }
|
|
20
|
+
| { sourceId: null; pending: boolean; error: null | ErrorLike[] }
|
|
20
21
|
| {
|
|
21
22
|
/** Unique source id for state caching */
|
|
22
23
|
sourceId: string;
|
|
@@ -66,7 +67,7 @@ export function usePlDataTableSettingsV2<T>(
|
|
|
66
67
|
|
|
67
68
|
if (!model.ok) {
|
|
68
69
|
model.errors.forEach((e) => console.error("Error in PlDataTableModel:", e));
|
|
69
|
-
settingsBase = { sourceId: null, pending: false };
|
|
70
|
+
settingsBase = { sourceId: null, pending: false, error: model.errors };
|
|
70
71
|
} else if ("sourceId" in options) {
|
|
71
72
|
const sourceIdValue = deepClone(toValue(options.sourceId));
|
|
72
73
|
if (options.sheets) {
|
|
@@ -78,7 +79,7 @@ export function usePlDataTableSettingsV2<T>(
|
|
|
78
79
|
sheets: sheetsValue,
|
|
79
80
|
model: model.value,
|
|
80
81
|
}
|
|
81
|
-
: { sourceId: null, pending: !model.stable };
|
|
82
|
+
: { sourceId: null, pending: !model.stable, error: null };
|
|
82
83
|
} else {
|
|
83
84
|
settingsBase = sourceIdValue
|
|
84
85
|
? {
|
|
@@ -86,7 +87,7 @@ export function usePlDataTableSettingsV2<T>(
|
|
|
86
87
|
sheets: [],
|
|
87
88
|
model: model.value,
|
|
88
89
|
}
|
|
89
|
-
: { sourceId: null, pending: !model.stable };
|
|
90
|
+
: { sourceId: null, pending: !model.stable, error: null };
|
|
90
91
|
}
|
|
91
92
|
} else {
|
|
92
93
|
if (options.sheets) {
|
|
@@ -97,7 +98,7 @@ export function usePlDataTableSettingsV2<T>(
|
|
|
97
98
|
sheets: sheetsValue,
|
|
98
99
|
model: model.value,
|
|
99
100
|
}
|
|
100
|
-
: { sourceId: null, pending: !model.stable };
|
|
101
|
+
: { sourceId: null, pending: !model.stable, error: null };
|
|
101
102
|
} else {
|
|
102
103
|
settingsBase = model.value
|
|
103
104
|
? {
|
|
@@ -105,7 +106,7 @@ export function usePlDataTableSettingsV2<T>(
|
|
|
105
106
|
sheets: [],
|
|
106
107
|
model: model.value,
|
|
107
108
|
}
|
|
108
|
-
: { sourceId: null, pending: !model.stable };
|
|
109
|
+
: { sourceId: null, pending: !model.stable, error: null };
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
return settingsBase;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type {
|
|
3
3
|
PTableColumnSpec,
|
|
4
|
-
PTableColumnId,
|
|
5
|
-
ListOptionBase,
|
|
6
4
|
PlDataTableFiltersWithMeta,
|
|
5
|
+
PFrameHandle,
|
|
6
|
+
PTableColumnId,
|
|
7
|
+
CanonicalizedJson,
|
|
7
8
|
} from "@platforma-sdk/model";
|
|
8
9
|
import {
|
|
9
10
|
canonicalizeJson,
|
|
@@ -11,8 +12,9 @@ import {
|
|
|
11
12
|
Domain,
|
|
12
13
|
readAnnotation,
|
|
13
14
|
readDomain,
|
|
14
|
-
parseJson,
|
|
15
15
|
getAxisId,
|
|
16
|
+
getUniqueSourceValuesWithLabels,
|
|
17
|
+
parseJson,
|
|
16
18
|
} from "@platforma-sdk/model";
|
|
17
19
|
import { computed, onMounted, ref } from "vue";
|
|
18
20
|
import { PlBtnGhost, PlSlideModal, usePlBlockPageTitleTeleportTarget } from "@milaboratories/uikit";
|
|
@@ -23,9 +25,12 @@ import {
|
|
|
23
25
|
type PlAdvancedFilterItem,
|
|
24
26
|
} from "../PlAdvancedFilter";
|
|
25
27
|
import type { PlAdvancedFilterColumnId } from "../PlAdvancedFilter/types";
|
|
28
|
+
import type { Nil } from "@milaboratories/helpers";
|
|
29
|
+
import { isNil } from "es-toolkit";
|
|
26
30
|
|
|
27
31
|
const model = defineModel<PlDataTableFiltersWithMeta>({ required: true });
|
|
28
32
|
const props = defineProps<{
|
|
33
|
+
pframeHandle: Nil | PFrameHandle;
|
|
29
34
|
columns: PTableColumnSpec[];
|
|
30
35
|
}>();
|
|
31
36
|
|
|
@@ -42,16 +47,14 @@ const filtersOn = computed(() => {
|
|
|
42
47
|
return model.value.filters.length > 0;
|
|
43
48
|
});
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
function makeFilterColumnId(spec: PTableColumnSpec): PlAdvancedFilterColumnId {
|
|
50
|
+
function makeFilterColumnId(spec: PTableColumnSpec): CanonicalizedJson<PTableColumnId> {
|
|
47
51
|
const id: PTableColumnId =
|
|
48
52
|
spec.type === "axis"
|
|
49
53
|
? { type: "axis", id: getAxisId(spec.spec) }
|
|
50
54
|
: { type: "column", id: spec.id };
|
|
51
|
-
return canonicalizeJson<PTableColumnId>(id)
|
|
55
|
+
return canonicalizeJson<PTableColumnId>(id);
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
// Convert PTableColumnSpec[] to PlAdvancedFilterItem[]
|
|
55
58
|
const items = computed<PlAdvancedFilterItem[]>(() => {
|
|
56
59
|
return props.columns.map((col, idx) => {
|
|
57
60
|
const id = makeFilterColumnId(col);
|
|
@@ -86,31 +89,31 @@ const supportedFilters = [
|
|
|
86
89
|
"notEqual",
|
|
87
90
|
] as (typeof PlAdvancedFilterSupportedFilters)[number][];
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
function getSuggestOptions(params: {
|
|
92
|
+
function handleSuggestOptions(params: {
|
|
91
93
|
columnId: PlAdvancedFilterColumnId;
|
|
92
94
|
axisIdx?: number;
|
|
93
95
|
searchStr: string;
|
|
94
96
|
searchType: "value" | "label";
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
}) {
|
|
98
|
+
if (isNil(props.pframeHandle)) {
|
|
99
|
+
console.warn("PFrame handle is not available, cannot fetch suggest options");
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
98
102
|
|
|
99
|
-
const
|
|
100
|
-
|
|
103
|
+
const strId = params.columnId as CanonicalizedJson<PTableColumnId>;
|
|
104
|
+
const tableColumnId = parseJson<PTableColumnId>(strId);
|
|
101
105
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return values
|
|
105
|
-
.filter((v) => {
|
|
106
|
-
if (!params.searchStr) return true;
|
|
107
|
-
const str = String(v).toLowerCase();
|
|
108
|
-
return str.includes(params.searchStr.toLowerCase());
|
|
109
|
-
})
|
|
110
|
-
.map((v) => ({ value: v, label: String(v) }));
|
|
111
|
-
} catch {
|
|
112
|
-
return [];
|
|
106
|
+
if (tableColumnId.type !== "column") {
|
|
107
|
+
throw new Error("ColumnId should be of type 'column' for suggest options");
|
|
113
108
|
}
|
|
109
|
+
|
|
110
|
+
return getUniqueSourceValuesWithLabels(props.pframeHandle, {
|
|
111
|
+
columnId: tableColumnId.id,
|
|
112
|
+
axisIdx: params.axisIdx,
|
|
113
|
+
limit: 100,
|
|
114
|
+
searchQuery: params.searchType === "label" ? params.searchStr : undefined,
|
|
115
|
+
searchQueryValue: params.searchType === "value" ? params.searchStr : undefined,
|
|
116
|
+
}).then((v) => v.values);
|
|
114
117
|
}
|
|
115
118
|
</script>
|
|
116
119
|
|
|
@@ -124,17 +127,16 @@ function getSuggestOptions(params: {
|
|
|
124
127
|
<PlSlideModal v-model="showManager" :close-on-outside-click="false">
|
|
125
128
|
<template #title>Manage Filters</template>
|
|
126
129
|
|
|
127
|
-
<div
|
|
130
|
+
<div :class="$style.root">
|
|
128
131
|
<PlAdvancedFilterComponent
|
|
129
132
|
v-model:filters="model as PlAdvancedFilter"
|
|
130
133
|
:items="items"
|
|
131
134
|
:supported-filters="supportedFilters"
|
|
132
|
-
:get-suggest-options="
|
|
135
|
+
:get-suggest-options="handleSuggestOptions"
|
|
133
136
|
:enable-dnd="false"
|
|
134
137
|
:enable-add-group-button="true"
|
|
135
138
|
/>
|
|
136
139
|
</div>
|
|
137
|
-
<div v-else>No filters applicable</div>
|
|
138
140
|
</PlSlideModal>
|
|
139
141
|
</template>
|
|
140
142
|
|