@platforma-sdk/ui-vue 1.72.0 → 1.73.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 +10 -10
- 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 +14 -0
- 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 +3 -8
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js +46 -54
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js.map +1 -1
- package/package.json +5 -5
- package/src/components/PlDatasetSelector/PlDatasetSelector.vue +20 -34
- package/src/components/PlDatasetSelector/__tests__/PlDatasetSelector.jsdomtest.ts +32 -20
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @platforma-sdk/ui-vue@1.
|
|
3
|
+
> @platforma-sdk/ui-vue@1.73.0 build /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder build --target browser-lib
|
|
5
5
|
|
|
6
6
|
Building browser-lib project...
|
|
@@ -16,7 +16,7 @@ Building browser-lib project...
|
|
|
16
16
|
rendering chunks...
|
|
17
17
|
|
|
18
18
|
[vite:dts] Start generate declaration files...
|
|
19
|
-
[vite:dts] Declaration files built in
|
|
19
|
+
[vite:dts] Declaration files built in 5519ms.
|
|
20
20
|
|
|
21
21
|
computing gzip size...
|
|
22
22
|
dist/components/PlAnnotations/components/PlAnnotations.vue?vue&type=style&index=0&lang.css 0.04 kB │ gzip: 0.06 kB
|
|
@@ -24,7 +24,7 @@ dist/components/PlAgCellStatusTag/PlAgCellStatusTag.vue_vue_type_style_index_0_l
|
|
|
24
24
|
dist/components/BlockLayout.vue?vue&type=style&index=0&lang.css 0.05 kB │ gzip: 0.07 kB
|
|
25
25
|
dist/components/PlAgDataTable/PlAgDataTableSheets.vue?vue&type=style&index=0&lang.css 0.06 kB │ gzip: 0.08 kB
|
|
26
26
|
dist/components/PlAnnotations/components/PlAnnotationsModal.vue?vue&type=style&index=0&lang.css 0.07 kB │ gzip: 0.08 kB
|
|
27
|
-
dist/components/PlDatasetSelector/PlDatasetSelector.
|
|
27
|
+
dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_style_index_0_scoped_cb8d3a14_lang.css 0.08 kB │ gzip: 0.09 kB
|
|
28
28
|
dist/components/PlAgDataTable/PlAgDataTableV2.vue?vue&type=style&index=0&lang.css 0.09 kB │ gzip: 0.10 kB
|
|
29
29
|
dist/components/PlAnnotations/components/FilterSidebar.vue?vue&type=style&index=0&lang.css 0.11 kB │ gzip: 0.09 kB
|
|
30
30
|
dist/components/PlAgChartHistogramCell/PlAgChartHistogramCell.vue_vue_type_style_index_0_lang.css 0.16 kB │ gzip: 0.13 kB
|
|
@@ -203,11 +203,11 @@ dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue_vue_
|
|
|
203
203
|
dist/components/PlAgDataTable/PlAgDataTableSheets.vue_vue_type_script_setup_true_lang.js 2.45 kB │ gzip: 1.17 kB │ map: 5.01 kB
|
|
204
204
|
dist/components/PlAnnotations/components/PlAnnotations.vue_vue_type_script_setup_true_lang.js 2.69 kB │ gzip: 1.12 kB │ map: 4.16 kB
|
|
205
205
|
dist/lib.js 2.73 kB │ gzip: 0.57 kB │ map: 3.98 kB
|
|
206
|
+
dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_script_setup_true_lang.js 2.90 kB │ gzip: 1.14 kB │ map: 6.46 kB
|
|
206
207
|
dist/components/PlAgDataTable/compositions/useGrid.js 2.91 kB │ gzip: 1.29 kB │ map: 6.51 kB
|
|
207
208
|
dist/components/PlAgColumnHeader/PlAgColumnHeader.vue_vue_type_script_setup_true_lang.js 2.93 kB │ gzip: 1.26 kB │ map: 7.97 kB
|
|
208
209
|
dist/components/PlAgDataTable/sources/row-number.js 2.99 kB │ gzip: 1.31 kB │ map: 7.42 kB
|
|
209
210
|
dist/defineApp.js 3.01 kB │ gzip: 1.05 kB │ map: 14.38 kB
|
|
210
|
-
dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_script_setup_true_lang.js 3.18 kB │ gzip: 1.24 kB │ map: 7.33 kB
|
|
211
211
|
dist/plugins/Monetization/LimitCard.vue_vue_type_script_setup_true_lang.js 3.31 kB │ gzip: 1.15 kB │ map: 9.08 kB
|
|
212
212
|
dist/composition/fileContent.js 3.78 kB │ gzip: 1.45 kB │ map: 12.95 kB
|
|
213
213
|
dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue_vue_type_script_setup_true_lang.js 3.83 kB │ gzip: 1.64 kB │ map: 6.89 kB
|
|
@@ -228,12 +228,12 @@ dist/components/PlAdvancedFilter/FilterEditor.vue_vue_type_script_setup_true_lan
|
|
|
228
228
|
dist/components/PlAgDataTable/PlAgDataTableV2.vue_vue_type_script_setup_true_lang.js 12.31 kB │ gzip: 3.90 kB │ map: 29.22 kB
|
|
229
229
|
|
|
230
230
|
[33m[33m[PLUGIN_TIMINGS] Warning:[0m Your build spent significant time in plugins. Here is a breakdown:
|
|
231
|
-
- sourcemaps (
|
|
232
|
-
- vite:dts (
|
|
233
|
-
- vite:vue (
|
|
234
|
-
- vite:css-post (
|
|
235
|
-
- vite:css (
|
|
231
|
+
- sourcemaps (34%)
|
|
232
|
+
- vite:dts (24%)
|
|
233
|
+
- vite:vue (11%)
|
|
234
|
+
- vite:css-post (11%)
|
|
235
|
+
- vite:css (8%)
|
|
236
236
|
See https://rolldown.rs/options/checks#plugintimings for more details.
|
|
237
237
|
[39m
|
|
238
|
-
[32m✓ built in 6.
|
|
238
|
+
[32m✓ built in 6.42s[39m
|
|
239
239
|
Build completed successfully
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @platforma-sdk/ui-vue@1.
|
|
3
|
+
> @platforma-sdk/ui-vue@1.73.0 formatter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder formatter --check
|
|
5
5
|
|
|
6
6
|
Checking formatting...
|
|
@@ -8,5 +8,5 @@ Checking formatting...
|
|
|
8
8
|
Checking formatting...
|
|
9
9
|
|
|
10
10
|
All matched files use the correct format.
|
|
11
|
-
Finished in
|
|
11
|
+
Finished in 3528ms on 137 files using 8 threads.
|
|
12
12
|
Format check completed successfully
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @platforma-sdk/ui-vue@1.
|
|
3
|
+
> @platforma-sdk/ui-vue@1.73.0 linter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder linter --check
|
|
5
5
|
|
|
6
6
|
Linting project...
|
|
7
7
|
↳ oxlint --config /home/runner/_work/platforma/platforma/sdk/ui-vue/.oxlintrc.json --deny-warnings
|
|
8
8
|
Found 0 warnings and 0 errors.
|
|
9
|
-
Finished in
|
|
9
|
+
Finished in 30ms on 120 files with 98 rules using 8 threads.
|
|
10
10
|
Linting completed successfully
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @platforma-sdk/ui-vue@1.
|
|
3
|
+
> @platforma-sdk/ui-vue@1.73.0 types:check /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder type-check --target browser-lib
|
|
5
5
|
|
|
6
6
|
↳ vue-tsc.js --noEmit --project ./tsconfig.json --customConditions ,
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @platforma-sdk/ui-vue
|
|
2
2
|
|
|
3
|
+
## 1.73.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2df0aff: `buildDatasetOptions`: scope filter discovery to the result pool only (block outputs and prerun no longer pollute the filter dropdown), add a `filter` predicate to restrict eligible filter columns, and skip filter matches without a PlRef instead of throwing. Removes the need for callers to wrap `buildDatasetOptions` in try/catch.
|
|
8
|
+
|
|
9
|
+
`tableBuilder.addPrimary`: drop a `PrimaryRef.filter` whose `resolveColumn` produced no spec, so a stale or malformed filter ref no longer causes `pframes.build-table` to panic with `field "spec" not found and inputs locked`.
|
|
10
|
+
|
|
11
|
+
`PlDatasetSelector`: always render the filter dropdown, regardless of whether the selected dataset has compatible filters; the dropdown is clearable and uses an empty selection (instead of a synthetic "No filter" entry) to mean "no filter applied". Removed the `noFilterLabel` prop.
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [2df0aff]
|
|
14
|
+
- @platforma-sdk/model@1.73.0
|
|
15
|
+
- @milaboratories/uikit@2.13.4
|
|
16
|
+
|
|
3
17
|
## 1.72.0
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotations.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Props as BaseProps } from \"./FilterSidebar.vue\";\nexport type Props = Omit<BaseProps, \"step\" | \"onUpdateStep\"> & {\n annotation: Annotation;\n onUpdateAnnotation: (annotation: Annotation) => void;\n onDeleteSchema?: () => void;\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, effect, shallowRef } from \"vue\";\n\nimport { isNil } from \"@milaboratories/helpers\";\nimport { produce } from \"immer\";\nimport { PlSidebarGroup, useConfirm } from \"@milaboratories/uikit\";\n\nimport type { Annotation, Filter } from \"../types\";\nimport AnnotationsSidebar from \"./AnnotationsSidebar.vue\";\nimport FilterSidebar from \"./FilterSidebar.vue\";\n\nconst props = defineProps<Props>();\n\nconst selectedStepId = shallowRef<undefined | number>(undefined);\n\nconst selectedStep = computed(() => {\n return isNil(selectedStepId.value) || isNil(props.annotation)\n ? undefined\n : props.annotation.steps.find((step) => step.id === selectedStepId.value);\n});\n\neffect(function setDefaultStepId() {\n if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {\n selectedStepId.value = props.annotation.steps[0].id;\n }\n});\n\nconst confirmResetSchema = useConfirm({\n title: \"Reset Schema\",\n message: \"Are you sure you want to reset the schema? This action cannot be undone.\",\n confirmLabel: \"Yes, reset\",\n cancelLabel: \"No, cancel\",\n});\n\nasync function handleDeleteSchema() {\n if (await confirmResetSchema()) {\n selectedStepId.value = undefined;\n props.onDeleteSchema?.();\n }\n}\n\nfunction updateSelectedStepId(id: undefined | number) {\n selectedStepId.value = id;\n}\n\nfunction updateSelectedStep(step: Filter) {\n props.onUpdateAnnotation(\n produce(props.annotation, (draft) => {\n const idx = draft.steps.findIndex((s) => s.id === step.id);\n if (idx !== -1) {\n draft.steps[idx] = step;\n }\n }),\n );\n}\n</script>\n\n<template>\n <PlSidebarGroup>\n <template #item-0>\n <AnnotationsSidebar\n :annotation=\"props.annotation\"\n :selected-step-id=\"selectedStepId\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-update-selected-step-id=\"updateSelectedStepId\"\n :class=\"$style.sidebarItem\"\n @delete-schema=\"handleDeleteSchema\"\n />\n </template>\n <template #item-1>\n <FilterSidebar\n v-if=\"selectedStep\"\n :step=\"selectedStep\"\n :on-update-step=\"updateSelectedStep\"\n :class=\"$style.sidebarItem\"\n :columns=\"props.columns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :hasSelectedColumns=\"props.hasSelectedColumns\"\n :getValuesForSelectedColumns=\"props.getValuesForSelectedColumns\"\n />\n </template>\n </PlSidebarGroup>\n</template>\n\n<style module>\n.sidebarItem {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAoBA,IAAM,IAAQ,GAER,IAAiB,EAA+B,KAAA,EAAU,EAE1D,IAAe,QACZ,EAAM,EAAe,MAAM,IAAI,EAAM,EAAM,WAAU,GACxD,KAAA,IACA,EAAM,WAAW,MAAM,MAAM,MAAS,EAAK,OAAO,EAAe,MAAM,CAC3E;AAEF,IAAO,WAA4B;AACjC,GAAI,EAAe,UAAU,KAAA,KAAa,EAAM,WAAW,MAAM,SAAS,MACxE,EAAe,QAAQ,EAAM,WAAW,MAAM,GAAG;IAEnD;EAEF,IAAM,IAAqB,EAAW;GACpC,OAAO;GACP,SAAS;GACT,cAAc;GACd,aAAa;GACd,CAAC;EAEF,eAAe,IAAqB;AAClC,GAAI,MAAM,GAAoB,KAC5B,EAAe,QAAQ,KAAA,GACvB,EAAM,kBAAkB;;EAI5B,SAAS,EAAqB,GAAwB;AACpD,KAAe,QAAQ;;EAGzB,SAAS,EAAmB,GAAc;AACxC,KAAM,mBACJ,EAAQ,EAAM,aAAa,MAAU;IACnC,IAAM,IAAM,EAAM,MAAM,WAAW,MAAM,EAAE,OAAO,EAAK,GAAG;AAC1D,IAAI,MAAQ,OACV,EAAM,MAAM,KAAO;KAErB,CACH;;yBAKD,EAuBiB,EAAA,EAAA,EAAA,MAAA;GAtBJ,UAAM,QAQb,CAPF,EAOE,GAAA;IANC,YAAY,EAAM;IAClB,oBAAkB,EAAA;IAClB,wBAAsB,EAAM;IAC5B,8BAA4B;IAC5B,OAAK,EAAEA,EAAAA,OAAO,YAAW;IACzB,gBAAe;;;;;;;GAGT,UAAM,
|
|
1
|
+
{"version":3,"file":"PlAnnotations.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Props as BaseProps } from \"./FilterSidebar.vue\";\nexport type Props = Omit<BaseProps, \"step\" | \"onUpdateStep\"> & {\n annotation: Annotation;\n onUpdateAnnotation: (annotation: Annotation) => void;\n onDeleteSchema?: () => void;\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, effect, shallowRef } from \"vue\";\n\nimport { isNil } from \"@milaboratories/helpers\";\nimport { produce } from \"immer\";\nimport { PlSidebarGroup, useConfirm } from \"@milaboratories/uikit\";\n\nimport type { Annotation, Filter } from \"../types\";\nimport AnnotationsSidebar from \"./AnnotationsSidebar.vue\";\nimport FilterSidebar from \"./FilterSidebar.vue\";\n\nconst props = defineProps<Props>();\n\nconst selectedStepId = shallowRef<undefined | number>(undefined);\n\nconst selectedStep = computed(() => {\n return isNil(selectedStepId.value) || isNil(props.annotation)\n ? undefined\n : props.annotation.steps.find((step) => step.id === selectedStepId.value);\n});\n\neffect(function setDefaultStepId() {\n if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {\n selectedStepId.value = props.annotation.steps[0].id;\n }\n});\n\nconst confirmResetSchema = useConfirm({\n title: \"Reset Schema\",\n message: \"Are you sure you want to reset the schema? This action cannot be undone.\",\n confirmLabel: \"Yes, reset\",\n cancelLabel: \"No, cancel\",\n});\n\nasync function handleDeleteSchema() {\n if (await confirmResetSchema()) {\n selectedStepId.value = undefined;\n props.onDeleteSchema?.();\n }\n}\n\nfunction updateSelectedStepId(id: undefined | number) {\n selectedStepId.value = id;\n}\n\nfunction updateSelectedStep(step: Filter) {\n props.onUpdateAnnotation(\n produce(props.annotation, (draft) => {\n const idx = draft.steps.findIndex((s) => s.id === step.id);\n if (idx !== -1) {\n draft.steps[idx] = step;\n }\n }),\n );\n}\n</script>\n\n<template>\n <PlSidebarGroup>\n <template #item-0>\n <AnnotationsSidebar\n :annotation=\"props.annotation\"\n :selected-step-id=\"selectedStepId\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-update-selected-step-id=\"updateSelectedStepId\"\n :class=\"$style.sidebarItem\"\n @delete-schema=\"handleDeleteSchema\"\n />\n </template>\n <template #item-1>\n <FilterSidebar\n v-if=\"selectedStep\"\n :step=\"selectedStep\"\n :on-update-step=\"updateSelectedStep\"\n :class=\"$style.sidebarItem\"\n :columns=\"props.columns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :hasSelectedColumns=\"props.hasSelectedColumns\"\n :getValuesForSelectedColumns=\"props.getValuesForSelectedColumns\"\n />\n </template>\n </PlSidebarGroup>\n</template>\n\n<style module>\n.sidebarItem {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAoBA,IAAM,IAAQ,GAER,IAAiB,EAA+B,KAAA,EAAU,EAE1D,IAAe,QACZ,EAAM,EAAe,MAAM,IAAI,EAAM,EAAM,WAAU,GACxD,KAAA,IACA,EAAM,WAAW,MAAM,MAAM,MAAS,EAAK,OAAO,EAAe,MAAM,CAC3E;AAEF,IAAO,WAA4B;AACjC,GAAI,EAAe,UAAU,KAAA,KAAa,EAAM,WAAW,MAAM,SAAS,MACxE,EAAe,QAAQ,EAAM,WAAW,MAAM,GAAG;IAEnD;EAEF,IAAM,IAAqB,EAAW;GACpC,OAAO;GACP,SAAS;GACT,cAAc;GACd,aAAa;GACd,CAAC;EAEF,eAAe,IAAqB;AAClC,GAAI,MAAM,GAAoB,KAC5B,EAAe,QAAQ,KAAA,GACvB,EAAM,kBAAkB;;EAI5B,SAAS,EAAqB,GAAwB;AACpD,KAAe,QAAQ;;EAGzB,SAAS,EAAmB,GAAc;AACxC,KAAM,mBACJ,EAAQ,EAAM,aAAa,MAAU;IACnC,IAAM,IAAM,EAAM,MAAM,WAAW,MAAM,EAAE,OAAO,EAAK,GAAG;AAC1D,IAAI,MAAQ,OACV,EAAM,MAAM,KAAO;KAErB,CACH;;yBAKD,EAuBiB,EAAA,EAAA,EAAA,MAAA;GAtBJ,UAAM,QAQb,CAPF,EAOE,GAAA;IANC,YAAY,EAAM;IAClB,oBAAkB,EAAA;IAClB,wBAAsB,EAAM;IAC5B,8BAA4B;IAC5B,OAAK,EAAEA,EAAAA,OAAO,YAAW;IACzB,gBAAe;;;;;;;GAGT,UAAM,QAiBZ,CAfK,EAAA,SAAA,GAAA,EADR,EASE,GAAA;;IAPC,MAAM,EAAA;IACN,kBAAgB;IAChB,OAAK,EAAEA,EAAAA,OAAO,YAAW;IACzB,SAAS,EAAM;IACf,uBAAqB,EAAM;IAC3B,oBAAoB,EAAM;IAC1B,6BAA6B,EAAM"}
|
|
@@ -2,7 +2,7 @@ import e from "../../_virtual/_plugin-vue_export-helper.js";
|
|
|
2
2
|
import t from "./PlDatasetSelector.vue2.js";
|
|
3
3
|
import './PlDatasetSelector.style.css';/* empty css */
|
|
4
4
|
//#region src/components/PlDatasetSelector/PlDatasetSelector.vue
|
|
5
|
-
var n = /* @__PURE__ */ e(t, [["__scopeId", "data-v-
|
|
5
|
+
var n = /* @__PURE__ */ e(t, [["__scopeId", "data-v-cb8d3a14"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { n as default };
|
|
8
8
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlDatasetSelector.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 *
|
|
1
|
+
{"version":3,"file":"PlDatasetSelector.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 * The filter dropdown is always rendered and is clearable — leaving it empty\n * means \"no filter\". When the selected dataset has no compatible filters, the\n * dropdown opens to an empty option list.\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 /** 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 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 filterOptions = computed<ListOption<PlRef>[]>(\n () => currentDatasetOption.value?.filters?.map((f) => ({ label: f.label, value: f.ref })) ?? [],\n);\n\n// Resolve from `props.options` directly — `currentDatasetOption` may not have\n// recomputed yet when this runs synchronously inside a change handler.\nfunction findOption(dataset: PlRef): DatasetOption | undefined {\n return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));\n}\n\nfunction onDatasetChange(dataset: PlRef | undefined) {\n if (dataset === undefined) {\n model.value = undefined;\n return;\n }\n model.value = createDatasetSelection(createPrimaryRef(dataset), findOption(dataset)?.enrichments);\n}\n\nfunction onFilterChange(filter: PlRef | undefined) {\n const dataset = selectedDataset.value;\n if (!dataset) return;\n model.value = createDatasetSelection(\n createPrimaryRef(dataset, filter),\n findOption(dataset)?.enrichments,\n );\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 :model-value=\"selectedFilter\"\n :options=\"filterOptions\"\n :label=\"filterLabel\"\n :placeholder=\"filterPlaceholder\"\n :disabled=\"disabled\"\n clearable\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":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.pl-dataset-selector[data-v-
|
|
1
|
+
.pl-dataset-selector[data-v-cb8d3a14]{flex-direction:column;gap:12px;display:flex}
|
|
@@ -2,9 +2,9 @@ import { DatasetOption, DatasetSelection } from '@platforma-sdk/model';
|
|
|
2
2
|
/**
|
|
3
3
|
* Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* filter
|
|
7
|
-
* dropdown
|
|
5
|
+
* The filter dropdown is always rendered and is clearable — leaving it empty
|
|
6
|
+
* means "no filter". When the selected dataset has no compatible filters, the
|
|
7
|
+
* dropdown opens to an empty option list.
|
|
8
8
|
*
|
|
9
9
|
* The emitted value bundles the user's pick (`primary`) with the auto-attached
|
|
10
10
|
* `enrichments` payload from the matching `DatasetOption`. Enrichments are
|
|
@@ -29,8 +29,6 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
29
29
|
filterLabel?: string;
|
|
30
30
|
/** Placeholder for the filter dropdown. */
|
|
31
31
|
filterPlaceholder?: string;
|
|
32
|
-
/** Label of the "no filter" entry prepended to the filter options. */
|
|
33
|
-
noFilterLabel?: string;
|
|
34
32
|
/** Show a clear button on the dataset dropdown. */
|
|
35
33
|
clearable?: boolean;
|
|
36
34
|
/** Mark the dataset dropdown as required. */
|
|
@@ -58,8 +56,6 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
58
56
|
filterLabel?: string;
|
|
59
57
|
/** Placeholder for the filter dropdown. */
|
|
60
58
|
filterPlaceholder?: string;
|
|
61
|
-
/** Label of the "no filter" entry prepended to the filter options. */
|
|
62
|
-
noFilterLabel?: string;
|
|
63
59
|
/** Show a clear button on the dataset dropdown. */
|
|
64
60
|
clearable?: boolean;
|
|
65
61
|
/** Mark the dataset dropdown as required. */
|
|
@@ -80,7 +76,6 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
80
76
|
disabled: boolean;
|
|
81
77
|
filterLabel: string;
|
|
82
78
|
filterPlaceholder: string;
|
|
83
|
-
noFilterLabel: string;
|
|
84
79
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>, Readonly<{
|
|
85
80
|
tooltip?: () => unknown;
|
|
86
81
|
}> & {
|
|
@@ -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":"AAyJA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAS,MAAM,sBAAsB,CAAC;AAOnF;;;;;;;;;;GAUG;;iBA4GU,gBAAgB,GAAG,SAAS;;IAnGrC,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,mDAAmD;gBACvC,OAAO;IACnB,6CAA6C;eAClC,OAAO;IAClB,+BAA+B;eACpB,OAAO;;;;iBA8ET,gBAAgB,GAAG,SAAS;;IAnGrC,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,mDAAmD;gBACvC,OAAO;IACnB,6CAA6C;eAClC,OAAO;IAClB,+BAA+B;eACpB,OAAO;;;;;WAlBV,MAAM;iBAQA,MAAM;aAVV,QAAQ,CAAC,aAAa,EAAE,CAAC;YAI1B,MAAM;0BAEQ,MAAM;eAUjB,OAAO;cAER,OAAO;cAEP,OAAO;iBARJ,MAAM;uBAEA,MAAM;;cArBlB,MAAM,OAAO;;cAAb,MAAM,OAAO;;AAFzB,wBAqPK;AAcL,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { computed as e,
|
|
2
|
-
import { createDatasetSelection as
|
|
3
|
-
import { PlDropdown as
|
|
1
|
+
import { computed as e, createElementBlock as t, createSlots as n, createVNode as r, defineComponent as i, mergeModels as a, openBlock as o, renderSlot as s, unref as c, useModel as l, useSlots as u, withCtx as d } from "vue";
|
|
2
|
+
import { createDatasetSelection as f, createPrimaryRef as p, plRefsEqual as m } from "@platforma-sdk/model";
|
|
3
|
+
import { PlDropdown as h, PlDropdownRef as g } from "@milaboratories/uikit";
|
|
4
4
|
//#region src/components/PlDatasetSelector/PlDatasetSelector.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var
|
|
5
|
+
var _ = { class: "pl-dataset-selector" }, v = /* @__PURE__ */ i({
|
|
6
6
|
name: "PlDatasetSelector",
|
|
7
|
-
props: /* @__PURE__ */
|
|
7
|
+
props: /* @__PURE__ */ a({
|
|
8
8
|
options: { default: void 0 },
|
|
9
9
|
label: { default: void 0 },
|
|
10
10
|
helper: { default: void 0 },
|
|
@@ -13,7 +13,6 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
13
13
|
placeholder: { default: "..." },
|
|
14
14
|
filterLabel: { default: "" },
|
|
15
15
|
filterPlaceholder: { default: "..." },
|
|
16
|
-
noFilterLabel: { default: "No filter" },
|
|
17
16
|
clearable: {
|
|
18
17
|
type: Boolean,
|
|
19
18
|
default: !1
|
|
@@ -31,50 +30,43 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
31
30
|
modelModifiers: {}
|
|
32
31
|
}),
|
|
33
32
|
emits: ["update:modelValue"],
|
|
34
|
-
setup(
|
|
35
|
-
let
|
|
36
|
-
let e =
|
|
37
|
-
if (e) return
|
|
38
|
-
}),
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}))] : [];
|
|
47
|
-
}), O = e(() => C.value ?? null);
|
|
48
|
-
function k(e, t) {
|
|
33
|
+
setup(i) {
|
|
34
|
+
let a = u(), v = l(i, "modelValue"), y = i, b = e(() => v.value?.primary.column), x = e(() => v.value?.primary.filter), S = e(() => {
|
|
35
|
+
let e = b.value;
|
|
36
|
+
if (e) return y.options?.find((t) => m(t.primary.ref, e, !0));
|
|
37
|
+
}), C = e(() => y.options?.map((e) => e.primary)), w = e(() => S.value?.filters?.map((e) => ({
|
|
38
|
+
label: e.label,
|
|
39
|
+
value: e.ref
|
|
40
|
+
})) ?? []);
|
|
41
|
+
function T(e) {
|
|
42
|
+
return y.options?.find((t) => m(t.primary.ref, e, !0));
|
|
43
|
+
}
|
|
44
|
+
function E(e) {
|
|
49
45
|
if (e === void 0) {
|
|
50
|
-
|
|
46
|
+
v.value = void 0;
|
|
51
47
|
return;
|
|
52
48
|
}
|
|
53
|
-
|
|
54
|
-
b.value = m(h(e, t), n?.enrichments);
|
|
55
|
-
}
|
|
56
|
-
function A(e) {
|
|
57
|
-
k(e, void 0);
|
|
49
|
+
v.value = f(p(e), T(e)?.enrichments);
|
|
58
50
|
}
|
|
59
|
-
function
|
|
60
|
-
let t =
|
|
61
|
-
t &&
|
|
51
|
+
function D(e) {
|
|
52
|
+
let t = b.value;
|
|
53
|
+
t && (v.value = f(p(t, e), T(t)?.enrichments));
|
|
62
54
|
}
|
|
63
|
-
return (e,
|
|
64
|
-
"model-value":
|
|
65
|
-
options:
|
|
66
|
-
label:
|
|
67
|
-
helper:
|
|
68
|
-
"loading-options-helper":
|
|
69
|
-
error:
|
|
70
|
-
placeholder:
|
|
71
|
-
clearable:
|
|
72
|
-
required:
|
|
73
|
-
disabled:
|
|
74
|
-
"onUpdate:modelValue":
|
|
75
|
-
},
|
|
55
|
+
return (e, l) => (o(), t("div", _, [r(c(g), {
|
|
56
|
+
"model-value": b.value,
|
|
57
|
+
options: C.value,
|
|
58
|
+
label: i.label,
|
|
59
|
+
helper: i.helper,
|
|
60
|
+
"loading-options-helper": i.loadingOptionsHelper,
|
|
61
|
+
error: i.error,
|
|
62
|
+
placeholder: i.placeholder,
|
|
63
|
+
clearable: i.clearable,
|
|
64
|
+
required: i.required,
|
|
65
|
+
disabled: i.disabled,
|
|
66
|
+
"onUpdate:modelValue": E
|
|
67
|
+
}, n({ _: 2 }, [a.tooltip ? {
|
|
76
68
|
name: "tooltip",
|
|
77
|
-
fn:
|
|
69
|
+
fn: d(() => [s(e.$slots, "tooltip", {}, void 0, !0)]),
|
|
78
70
|
key: "0"
|
|
79
71
|
} : void 0]), 1032, [
|
|
80
72
|
"model-value",
|
|
@@ -87,24 +79,24 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
87
79
|
"clearable",
|
|
88
80
|
"required",
|
|
89
81
|
"disabled"
|
|
90
|
-
]),
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"onUpdate:modelValue":
|
|
82
|
+
]), r(c(h), {
|
|
83
|
+
"model-value": x.value,
|
|
84
|
+
options: w.value,
|
|
85
|
+
label: i.filterLabel,
|
|
86
|
+
placeholder: i.filterPlaceholder,
|
|
87
|
+
disabled: i.disabled,
|
|
88
|
+
clearable: "",
|
|
89
|
+
"onUpdate:modelValue": D
|
|
98
90
|
}, null, 8, [
|
|
99
91
|
"model-value",
|
|
100
92
|
"options",
|
|
101
93
|
"label",
|
|
102
94
|
"placeholder",
|
|
103
95
|
"disabled"
|
|
104
|
-
])
|
|
96
|
+
])]));
|
|
105
97
|
}
|
|
106
98
|
});
|
|
107
99
|
//#endregion
|
|
108
|
-
export {
|
|
100
|
+
export { v as default };
|
|
109
101
|
|
|
110
102
|
//# sourceMappingURL=PlDatasetSelector.vue2.js.map
|
|
@@ -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 {@link DatasetSelection}.\n *\n *
|
|
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 * The filter dropdown is always rendered and is clearable — leaving it empty\n * means \"no filter\". When the selected dataset has no compatible filters, the\n * dropdown opens to an empty option list.\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 /** 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 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 filterOptions = computed<ListOption<PlRef>[]>(\n () => currentDatasetOption.value?.filters?.map((f) => ({ label: f.label, value: f.ref })) ?? [],\n);\n\n// Resolve from `props.options` directly — `currentDatasetOption` may not have\n// recomputed yet when this runs synchronously inside a change handler.\nfunction findOption(dataset: PlRef): DatasetOption | undefined {\n return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));\n}\n\nfunction onDatasetChange(dataset: PlRef | undefined) {\n if (dataset === undefined) {\n model.value = undefined;\n return;\n }\n model.value = createDatasetSelection(createPrimaryRef(dataset), findOption(dataset)?.enrichments);\n}\n\nfunction onFilterChange(filter: PlRef | undefined) {\n const dataset = selectedDataset.value;\n if (!dataset) return;\n model.value = createDatasetSelection(\n createPrimaryRef(dataset, filter),\n findOption(dataset)?.enrichments,\n );\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 :model-value=\"selectedFilter\"\n :options=\"filterOptions\"\n :label=\"filterLabel\"\n :placeholder=\"filterPlaceholder\"\n :disabled=\"disabled\"\n clearable\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,GAwCR,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,IAAgB,QACd,EAAqB,OAAO,SAAS,KAAK,OAAO;GAAE,OAAO,EAAE;GAAO,OAAO,EAAE;GAAK,EAAE,IAAI,EAAE,CAChG;EAID,SAAS,EAAW,GAA2C;AAC7D,UAAO,EAAM,SAAS,MAAM,MAAM,EAAY,EAAE,QAAQ,KAAK,GAAS,GAAK,CAAC;;EAG9E,SAAS,EAAgB,GAA4B;AACnD,OAAI,MAAY,KAAA,GAAW;AACzB,MAAM,QAAQ,KAAA;AACd;;AAEF,KAAM,QAAQ,EAAuB,EAAiB,EAAQ,EAAE,EAAW,EAAQ,EAAE,YAAY;;EAGnG,SAAS,EAAe,GAA2B;GACjD,IAAM,IAAU,EAAgB;AAC3B,SACL,EAAM,QAAQ,EACZ,EAAiB,GAAS,EAAO,EACjC,EAAW,EAAQ,EAAE,YACtB;;yBAKD,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;;;;;;;;;;;;;MAG3B,EAQE,EAAA,EAAA,EAAA;GAPC,eAAa,EAAA;GACb,SAAS,EAAA;GACT,OAAO,EAAA;GACP,aAAa,EAAA;GACb,UAAU,EAAA;GACX,WAAA;GACC,uBAAoB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.73.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"vue": "^3.5.24",
|
|
28
28
|
"zod": "~3.25.76",
|
|
29
29
|
"@milaboratories/pf-spec-driver": "1.3.9",
|
|
30
|
-
"@
|
|
31
|
-
"@
|
|
30
|
+
"@platforma-sdk/model": "1.73.0",
|
|
31
|
+
"@milaboratories/uikit": "2.13.4",
|
|
32
32
|
"@milaboratories/pl-model-common": "1.39.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"typescript": "~5.9.3",
|
|
46
46
|
"vite": "^8.0.6",
|
|
47
47
|
"vitest": "^4.1.3",
|
|
48
|
+
"@milaboratories/build-configs": "2.0.0",
|
|
48
49
|
"@milaboratories/helpers": "1.14.1",
|
|
49
50
|
"@milaboratories/ts-builder": "1.3.2",
|
|
50
|
-
"@milaboratories/ts-configs": "1.2.3"
|
|
51
|
-
"@milaboratories/build-configs": "2.0.0"
|
|
51
|
+
"@milaboratories/ts-configs": "1.2.3"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"dev": "ts-builder serve --target browser-lib",
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* filter
|
|
7
|
-
* dropdown
|
|
5
|
+
* The filter dropdown is always rendered and is clearable — leaving it empty
|
|
6
|
+
* means "no filter". When the selected dataset has no compatible filters, the
|
|
7
|
+
* dropdown opens to an empty option list.
|
|
8
8
|
*
|
|
9
9
|
* The emitted value bundles the user's pick (`primary`) with the auto-attached
|
|
10
10
|
* `enrichments` payload from the matching `DatasetOption`. Enrichments are
|
|
@@ -46,8 +46,6 @@ const props = withDefaults(
|
|
|
46
46
|
filterLabel?: string;
|
|
47
47
|
/** Placeholder for the filter dropdown. */
|
|
48
48
|
filterPlaceholder?: string;
|
|
49
|
-
/** Label of the "no filter" entry prepended to the filter options. */
|
|
50
|
-
noFilterLabel?: string;
|
|
51
49
|
/** Show a clear button on the dataset dropdown. */
|
|
52
50
|
clearable?: boolean;
|
|
53
51
|
/** Mark the dataset dropdown as required. */
|
|
@@ -64,7 +62,6 @@ const props = withDefaults(
|
|
|
64
62
|
placeholder: "...",
|
|
65
63
|
filterLabel: "",
|
|
66
64
|
filterPlaceholder: "...",
|
|
67
|
-
noFilterLabel: "No filter",
|
|
68
65
|
clearable: false,
|
|
69
66
|
required: false,
|
|
70
67
|
disabled: false,
|
|
@@ -86,42 +83,31 @@ const primaryOptions = computed<readonly { ref: PlRef; label: string }[] | undef
|
|
|
86
83
|
props.options?.map((o) => o.primary),
|
|
87
84
|
);
|
|
88
85
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
* Filter dropdown options. The first entry (`null`) is the "No filter" choice —
|
|
93
|
-
* null distinguishes it from `undefined` (dropdown clear button, disabled here).
|
|
94
|
-
*/
|
|
95
|
-
const filterOptions = computed<ListOption<PlRef | null>[]>(() => {
|
|
96
|
-
const filters = currentDatasetOption.value?.filters;
|
|
97
|
-
if (!filters) return [];
|
|
98
|
-
return [
|
|
99
|
-
{ label: props.noFilterLabel, value: null } as ListOption<PlRef | null>,
|
|
100
|
-
...filters.map((f) => ({ label: f.label, value: f.ref }) as ListOption<PlRef | null>),
|
|
101
|
-
];
|
|
102
|
-
});
|
|
86
|
+
const filterOptions = computed<ListOption<PlRef>[]>(
|
|
87
|
+
() => currentDatasetOption.value?.filters?.map((f) => ({ label: f.label, value: f.ref })) ?? [],
|
|
88
|
+
);
|
|
103
89
|
|
|
104
|
-
|
|
90
|
+
// Resolve from `props.options` directly — `currentDatasetOption` may not have
|
|
91
|
+
// recomputed yet when this runs synchronously inside a change handler.
|
|
92
|
+
function findOption(dataset: PlRef): DatasetOption | undefined {
|
|
93
|
+
return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));
|
|
94
|
+
}
|
|
105
95
|
|
|
106
|
-
function
|
|
96
|
+
function onDatasetChange(dataset: PlRef | undefined) {
|
|
107
97
|
if (dataset === undefined) {
|
|
108
98
|
model.value = undefined;
|
|
109
99
|
return;
|
|
110
100
|
}
|
|
111
|
-
|
|
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);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function onDatasetChange(dataset: PlRef | undefined) {
|
|
118
|
-
emitValue(dataset, undefined);
|
|
101
|
+
model.value = createDatasetSelection(createPrimaryRef(dataset), findOption(dataset)?.enrichments);
|
|
119
102
|
}
|
|
120
103
|
|
|
121
|
-
function onFilterChange(
|
|
104
|
+
function onFilterChange(filter: PlRef | undefined) {
|
|
122
105
|
const dataset = selectedDataset.value;
|
|
123
106
|
if (!dataset) return;
|
|
124
|
-
|
|
107
|
+
model.value = createDatasetSelection(
|
|
108
|
+
createPrimaryRef(dataset, filter),
|
|
109
|
+
findOption(dataset)?.enrichments,
|
|
110
|
+
);
|
|
125
111
|
}
|
|
126
112
|
</script>
|
|
127
113
|
|
|
@@ -145,12 +131,12 @@ function onFilterChange(value: PlRef | null | undefined) {
|
|
|
145
131
|
</template>
|
|
146
132
|
</PlDropdownRef>
|
|
147
133
|
<PlDropdown
|
|
148
|
-
|
|
149
|
-
:model-value="filterValue"
|
|
134
|
+
:model-value="selectedFilter"
|
|
150
135
|
:options="filterOptions"
|
|
151
136
|
:label="filterLabel"
|
|
152
137
|
:placeholder="filterPlaceholder"
|
|
153
138
|
:disabled="disabled"
|
|
139
|
+
clearable
|
|
154
140
|
@update:model-value="onFilterChange"
|
|
155
141
|
/>
|
|
156
142
|
</div>
|
|
@@ -24,7 +24,7 @@ const optionsWithFilters: DatasetOption[] = [
|
|
|
24
24
|
],
|
|
25
25
|
enrichments: enrichmentsA,
|
|
26
26
|
},
|
|
27
|
-
// Dataset B has no filters — filter dropdown
|
|
27
|
+
// Dataset B has no filters — filter dropdown is rendered but with no options.
|
|
28
28
|
{ primary: { label: "Dataset B", ref: datasetB } },
|
|
29
29
|
];
|
|
30
30
|
|
|
@@ -51,7 +51,7 @@ async function pickOption(index: number) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
describe("PlDatasetSelector", () => {
|
|
54
|
-
it("renders
|
|
54
|
+
it("always renders both dataset and filter dropdowns", async () => {
|
|
55
55
|
const wrapper = mount(PlDatasetSelector, {
|
|
56
56
|
props: { modelValue: undefined, options: optionsNoFilters },
|
|
57
57
|
attachTo: document.body,
|
|
@@ -60,12 +60,11 @@ describe("PlDatasetSelector", () => {
|
|
|
60
60
|
|
|
61
61
|
const selector = wrapper.find(".pl-dataset-selector");
|
|
62
62
|
expect(selector.exists()).toBe(true);
|
|
63
|
-
|
|
64
|
-
expect(selector.element.children.length).toBe(1);
|
|
63
|
+
expect(selector.element.children.length).toBe(2);
|
|
65
64
|
wrapper.unmount();
|
|
66
65
|
});
|
|
67
66
|
|
|
68
|
-
it("
|
|
67
|
+
it("filter dropdown is rendered when the selected dataset has filters", async () => {
|
|
69
68
|
const wrapper = mount(PlDatasetSelector, {
|
|
70
69
|
props: { modelValue: selection(datasetA), options: optionsWithFilters },
|
|
71
70
|
attachTo: document.body,
|
|
@@ -76,14 +75,20 @@ describe("PlDatasetSelector", () => {
|
|
|
76
75
|
wrapper.unmount();
|
|
77
76
|
});
|
|
78
77
|
|
|
79
|
-
it("
|
|
78
|
+
it("filter dropdown is still rendered (with no options) when the selected dataset has no filters", async () => {
|
|
80
79
|
const wrapper = mount(PlDatasetSelector, {
|
|
81
80
|
props: { modelValue: selection(datasetB), options: optionsWithFilters },
|
|
82
81
|
attachTo: document.body,
|
|
83
82
|
});
|
|
84
83
|
await flushPromises();
|
|
85
84
|
|
|
86
|
-
expect(wrapper.find(".pl-dataset-selector").element.children.length).toBe(
|
|
85
|
+
expect(wrapper.find(".pl-dataset-selector").element.children.length).toBe(2);
|
|
86
|
+
|
|
87
|
+
// Opening the filter dropdown shows no options.
|
|
88
|
+
const inputs = wrapper.findAll("input");
|
|
89
|
+
expect(inputs.length).toBe(2);
|
|
90
|
+
await inputs[1].trigger("focus");
|
|
91
|
+
expect(document.body.querySelectorAll(".dropdown-list-item").length).toBe(0);
|
|
87
92
|
wrapper.unmount();
|
|
88
93
|
});
|
|
89
94
|
|
|
@@ -129,8 +134,8 @@ describe("PlDatasetSelector", () => {
|
|
|
129
134
|
const inputs = wrapper.findAll("input");
|
|
130
135
|
expect(inputs.length).toBe(2);
|
|
131
136
|
await inputs[1].trigger("focus");
|
|
132
|
-
// Options: [
|
|
133
|
-
await pickOption(
|
|
137
|
+
// Options: [Top 1000, High quality]. Pick "Top 1000".
|
|
138
|
+
await pickOption(0);
|
|
134
139
|
|
|
135
140
|
const emitted = wrapper.emitted("update:modelValue");
|
|
136
141
|
expect(emitted).toBeDefined();
|
|
@@ -143,7 +148,7 @@ describe("PlDatasetSelector", () => {
|
|
|
143
148
|
wrapper.unmount();
|
|
144
149
|
});
|
|
145
150
|
|
|
146
|
-
it("emits DatasetSelection with no filter key when
|
|
151
|
+
it("emits DatasetSelection with no filter key when the filter dropdown is cleared", async () => {
|
|
147
152
|
const wrapper = mount(PlDatasetSelector, {
|
|
148
153
|
props: {
|
|
149
154
|
modelValue: selection(datasetA, filterA1, enrichmentsA),
|
|
@@ -155,9 +160,12 @@ describe("PlDatasetSelector", () => {
|
|
|
155
160
|
});
|
|
156
161
|
await flushPromises();
|
|
157
162
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
163
|
+
// The filter dropdown is the second .clear button (the first belongs to
|
|
164
|
+
// the dataset dropdown, but it's only present when the dataset selector
|
|
165
|
+
// itself is clearable; here only the filter is clearable by default).
|
|
166
|
+
const clearBtns = wrapper.findAll(".clear");
|
|
167
|
+
expect(clearBtns.length).toBeGreaterThan(0);
|
|
168
|
+
await clearBtns[clearBtns.length - 1].trigger("click");
|
|
161
169
|
|
|
162
170
|
const emitted = wrapper.emitted("update:modelValue");
|
|
163
171
|
expect(emitted).toBeDefined();
|
|
@@ -168,14 +176,18 @@ describe("PlDatasetSelector", () => {
|
|
|
168
176
|
wrapper.unmount();
|
|
169
177
|
});
|
|
170
178
|
|
|
171
|
-
it("
|
|
179
|
+
it("filter dropdown is still rendered (with no options) when dataset has filters: [] (empty array)", async () => {
|
|
172
180
|
const wrapper = mount(PlDatasetSelector, {
|
|
173
181
|
props: { modelValue: selection(datasetC), options: optionsWithEmptyFilters },
|
|
174
182
|
attachTo: document.body,
|
|
175
183
|
});
|
|
176
184
|
await flushPromises();
|
|
177
185
|
|
|
178
|
-
expect(wrapper.find(".pl-dataset-selector").element.children.length).toBe(
|
|
186
|
+
expect(wrapper.find(".pl-dataset-selector").element.children.length).toBe(2);
|
|
187
|
+
|
|
188
|
+
const inputs = wrapper.findAll("input");
|
|
189
|
+
await inputs[1].trigger("focus");
|
|
190
|
+
expect(document.body.querySelectorAll(".dropdown-list-item").length).toBe(0);
|
|
179
191
|
wrapper.unmount();
|
|
180
192
|
});
|
|
181
193
|
|
|
@@ -197,8 +209,7 @@ describe("PlDatasetSelector", () => {
|
|
|
197
209
|
expect(inputs.length).toBe(2);
|
|
198
210
|
await inputs[1].trigger("focus");
|
|
199
211
|
const items = document.body.querySelectorAll(".dropdown-list-item");
|
|
200
|
-
expect(items.length).toBe(
|
|
201
|
-
expect(items[0].textContent).toContain("No filter");
|
|
212
|
+
expect(items.length).toBe(2); // Top 1000, High quality — no synthetic "No filter"
|
|
202
213
|
wrapper.unmount();
|
|
203
214
|
});
|
|
204
215
|
|
|
@@ -242,9 +253,10 @@ describe("PlDatasetSelector", () => {
|
|
|
242
253
|
});
|
|
243
254
|
await flushPromises();
|
|
244
255
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
256
|
+
// First .clear button is on the dataset dropdown (clearable: true).
|
|
257
|
+
const clearBtns = wrapper.findAll(".clear");
|
|
258
|
+
expect(clearBtns.length).toBeGreaterThan(0);
|
|
259
|
+
await clearBtns[0].trigger("click");
|
|
248
260
|
|
|
249
261
|
const emitted = wrapper.emitted("update:modelValue");
|
|
250
262
|
expect(emitted).toBeDefined();
|