@platforma-sdk/ui-vue 1.75.10 → 1.76.4
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 -11
- 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 +16 -0
- package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.js +3 -5
- package/dist/components/PlDatasetSelector/PlDatasetSelector.js.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue.d.ts +22 -29
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js +52 -55
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js.map +1 -1
- package/package.json +5 -5
- package/src/components/PlDatasetSelector/PlDatasetSelector.vue +63 -83
- package/src/components/PlDatasetSelector/__tests__/PlDatasetSelector.jsdomtest.ts +48 -118
- package/dist/components/PlDatasetSelector/PlDatasetSelector.style.css +0 -1
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.76.4 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...
|
|
@@ -12,11 +12,11 @@ Building browser-lib project...
|
|
|
12
12
|
[7m4[0m export function useGridColumns(props: { api: GridApi }) {
|
|
13
13
|
[7m [0m [91m ~~~~~~~~~~~~~~[0m
|
|
14
14
|
|
|
15
|
-
[2K
|
|
15
|
+
[2K
|
|
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 4821ms.
|
|
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,6 @@ 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.vue_vue_type_style_index_0_scoped_cb8d3a14_lang.css 0.08 kB │ gzip: 0.09 kB
|
|
28
27
|
dist/components/PlAgDataTable/PlAgDataTableV2.vue?vue&type=style&index=0&lang.css 0.09 kB │ gzip: 0.10 kB
|
|
29
28
|
dist/components/PlAnnotations/components/FilterSidebar.vue?vue&type=style&index=0&lang.css 0.11 kB │ gzip: 0.09 kB
|
|
30
29
|
dist/components/PlAgChartHistogramCell/PlAgChartHistogramCell.vue_vue_type_style_index_0_lang.css 0.16 kB │ gzip: 0.13 kB
|
|
@@ -90,6 +89,7 @@ dist/components/PlAgCellProgress/PlAgCellProgress.js
|
|
|
90
89
|
dist/components/PlAgColumnHeader/PlAgColumnHeader.js 0.23 kB │ gzip: 0.17 kB │ map: 3.22 kB
|
|
91
90
|
dist/plugins/Monetization/MonetizationSidebar.js 0.23 kB │ gzip: 0.17 kB │ map: 3.72 kB
|
|
92
91
|
dist/components/PlAgDataTable/PlAgOverlayLoading.js 0.23 kB │ gzip: 0.17 kB │ map: 1.74 kB
|
|
92
|
+
dist/components/PlDatasetSelector/PlDatasetSelector.js 0.23 kB │ gzip: 0.16 kB │ map: 4.56 kB
|
|
93
93
|
dist/components/PlTableFastSearch/PlTableFastSearch.js 0.23 kB │ gzip: 0.17 kB │ map: 1.37 kB
|
|
94
94
|
dist/components/PlAgDataTable/PlAgDataTableSheets.vue_vue_type_style_index_0_lang.module.js 0.23 kB │ gzip: 0.19 kB │ map: 0.42 kB
|
|
95
95
|
dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.js 0.24 kB │ gzip: 0.17 kB │ map: 1.78 kB
|
|
@@ -146,7 +146,6 @@ dist/objectHash.js
|
|
|
146
146
|
dist/composition/AgGrid/index.js 0.46 kB │ gzip: 0.32 kB │ map: 0.79 kB
|
|
147
147
|
dist/defineStore.js 0.49 kB │ gzip: 0.32 kB │ map: 1.20 kB
|
|
148
148
|
dist/internal/utils.js 0.50 kB │ gzip: 0.29 kB │ map: 1.08 kB
|
|
149
|
-
dist/components/PlDatasetSelector/PlDatasetSelector.js 0.51 kB │ gzip: 0.29 kB │ map: 1.10 kB
|
|
150
149
|
dist/components/LoaderPage.js 0.52 kB │ gzip: 0.35 kB │ map: 0.48 kB
|
|
151
150
|
dist/components/PlAdvancedFilter/PlAdvancedFilter.vue_vue_type_style_index_0_lang.module.js 0.54 kB │ gzip: 0.29 kB │ map: 0.72 kB
|
|
152
151
|
dist/plugins/Monetization/useButtonTarget.js 0.54 kB │ gzip: 0.35 kB │ map: 1.10 kB
|
|
@@ -201,9 +200,9 @@ dist/plugins/Monetization/UserCabinetCard.vue_vue_type_script_setup_true_lang.js
|
|
|
201
200
|
dist/components/BlockLayout.vue_vue_type_script_setup_true_lang.js 2.18 kB │ gzip: 1.03 kB │ map: 5.92 kB
|
|
202
201
|
dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue_vue_type_script_setup_true_lang.js 2.40 kB │ gzip: 1.12 kB │ map: 6.67 kB
|
|
203
202
|
dist/components/PlAgDataTable/PlAgDataTableSheets.vue_vue_type_script_setup_true_lang.js 2.45 kB │ gzip: 1.17 kB │ map: 5.01 kB
|
|
203
|
+
dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_script_setup_true_lang.js 2.50 kB │ gzip: 1.04 kB │ map: 5.69 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
|
|
207
206
|
dist/components/PlAgDataTable/compositions/useGrid.js 2.91 kB │ gzip: 1.29 kB │ map: 6.51 kB
|
|
208
207
|
dist/components/PlAgColumnHeader/PlAgColumnHeader.vue_vue_type_script_setup_true_lang.js 2.93 kB │ gzip: 1.26 kB │ map: 7.97 kB
|
|
209
208
|
dist/components/PlAgDataTable/sources/row-number.js 2.99 kB │ gzip: 1.31 kB │ map: 7.42 kB
|
|
@@ -228,12 +227,12 @@ dist/components/PlAdvancedFilter/FilterEditor.vue_vue_type_script_setup_true_lan
|
|
|
228
227
|
dist/components/PlAgDataTable/PlAgDataTableV2.vue_vue_type_script_setup_true_lang.js 12.31 kB │ gzip: 3.90 kB │ map: 29.22 kB
|
|
229
228
|
|
|
230
229
|
[33m[33m[PLUGIN_TIMINGS] Warning:[0m Your build spent significant time in plugins. Here is a breakdown:
|
|
231
|
-
- sourcemaps (
|
|
230
|
+
- sourcemaps (35%)
|
|
232
231
|
- vite:dts (27%)
|
|
233
|
-
- vite:
|
|
234
|
-
- vite:
|
|
235
|
-
- vite:css (
|
|
232
|
+
- vite:vue (10%)
|
|
233
|
+
- vite:css-post (8%)
|
|
234
|
+
- vite:css (8%)
|
|
236
235
|
See https://rolldown.rs/options/checks#plugintimings for more details.
|
|
237
236
|
[39m
|
|
238
|
-
[32m✓ built in 5.
|
|
237
|
+
[32m✓ built in 5.60s[39m
|
|
239
238
|
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.76.4 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 2891ms 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.76.4 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 29ms 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.76.4 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,21 @@
|
|
|
1
1
|
# @platforma-sdk/ui-vue
|
|
2
2
|
|
|
3
|
+
## 1.76.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [2b928af]
|
|
8
|
+
- @milaboratories/pl-model-common@1.42.0
|
|
9
|
+
- @milaboratories/pf-spec-driver@1.3.16
|
|
10
|
+
- @platforma-sdk/model@1.76.4
|
|
11
|
+
- @milaboratories/uikit@2.14.8
|
|
12
|
+
|
|
13
|
+
## 1.76.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 9310b53: `PlDatasetSelector` now renders datasets and their filters in a single dropdown — each dataset row is followed by its filter rows, with the parent dataset label shown as the row description. Removed the `filterLabel` and `filterPlaceholder` props (no longer applicable).
|
|
18
|
+
|
|
3
19
|
## 1.75.10
|
|
4
20
|
|
|
5
21
|
### 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,QAUb,CARM,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"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import e from "
|
|
2
|
-
import t from "./PlDatasetSelector.vue2.js";
|
|
3
|
-
import './PlDatasetSelector.style.css';/* empty css */
|
|
1
|
+
import e from "./PlDatasetSelector.vue2.js";
|
|
4
2
|
//#region src/components/PlDatasetSelector/PlDatasetSelector.vue
|
|
5
|
-
var
|
|
3
|
+
var t = e;
|
|
6
4
|
//#endregion
|
|
7
|
-
export {
|
|
5
|
+
export { t as default };
|
|
8
6
|
|
|
9
7
|
//# sourceMappingURL=PlDatasetSelector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlDatasetSelector.js","names":[],"sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Select a dataset
|
|
1
|
+
{"version":3,"file":"PlDatasetSelector.js","names":[],"sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Select a dataset or one of its filters in a single dropdown, emitting a\n * {@link DatasetSelection}.\n *\n * Each `DatasetOption` contributes one row for its primary plus one row per\n * filter — filters are listed directly underneath their parent dataset and\n * carry the parent's primary label as the row description. Filter labels are\n * derived by `buildDatasetOptions` from each filter column's latest\n * `pl7.app/trace` step (the producing block's self-description).\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 } 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 dropdown. */\n label?: string;\n /** Helper text below the 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 dropdown. */\n error?: unknown;\n /** Placeholder when nothing is selected. */\n placeholder?: string;\n /** Show a clear button. */\n clearable?: boolean;\n /** Mark the dropdown as required. */\n required?: boolean;\n /** Disable interaction. */\n disabled?: boolean;\n }>(),\n {\n options: undefined,\n label: undefined,\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n clearable: false,\n required: false,\n disabled: false,\n },\n);\n\ntype Selection = { primary: PlRef; filter?: PlRef };\n\nconst selectionValue = computed<Selection | undefined>(() => {\n const primary = model.value?.primary;\n if (primary === undefined) return undefined;\n return primary.filter === undefined\n ? { primary: primary.column }\n : { primary: primary.column, filter: primary.filter };\n});\n\n// `deepEqual` (used by PlDropdown for matching) treats `{a, b: undefined}` and\n// `{a}` as different shapes, so the option list and the selection value must\n// agree on filter-key presence.\nconst dropdownOptions = computed<ListOption<Selection>[] | undefined>(() => {\n if (props.options === undefined) return undefined;\n const out: ListOption<Selection>[] = [];\n for (const o of props.options) {\n out.push({ label: o.primary.label, value: { primary: o.primary.ref } });\n for (const filter of o.filters ?? []) {\n out.push({\n label: filter.label,\n description: o.primary.label,\n value: { primary: o.primary.ref, filter: filter.ref },\n });\n }\n }\n return out;\n});\n\nfunction findOption(primary: PlRef): DatasetOption | undefined {\n return props.options?.find((o) => plRefsEqual(o.primary.ref, primary, true));\n}\n\nfunction onChange(selection: Selection | undefined) {\n if (selection === undefined) {\n model.value = undefined;\n return;\n }\n model.value = createDatasetSelection(\n createPrimaryRef(selection.primary, selection.filter),\n findOption(selection.primary)?.enrichments,\n );\n}\n</script>\n\n<template>\n <PlDropdown\n :model-value=\"selectionValue\"\n :options=\"dropdownOptions\"\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=\"onChange\"\n >\n <template v-if=\"slots.tooltip\" #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlDropdown>\n</template>\n"],"mappings":""}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { DatasetOption, DatasetSelection } from '@platforma-sdk/model';
|
|
2
2
|
/**
|
|
3
|
-
* Select a dataset
|
|
3
|
+
* Select a dataset or one of its filters in a single dropdown, emitting a
|
|
4
|
+
* {@link DatasetSelection}.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Each `DatasetOption` contributes one row for its primary plus one row per
|
|
7
|
+
* filter — filters are listed directly underneath their parent dataset and
|
|
8
|
+
* carry the parent's primary label as the row description. Filter labels are
|
|
9
|
+
* derived by `buildDatasetOptions` from each filter column's latest
|
|
10
|
+
* `pl7.app/trace` step (the producing block's self-description).
|
|
8
11
|
*
|
|
9
12
|
* The emitted value bundles the user's pick (`primary`) with the auto-attached
|
|
10
13
|
* `enrichments` payload from the matching `DatasetOption`. Enrichments are
|
|
@@ -15,25 +18,21 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
15
18
|
} & {
|
|
16
19
|
/** Available datasets, each optionally carrying compatible filter choices. */
|
|
17
20
|
options?: Readonly<DatasetOption[]>;
|
|
18
|
-
/** Label above the
|
|
21
|
+
/** Label above the dropdown. */
|
|
19
22
|
label?: string;
|
|
20
|
-
/** Helper text below the
|
|
23
|
+
/** Helper text below the dropdown (shown when there is no error). */
|
|
21
24
|
helper?: string;
|
|
22
25
|
/** Helper text shown while `options` is undefined (loading). */
|
|
23
26
|
loadingOptionsHelper?: string;
|
|
24
|
-
/** Error message displayed below the
|
|
27
|
+
/** Error message displayed below the dropdown. */
|
|
25
28
|
error?: unknown;
|
|
26
|
-
/** Placeholder when
|
|
29
|
+
/** Placeholder when nothing is selected. */
|
|
27
30
|
placeholder?: string;
|
|
28
|
-
/**
|
|
29
|
-
filterLabel?: string;
|
|
30
|
-
/** Placeholder for the filter dropdown. */
|
|
31
|
-
filterPlaceholder?: string;
|
|
32
|
-
/** Show a clear button on the dataset dropdown. */
|
|
31
|
+
/** Show a clear button. */
|
|
33
32
|
clearable?: boolean;
|
|
34
|
-
/** Mark the
|
|
33
|
+
/** Mark the dropdown as required. */
|
|
35
34
|
required?: boolean;
|
|
36
|
-
/** Disable
|
|
35
|
+
/** Disable interaction. */
|
|
37
36
|
disabled?: boolean;
|
|
38
37
|
}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
39
38
|
"update:modelValue": (value: DatasetSelection | undefined) => any;
|
|
@@ -42,25 +41,21 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
42
41
|
} & {
|
|
43
42
|
/** Available datasets, each optionally carrying compatible filter choices. */
|
|
44
43
|
options?: Readonly<DatasetOption[]>;
|
|
45
|
-
/** Label above the
|
|
44
|
+
/** Label above the dropdown. */
|
|
46
45
|
label?: string;
|
|
47
|
-
/** Helper text below the
|
|
46
|
+
/** Helper text below the dropdown (shown when there is no error). */
|
|
48
47
|
helper?: string;
|
|
49
48
|
/** Helper text shown while `options` is undefined (loading). */
|
|
50
49
|
loadingOptionsHelper?: string;
|
|
51
|
-
/** Error message displayed below the
|
|
50
|
+
/** Error message displayed below the dropdown. */
|
|
52
51
|
error?: unknown;
|
|
53
|
-
/** Placeholder when
|
|
52
|
+
/** Placeholder when nothing is selected. */
|
|
54
53
|
placeholder?: string;
|
|
55
|
-
/**
|
|
56
|
-
filterLabel?: string;
|
|
57
|
-
/** Placeholder for the filter dropdown. */
|
|
58
|
-
filterPlaceholder?: string;
|
|
59
|
-
/** Show a clear button on the dataset dropdown. */
|
|
54
|
+
/** Show a clear button. */
|
|
60
55
|
clearable?: boolean;
|
|
61
|
-
/** Mark the
|
|
56
|
+
/** Mark the dropdown as required. */
|
|
62
57
|
required?: boolean;
|
|
63
|
-
/** Disable
|
|
58
|
+
/** Disable interaction. */
|
|
64
59
|
disabled?: boolean;
|
|
65
60
|
}> & Readonly<{
|
|
66
61
|
"onUpdate:modelValue"?: ((value: DatasetSelection | undefined) => any) | undefined;
|
|
@@ -74,9 +69,7 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
74
69
|
clearable: boolean;
|
|
75
70
|
required: boolean;
|
|
76
71
|
disabled: boolean;
|
|
77
|
-
|
|
78
|
-
filterPlaceholder: string;
|
|
79
|
-
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>, Readonly<{
|
|
72
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>, Readonly<{
|
|
80
73
|
tooltip?: () => unknown;
|
|
81
74
|
}> & {
|
|
82
75
|
tooltip?: () => unknown;
|
|
@@ -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":"AAqIA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAS,MAAM,sBAAsB,CAAC;AAOnF;;;;;;;;;;;;;GAaG;;iBAsGU,gBAAgB,GAAG,SAAS;;IA7FrC,8EAA8E;cACpE,QAAQ,CAAC,aAAa,EAAE,CAAC;IACnC,gCAAgC;YACxB,MAAM;IACd,qEAAqE;aAC5D,MAAM;IACf,gEAAgE;2BACzC,MAAM;IAC7B,kDAAkD;YAC1C,OAAO;IACf,4CAA4C;kBAC9B,MAAM;IACpB,2BAA2B;gBACf,OAAO;IACnB,qCAAqC;eAC1B,OAAO;IAClB,2BAA2B;eAChB,OAAO;;;;iBA4ET,gBAAgB,GAAG,SAAS;;IA7FrC,8EAA8E;cACpE,QAAQ,CAAC,aAAa,EAAE,CAAC;IACnC,gCAAgC;YACxB,MAAM;IACd,qEAAqE;aAC5D,MAAM;IACf,gEAAgE;2BACzC,MAAM;IAC7B,kDAAkD;YAC1C,OAAO;IACf,4CAA4C;kBAC9B,MAAM;IACpB,2BAA2B;gBACf,OAAO;IACnB,qCAAqC;eAC1B,OAAO;IAClB,2BAA2B;eAChB,OAAO;;;;;WAdV,MAAM;iBAQA,MAAM;aAVV,QAAQ,CAAC,aAAa,EAAE,CAAC;YAI1B,MAAM;0BAEQ,MAAM;eAMjB,OAAO;cAER,OAAO;cAEP,OAAO;;cAvBV,MAAM,OAAO;;cAAb,MAAM,OAAO;;AAFzB,wBA0MK;AAcL,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import { computed as e,
|
|
2
|
-
import { createDatasetSelection as
|
|
3
|
-
import { PlDropdown as
|
|
4
|
-
|
|
5
|
-
var _ = { class: "pl-dataset-selector" }, v = /* @__PURE__ */ i({
|
|
1
|
+
import { computed as e, createBlock as t, createSlots as n, defineComponent as r, mergeModels as i, openBlock as a, renderSlot as o, unref as s, useModel as c, useSlots as l, withCtx as u } from "vue";
|
|
2
|
+
import { createDatasetSelection as d, createPrimaryRef as f, plRefsEqual as p } from "@platforma-sdk/model";
|
|
3
|
+
import { PlDropdown as m } from "@milaboratories/uikit";
|
|
4
|
+
var h = /* @__PURE__ */ r({
|
|
6
5
|
name: "PlDatasetSelector",
|
|
7
|
-
props: /* @__PURE__ */
|
|
6
|
+
props: /* @__PURE__ */ i({
|
|
8
7
|
options: { default: void 0 },
|
|
9
8
|
label: { default: void 0 },
|
|
10
9
|
helper: { default: void 0 },
|
|
11
10
|
loadingOptionsHelper: { default: void 0 },
|
|
12
11
|
error: { default: void 0 },
|
|
13
12
|
placeholder: { default: "..." },
|
|
14
|
-
filterLabel: { default: "" },
|
|
15
|
-
filterPlaceholder: { default: "..." },
|
|
16
13
|
clearable: {
|
|
17
14
|
type: Boolean,
|
|
18
15
|
default: !1
|
|
@@ -30,43 +27,57 @@ var _ = { class: "pl-dataset-selector" }, v = /* @__PURE__ */ i({
|
|
|
30
27
|
modelModifiers: {}
|
|
31
28
|
}),
|
|
32
29
|
emits: ["update:modelValue"],
|
|
33
|
-
setup(
|
|
34
|
-
let
|
|
35
|
-
let e =
|
|
36
|
-
if (e) return
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}))
|
|
41
|
-
|
|
42
|
-
|
|
30
|
+
setup(r) {
|
|
31
|
+
let i = l(), h = c(r, "modelValue"), g = r, _ = e(() => {
|
|
32
|
+
let e = h.value?.primary;
|
|
33
|
+
if (e !== void 0) return e.filter === void 0 ? { primary: e.column } : {
|
|
34
|
+
primary: e.column,
|
|
35
|
+
filter: e.filter
|
|
36
|
+
};
|
|
37
|
+
}), v = e(() => {
|
|
38
|
+
if (g.options === void 0) return;
|
|
39
|
+
let e = [];
|
|
40
|
+
for (let t of g.options) {
|
|
41
|
+
e.push({
|
|
42
|
+
label: t.primary.label,
|
|
43
|
+
value: { primary: t.primary.ref }
|
|
44
|
+
});
|
|
45
|
+
for (let n of t.filters ?? []) e.push({
|
|
46
|
+
label: n.label,
|
|
47
|
+
description: t.primary.label,
|
|
48
|
+
value: {
|
|
49
|
+
primary: t.primary.ref,
|
|
50
|
+
filter: n.ref
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return e;
|
|
55
|
+
});
|
|
56
|
+
function y(e) {
|
|
57
|
+
return g.options?.find((t) => p(t.primary.ref, e, !0));
|
|
43
58
|
}
|
|
44
|
-
function
|
|
59
|
+
function b(e) {
|
|
45
60
|
if (e === void 0) {
|
|
46
|
-
|
|
61
|
+
h.value = void 0;
|
|
47
62
|
return;
|
|
48
63
|
}
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
function D(e) {
|
|
52
|
-
let t = b.value;
|
|
53
|
-
t && (v.value = f(p(t, e), T(t)?.enrichments));
|
|
64
|
+
h.value = d(f(e.primary, e.filter), y(e.primary)?.enrichments);
|
|
54
65
|
}
|
|
55
|
-
return (e,
|
|
56
|
-
"model-value":
|
|
57
|
-
options:
|
|
58
|
-
label:
|
|
59
|
-
helper:
|
|
60
|
-
"loading-options-helper":
|
|
61
|
-
error:
|
|
62
|
-
placeholder:
|
|
63
|
-
clearable:
|
|
64
|
-
required:
|
|
65
|
-
disabled:
|
|
66
|
-
"onUpdate:modelValue":
|
|
67
|
-
}, n({ _: 2 }, [
|
|
66
|
+
return (e, c) => (a(), t(s(m), {
|
|
67
|
+
"model-value": _.value,
|
|
68
|
+
options: v.value,
|
|
69
|
+
label: r.label,
|
|
70
|
+
helper: r.helper,
|
|
71
|
+
"loading-options-helper": r.loadingOptionsHelper,
|
|
72
|
+
error: r.error,
|
|
73
|
+
placeholder: r.placeholder,
|
|
74
|
+
clearable: r.clearable,
|
|
75
|
+
required: r.required,
|
|
76
|
+
disabled: r.disabled,
|
|
77
|
+
"onUpdate:modelValue": b
|
|
78
|
+
}, n({ _: 2 }, [i.tooltip ? {
|
|
68
79
|
name: "tooltip",
|
|
69
|
-
fn:
|
|
80
|
+
fn: u(() => [o(e.$slots, "tooltip")]),
|
|
70
81
|
key: "0"
|
|
71
82
|
} : void 0]), 1032, [
|
|
72
83
|
"model-value",
|
|
@@ -79,24 +90,10 @@ var _ = { class: "pl-dataset-selector" }, v = /* @__PURE__ */ i({
|
|
|
79
90
|
"clearable",
|
|
80
91
|
"required",
|
|
81
92
|
"disabled"
|
|
82
|
-
])
|
|
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
|
|
90
|
-
}, null, 8, [
|
|
91
|
-
"model-value",
|
|
92
|
-
"options",
|
|
93
|
-
"label",
|
|
94
|
-
"placeholder",
|
|
95
|
-
"disabled"
|
|
96
|
-
])]));
|
|
93
|
+
]));
|
|
97
94
|
}
|
|
98
95
|
});
|
|
99
96
|
//#endregion
|
|
100
|
-
export {
|
|
97
|
+
export { h as default };
|
|
101
98
|
|
|
102
99
|
//# 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
|
|
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 or one of its filters in a single dropdown, emitting a\n * {@link DatasetSelection}.\n *\n * Each `DatasetOption` contributes one row for its primary plus one row per\n * filter — filters are listed directly underneath their parent dataset and\n * carry the parent's primary label as the row description. Filter labels are\n * derived by `buildDatasetOptions` from each filter column's latest\n * `pl7.app/trace` step (the producing block's self-description).\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 } 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 dropdown. */\n label?: string;\n /** Helper text below the 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 dropdown. */\n error?: unknown;\n /** Placeholder when nothing is selected. */\n placeholder?: string;\n /** Show a clear button. */\n clearable?: boolean;\n /** Mark the dropdown as required. */\n required?: boolean;\n /** Disable interaction. */\n disabled?: boolean;\n }>(),\n {\n options: undefined,\n label: undefined,\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n clearable: false,\n required: false,\n disabled: false,\n },\n);\n\ntype Selection = { primary: PlRef; filter?: PlRef };\n\nconst selectionValue = computed<Selection | undefined>(() => {\n const primary = model.value?.primary;\n if (primary === undefined) return undefined;\n return primary.filter === undefined\n ? { primary: primary.column }\n : { primary: primary.column, filter: primary.filter };\n});\n\n// `deepEqual` (used by PlDropdown for matching) treats `{a, b: undefined}` and\n// `{a}` as different shapes, so the option list and the selection value must\n// agree on filter-key presence.\nconst dropdownOptions = computed<ListOption<Selection>[] | undefined>(() => {\n if (props.options === undefined) return undefined;\n const out: ListOption<Selection>[] = [];\n for (const o of props.options) {\n out.push({ label: o.primary.label, value: { primary: o.primary.ref } });\n for (const filter of o.filters ?? []) {\n out.push({\n label: filter.label,\n description: o.primary.label,\n value: { primary: o.primary.ref, filter: filter.ref },\n });\n }\n }\n return out;\n});\n\nfunction findOption(primary: PlRef): DatasetOption | undefined {\n return props.options?.find((o) => plRefsEqual(o.primary.ref, primary, true));\n}\n\nfunction onChange(selection: Selection | undefined) {\n if (selection === undefined) {\n model.value = undefined;\n return;\n }\n model.value = createDatasetSelection(\n createPrimaryRef(selection.primary, selection.filter),\n findOption(selection.primary)?.enrichments,\n );\n}\n</script>\n\n<template>\n <PlDropdown\n :model-value=\"selectionValue\"\n :options=\"dropdownOptions\"\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=\"onChange\"\n >\n <template v-if=\"slots.tooltip\" #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlDropdown>\n</template>\n"],"mappings":";;;;CAgBE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;EAWR,IAAM,IAAQ,GAEV,EAEE,IAAQ,EAAyC,GAAA,aAAE,EAEnD,IAAQ,GAoCR,IAAiB,QAAsC;GAC3D,IAAM,IAAU,EAAM,OAAO;AACzB,aAAY,KAAA,EAChB,QAAO,EAAQ,WAAW,KAAA,IACtB,EAAE,SAAS,EAAQ,QAAO,GAC1B;IAAE,SAAS,EAAQ;IAAQ,QAAQ,EAAQ;IAAQ;IACvD,EAKI,IAAkB,QAAoD;AAC1E,OAAI,EAAM,YAAY,KAAA,EAAW;GACjC,IAAM,IAA+B,EAAE;AACvC,QAAK,IAAM,KAAK,EAAM,SAAS;AAC7B,MAAI,KAAK;KAAE,OAAO,EAAE,QAAQ;KAAO,OAAO,EAAE,SAAS,EAAE,QAAQ,KAAK;KAAE,CAAC;AACvE,SAAK,IAAM,KAAU,EAAE,WAAW,EAAE,CAClC,GAAI,KAAK;KACP,OAAO,EAAO;KACd,aAAa,EAAE,QAAQ;KACvB,OAAO;MAAE,SAAS,EAAE,QAAQ;MAAK,QAAQ,EAAO;MAAK;KACtD,CAAC;;AAGN,UAAO;IACP;EAEF,SAAS,EAAW,GAA2C;AAC7D,UAAO,EAAM,SAAS,MAAM,MAAM,EAAY,EAAE,QAAQ,KAAK,GAAS,GAAK,CAAC;;EAG9E,SAAS,EAAS,GAAkC;AAClD,OAAI,MAAc,KAAA,GAAW;AAC3B,MAAM,QAAQ,KAAA;AACd;;AAEF,KAAM,QAAQ,EACZ,EAAiB,EAAU,SAAS,EAAU,OAAO,EACrD,EAAW,EAAU,QAAQ,EAAE,YAChC;;yBAKD,EAgBa,EAAA,EAAA,EAAA;GAfV,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,UAAA,CAAA,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.76.4",
|
|
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/
|
|
30
|
-
"@milaboratories/
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
29
|
+
"@milaboratories/pl-model-common": "1.42.0",
|
|
30
|
+
"@milaboratories/pf-spec-driver": "1.3.16",
|
|
31
|
+
"@milaboratories/uikit": "2.14.8",
|
|
32
|
+
"@platforma-sdk/model": "1.76.4"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@faker-js/faker": "^9.2.0",
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/**
|
|
3
|
-
* Select a dataset
|
|
3
|
+
* Select a dataset or one of its filters in a single dropdown, emitting a
|
|
4
|
+
* {@link DatasetSelection}.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Each `DatasetOption` contributes one row for its primary plus one row per
|
|
7
|
+
* filter — filters are listed directly underneath their parent dataset and
|
|
8
|
+
* carry the parent's primary label as the row description. Filter labels are
|
|
9
|
+
* derived by `buildDatasetOptions` from each filter column's latest
|
|
10
|
+
* `pl7.app/trace` step (the producing block's self-description).
|
|
8
11
|
*
|
|
9
12
|
* The emitted value bundles the user's pick (`primary`) with the auto-attached
|
|
10
13
|
* `enrichments` payload from the matching `DatasetOption`. Enrichments are
|
|
@@ -19,7 +22,7 @@ export default {
|
|
|
19
22
|
import type { DatasetOption, DatasetSelection, PlRef } from "@platforma-sdk/model";
|
|
20
23
|
import { createDatasetSelection, createPrimaryRef, plRefsEqual } from "@platforma-sdk/model";
|
|
21
24
|
import type { ListOption } from "@milaboratories/uikit";
|
|
22
|
-
import { PlDropdown
|
|
25
|
+
import { PlDropdown } from "@milaboratories/uikit";
|
|
23
26
|
import { computed } from "vue";
|
|
24
27
|
|
|
25
28
|
const slots = defineSlots<{
|
|
@@ -32,25 +35,21 @@ const props = withDefaults(
|
|
|
32
35
|
defineProps<{
|
|
33
36
|
/** Available datasets, each optionally carrying compatible filter choices. */
|
|
34
37
|
options?: Readonly<DatasetOption[]>;
|
|
35
|
-
/** Label above the
|
|
38
|
+
/** Label above the dropdown. */
|
|
36
39
|
label?: string;
|
|
37
|
-
/** Helper text below the
|
|
40
|
+
/** Helper text below the dropdown (shown when there is no error). */
|
|
38
41
|
helper?: string;
|
|
39
42
|
/** Helper text shown while `options` is undefined (loading). */
|
|
40
43
|
loadingOptionsHelper?: string;
|
|
41
|
-
/** Error message displayed below the
|
|
44
|
+
/** Error message displayed below the dropdown. */
|
|
42
45
|
error?: unknown;
|
|
43
|
-
/** Placeholder when
|
|
46
|
+
/** Placeholder when nothing is selected. */
|
|
44
47
|
placeholder?: string;
|
|
45
|
-
/**
|
|
46
|
-
filterLabel?: string;
|
|
47
|
-
/** Placeholder for the filter dropdown. */
|
|
48
|
-
filterPlaceholder?: string;
|
|
49
|
-
/** Show a clear button on the dataset dropdown. */
|
|
48
|
+
/** Show a clear button. */
|
|
50
49
|
clearable?: boolean;
|
|
51
|
-
/** Mark the
|
|
50
|
+
/** Mark the dropdown as required. */
|
|
52
51
|
required?: boolean;
|
|
53
|
-
/** Disable
|
|
52
|
+
/** Disable interaction. */
|
|
54
53
|
disabled?: boolean;
|
|
55
54
|
}>(),
|
|
56
55
|
{
|
|
@@ -60,92 +59,73 @@ const props = withDefaults(
|
|
|
60
59
|
loadingOptionsHelper: undefined,
|
|
61
60
|
error: undefined,
|
|
62
61
|
placeholder: "...",
|
|
63
|
-
filterLabel: "",
|
|
64
|
-
filterPlaceholder: "...",
|
|
65
62
|
clearable: false,
|
|
66
63
|
required: false,
|
|
67
64
|
disabled: false,
|
|
68
65
|
},
|
|
69
66
|
);
|
|
70
67
|
|
|
71
|
-
|
|
68
|
+
type Selection = { primary: PlRef; filter?: PlRef };
|
|
72
69
|
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
const selectionValue = computed<Selection | undefined>(() => {
|
|
71
|
+
const primary = model.value?.primary;
|
|
72
|
+
if (primary === undefined) return undefined;
|
|
73
|
+
return primary.filter === undefined
|
|
74
|
+
? { primary: primary.column }
|
|
75
|
+
: { primary: primary.column, filter: primary.filter };
|
|
79
76
|
});
|
|
80
77
|
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
);
|
|
78
|
+
// `deepEqual` (used by PlDropdown for matching) treats `{a, b: undefined}` and
|
|
79
|
+
// `{a}` as different shapes, so the option list and the selection value must
|
|
80
|
+
// agree on filter-key presence.
|
|
81
|
+
const dropdownOptions = computed<ListOption<Selection>[] | undefined>(() => {
|
|
82
|
+
if (props.options === undefined) return undefined;
|
|
83
|
+
const out: ListOption<Selection>[] = [];
|
|
84
|
+
for (const o of props.options) {
|
|
85
|
+
out.push({ label: o.primary.label, value: { primary: o.primary.ref } });
|
|
86
|
+
for (const filter of o.filters ?? []) {
|
|
87
|
+
out.push({
|
|
88
|
+
label: filter.label,
|
|
89
|
+
description: o.primary.label,
|
|
90
|
+
value: { primary: o.primary.ref, filter: filter.ref },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
});
|
|
89
96
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
function findOption(dataset: PlRef): DatasetOption | undefined {
|
|
93
|
-
return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));
|
|
97
|
+
function findOption(primary: PlRef): DatasetOption | undefined {
|
|
98
|
+
return props.options?.find((o) => plRefsEqual(o.primary.ref, primary, true));
|
|
94
99
|
}
|
|
95
100
|
|
|
96
|
-
function
|
|
97
|
-
if (
|
|
101
|
+
function onChange(selection: Selection | undefined) {
|
|
102
|
+
if (selection === undefined) {
|
|
98
103
|
model.value = undefined;
|
|
99
104
|
return;
|
|
100
105
|
}
|
|
101
|
-
model.value = createDatasetSelection(createPrimaryRef(dataset), findOption(dataset)?.enrichments);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function onFilterChange(filter: PlRef | undefined) {
|
|
105
|
-
const dataset = selectedDataset.value;
|
|
106
|
-
if (!dataset) return;
|
|
107
106
|
model.value = createDatasetSelection(
|
|
108
|
-
createPrimaryRef(
|
|
109
|
-
findOption(
|
|
107
|
+
createPrimaryRef(selection.primary, selection.filter),
|
|
108
|
+
findOption(selection.primary)?.enrichments,
|
|
110
109
|
);
|
|
111
110
|
}
|
|
112
111
|
</script>
|
|
113
112
|
|
|
114
113
|
<template>
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
>
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
</PlDropdownRef>
|
|
133
|
-
<PlDropdown
|
|
134
|
-
:model-value="selectedFilter"
|
|
135
|
-
:options="filterOptions"
|
|
136
|
-
:label="filterLabel"
|
|
137
|
-
:placeholder="filterPlaceholder"
|
|
138
|
-
:disabled="disabled"
|
|
139
|
-
clearable
|
|
140
|
-
@update:model-value="onFilterChange"
|
|
141
|
-
/>
|
|
142
|
-
</div>
|
|
114
|
+
<PlDropdown
|
|
115
|
+
:model-value="selectionValue"
|
|
116
|
+
:options="dropdownOptions"
|
|
117
|
+
:label="label"
|
|
118
|
+
:helper="helper"
|
|
119
|
+
:loading-options-helper="loadingOptionsHelper"
|
|
120
|
+
:error="error"
|
|
121
|
+
:placeholder="placeholder"
|
|
122
|
+
:clearable="clearable"
|
|
123
|
+
:required="required"
|
|
124
|
+
:disabled="disabled"
|
|
125
|
+
@update:model-value="onChange"
|
|
126
|
+
>
|
|
127
|
+
<template v-if="slots.tooltip" #tooltip>
|
|
128
|
+
<slot name="tooltip" />
|
|
129
|
+
</template>
|
|
130
|
+
</PlDropdown>
|
|
143
131
|
</template>
|
|
144
|
-
|
|
145
|
-
<style scoped>
|
|
146
|
-
.pl-dataset-selector {
|
|
147
|
-
display: flex;
|
|
148
|
-
flex-direction: column;
|
|
149
|
-
gap: 12px;
|
|
150
|
-
}
|
|
151
|
-
</style>
|
|
@@ -24,18 +24,12 @@ const optionsWithFilters: DatasetOption[] = [
|
|
|
24
24
|
],
|
|
25
25
|
enrichments: enrichmentsA,
|
|
26
26
|
},
|
|
27
|
-
// Dataset B has no filters —
|
|
27
|
+
// Dataset B has no filters — it appears as a single row with no children.
|
|
28
28
|
{ primary: { label: "Dataset B", ref: datasetB } },
|
|
29
29
|
];
|
|
30
30
|
|
|
31
|
-
const datasetC = createPlRef("3", "out-c", true);
|
|
32
|
-
|
|
33
31
|
const optionsNoFilters: DatasetOption[] = [{ primary: { label: "Dataset B", ref: datasetB } }];
|
|
34
32
|
|
|
35
|
-
const optionsWithEmptyFilters: DatasetOption[] = [
|
|
36
|
-
{ primary: { label: "Dataset C", ref: datasetC }, filters: [] },
|
|
37
|
-
];
|
|
38
|
-
|
|
39
33
|
function selection(
|
|
40
34
|
ref: typeof datasetA,
|
|
41
35
|
filter?: typeof filterA1,
|
|
@@ -45,57 +39,46 @@ function selection(
|
|
|
45
39
|
}
|
|
46
40
|
|
|
47
41
|
async function pickOption(index: number) {
|
|
48
|
-
const
|
|
49
|
-
|
|
42
|
+
const items = [...document.body.querySelectorAll(".dropdown-list-item")] as HTMLElement[];
|
|
43
|
+
items[index].click();
|
|
50
44
|
await flushPromises();
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
describe("PlDatasetSelector", () => {
|
|
54
|
-
it("
|
|
48
|
+
it("renders a single dropdown that lists datasets and filters together", async () => {
|
|
55
49
|
const wrapper = mount(PlDatasetSelector, {
|
|
56
|
-
props: { modelValue: undefined, options:
|
|
50
|
+
props: { modelValue: undefined, options: optionsWithFilters },
|
|
57
51
|
attachTo: document.body,
|
|
58
52
|
});
|
|
59
53
|
await flushPromises();
|
|
60
54
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
expect(selector.element.children.length).toBe(2);
|
|
64
|
-
wrapper.unmount();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it("filter dropdown is rendered when the selected dataset has filters", async () => {
|
|
68
|
-
const wrapper = mount(PlDatasetSelector, {
|
|
69
|
-
props: { modelValue: selection(datasetA), options: optionsWithFilters },
|
|
70
|
-
attachTo: document.body,
|
|
71
|
-
});
|
|
72
|
-
await flushPromises();
|
|
55
|
+
expect(wrapper.findAll("input").length).toBe(1);
|
|
56
|
+
await wrapper.find("input").trigger("focus");
|
|
73
57
|
|
|
74
|
-
|
|
58
|
+
const items = document.body.querySelectorAll(".dropdown-list-item");
|
|
59
|
+
// Dataset A + 2 filters under it + Dataset B.
|
|
60
|
+
expect(items.length).toBe(4);
|
|
75
61
|
wrapper.unmount();
|
|
76
62
|
});
|
|
77
63
|
|
|
78
|
-
it("
|
|
64
|
+
it("uses the filter option's label as the row's display label", async () => {
|
|
79
65
|
const wrapper = mount(PlDatasetSelector, {
|
|
80
|
-
props: { modelValue:
|
|
66
|
+
props: { modelValue: undefined, options: optionsWithFilters },
|
|
81
67
|
attachTo: document.body,
|
|
82
68
|
});
|
|
83
69
|
await flushPromises();
|
|
84
70
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
expect(inputs.length).toBe(2);
|
|
90
|
-
await inputs[1].trigger("focus");
|
|
91
|
-
expect(document.body.querySelectorAll(".dropdown-list-item").length).toBe(0);
|
|
71
|
+
await wrapper.find("input").trigger("focus");
|
|
72
|
+
const items = [...document.body.querySelectorAll(".dropdown-list-item")] as HTMLElement[];
|
|
73
|
+
expect(items[1].textContent).toContain("Top 1000");
|
|
74
|
+
expect(items[2].textContent).toContain("High quality");
|
|
92
75
|
wrapper.unmount();
|
|
93
76
|
});
|
|
94
77
|
|
|
95
|
-
it("emits DatasetSelection bundling primary + enrichments when dataset
|
|
78
|
+
it("emits DatasetSelection bundling primary + enrichments when a dataset is picked", async () => {
|
|
96
79
|
const wrapper = mount(PlDatasetSelector, {
|
|
97
80
|
props: {
|
|
98
|
-
modelValue:
|
|
81
|
+
modelValue: undefined,
|
|
99
82
|
options: optionsWithFilters,
|
|
100
83
|
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
101
84
|
wrapper.setProps({ modelValue: e }),
|
|
@@ -104,25 +87,25 @@ describe("PlDatasetSelector", () => {
|
|
|
104
87
|
});
|
|
105
88
|
await flushPromises();
|
|
106
89
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await pickOption(1);
|
|
90
|
+
await wrapper.find("input").trigger("focus");
|
|
91
|
+
// Items in order: Dataset A, filterA1, filterA2, Dataset B.
|
|
92
|
+
await pickOption(0);
|
|
111
93
|
|
|
112
94
|
const emitted = wrapper.emitted("update:modelValue");
|
|
113
95
|
expect(emitted).toBeDefined();
|
|
114
96
|
const last = emitted![emitted!.length - 1][0] as DatasetSelection;
|
|
115
97
|
expect(last).toEqual({
|
|
116
98
|
__isDatasetSelection: "v1",
|
|
117
|
-
primary: { __isPrimaryRef: "v1", column:
|
|
99
|
+
primary: { __isPrimaryRef: "v1", column: datasetA },
|
|
100
|
+
enrichments: enrichmentsA,
|
|
118
101
|
});
|
|
119
102
|
wrapper.unmount();
|
|
120
103
|
});
|
|
121
104
|
|
|
122
|
-
it("emits DatasetSelection with filter set when a filter is picked", async () => {
|
|
105
|
+
it("emits DatasetSelection with filter set when a filter row is picked", async () => {
|
|
123
106
|
const wrapper = mount(PlDatasetSelector, {
|
|
124
107
|
props: {
|
|
125
|
-
modelValue:
|
|
108
|
+
modelValue: undefined,
|
|
126
109
|
options: optionsWithFilters,
|
|
127
110
|
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
128
111
|
wrapper.setProps({ modelValue: e }),
|
|
@@ -131,11 +114,9 @@ describe("PlDatasetSelector", () => {
|
|
|
131
114
|
});
|
|
132
115
|
await flushPromises();
|
|
133
116
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
await
|
|
137
|
-
// Options: [Top 1000, High quality]. Pick "Top 1000".
|
|
138
|
-
await pickOption(0);
|
|
117
|
+
await wrapper.find("input").trigger("focus");
|
|
118
|
+
// Pick filterA1 — index 1 in the flat list.
|
|
119
|
+
await pickOption(1);
|
|
139
120
|
|
|
140
121
|
const emitted = wrapper.emitted("update:modelValue");
|
|
141
122
|
expect(emitted).toBeDefined();
|
|
@@ -148,11 +129,11 @@ describe("PlDatasetSelector", () => {
|
|
|
148
129
|
wrapper.unmount();
|
|
149
130
|
});
|
|
150
131
|
|
|
151
|
-
it("emits DatasetSelection
|
|
132
|
+
it("emits DatasetSelection without enrichments when the picked option carries none", async () => {
|
|
152
133
|
const wrapper = mount(PlDatasetSelector, {
|
|
153
134
|
props: {
|
|
154
|
-
modelValue:
|
|
155
|
-
options:
|
|
135
|
+
modelValue: undefined,
|
|
136
|
+
options: optionsNoFilters,
|
|
156
137
|
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
157
138
|
wrapper.setProps({ modelValue: e }),
|
|
158
139
|
},
|
|
@@ -160,42 +141,26 @@ describe("PlDatasetSelector", () => {
|
|
|
160
141
|
});
|
|
161
142
|
await flushPromises();
|
|
162
143
|
|
|
163
|
-
|
|
164
|
-
|
|
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");
|
|
144
|
+
await wrapper.find("input").trigger("focus");
|
|
145
|
+
await pickOption(0);
|
|
169
146
|
|
|
170
147
|
const emitted = wrapper.emitted("update:modelValue");
|
|
171
148
|
expect(emitted).toBeDefined();
|
|
172
149
|
const last = emitted![emitted!.length - 1][0] as DatasetSelection;
|
|
173
|
-
expect(last
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
wrapper.unmount();
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it("filter dropdown is still rendered (with no options) when dataset has filters: [] (empty array)", async () => {
|
|
180
|
-
const wrapper = mount(PlDatasetSelector, {
|
|
181
|
-
props: { modelValue: selection(datasetC), options: optionsWithEmptyFilters },
|
|
182
|
-
attachTo: document.body,
|
|
150
|
+
expect(last).toEqual({
|
|
151
|
+
__isDatasetSelection: "v1",
|
|
152
|
+
primary: { __isPrimaryRef: "v1", column: datasetB },
|
|
183
153
|
});
|
|
184
|
-
|
|
185
|
-
|
|
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);
|
|
154
|
+
expect("enrichments" in last).toBe(false);
|
|
191
155
|
wrapper.unmount();
|
|
192
156
|
});
|
|
193
157
|
|
|
194
|
-
it("
|
|
158
|
+
it("emits undefined when cleared", async () => {
|
|
195
159
|
const wrapper = mount(PlDatasetSelector, {
|
|
196
160
|
props: {
|
|
197
|
-
modelValue: selection(datasetA),
|
|
161
|
+
modelValue: selection(datasetA, filterA1, enrichmentsA),
|
|
198
162
|
options: optionsWithFilters,
|
|
163
|
+
clearable: true,
|
|
199
164
|
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
200
165
|
wrapper.setProps({ modelValue: e }),
|
|
201
166
|
},
|
|
@@ -203,49 +168,22 @@ describe("PlDatasetSelector", () => {
|
|
|
203
168
|
});
|
|
204
169
|
await flushPromises();
|
|
205
170
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
expect(inputs.length).toBe(2);
|
|
210
|
-
await inputs[1].trigger("focus");
|
|
211
|
-
const items = document.body.querySelectorAll(".dropdown-list-item");
|
|
212
|
-
expect(items.length).toBe(2); // Top 1000, High quality — no synthetic "No filter"
|
|
213
|
-
wrapper.unmount();
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it("emits DatasetSelection without enrichments when the option carries none", async () => {
|
|
217
|
-
const wrapper = mount(PlDatasetSelector, {
|
|
218
|
-
props: {
|
|
219
|
-
modelValue: undefined,
|
|
220
|
-
options: optionsNoFilters,
|
|
221
|
-
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
222
|
-
wrapper.setProps({ modelValue: e }),
|
|
223
|
-
},
|
|
224
|
-
attachTo: document.body,
|
|
225
|
-
});
|
|
226
|
-
await flushPromises();
|
|
227
|
-
|
|
228
|
-
const inputs = wrapper.findAll("input");
|
|
229
|
-
await inputs[0].trigger("focus");
|
|
230
|
-
await pickOption(0);
|
|
171
|
+
const clearBtn = wrapper.find(".clear");
|
|
172
|
+
expect(clearBtn.exists()).toBe(true);
|
|
173
|
+
await clearBtn.trigger("click");
|
|
231
174
|
|
|
232
175
|
const emitted = wrapper.emitted("update:modelValue");
|
|
233
176
|
expect(emitted).toBeDefined();
|
|
234
|
-
const last = emitted![emitted!.length - 1][0]
|
|
235
|
-
expect(last).
|
|
236
|
-
__isDatasetSelection: "v1",
|
|
237
|
-
primary: { __isPrimaryRef: "v1", column: datasetB },
|
|
238
|
-
});
|
|
239
|
-
expect("enrichments" in last).toBe(false);
|
|
177
|
+
const last = emitted![emitted!.length - 1][0];
|
|
178
|
+
expect(last).toBeUndefined();
|
|
240
179
|
wrapper.unmount();
|
|
241
180
|
});
|
|
242
181
|
|
|
243
|
-
it("
|
|
182
|
+
it("does not emit on mount when a value is provided", async () => {
|
|
244
183
|
const wrapper = mount(PlDatasetSelector, {
|
|
245
184
|
props: {
|
|
246
|
-
modelValue: selection(datasetA
|
|
185
|
+
modelValue: selection(datasetA),
|
|
247
186
|
options: optionsWithFilters,
|
|
248
|
-
clearable: true,
|
|
249
187
|
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
250
188
|
wrapper.setProps({ modelValue: e }),
|
|
251
189
|
},
|
|
@@ -253,15 +191,7 @@ describe("PlDatasetSelector", () => {
|
|
|
253
191
|
});
|
|
254
192
|
await flushPromises();
|
|
255
193
|
|
|
256
|
-
|
|
257
|
-
const clearBtns = wrapper.findAll(".clear");
|
|
258
|
-
expect(clearBtns.length).toBeGreaterThan(0);
|
|
259
|
-
await clearBtns[0].trigger("click");
|
|
260
|
-
|
|
261
|
-
const emitted = wrapper.emitted("update:modelValue");
|
|
262
|
-
expect(emitted).toBeDefined();
|
|
263
|
-
const last = emitted![emitted!.length - 1][0];
|
|
264
|
-
expect(last).toBeUndefined();
|
|
194
|
+
expect(wrapper.emitted("update:modelValue")).toBeUndefined();
|
|
265
195
|
wrapper.unmount();
|
|
266
196
|
});
|
|
267
197
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.pl-dataset-selector[data-v-cb8d3a14]{flex-direction:column;gap:12px;display:flex}
|