@platforma-sdk/ui-vue 1.76.4 → 1.76.5

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.
@@ -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.76.4 build /home/runner/_work/platforma/platforma/sdk/ui-vue
3
+ > @platforma-sdk/ui-vue@1.76.5 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 4821ms.
19
+ [vite:dts] Declaration files built in 5191ms.
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
@@ -89,7 +89,7 @@ dist/components/PlAgCellProgress/PlAgCellProgress.js
89
89
  dist/components/PlAgColumnHeader/PlAgColumnHeader.js 0.23 kB │ gzip: 0.17 kB │ map: 3.22 kB
90
90
  dist/plugins/Monetization/MonetizationSidebar.js 0.23 kB │ gzip: 0.17 kB │ map: 3.72 kB
91
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
92
+ dist/components/PlDatasetSelector/PlDatasetSelector.js 0.23 kB │ gzip: 0.16 kB │ map: 4.75 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
@@ -200,7 +200,7 @@ dist/plugins/Monetization/UserCabinetCard.vue_vue_type_script_setup_true_lang.js
200
200
  dist/components/BlockLayout.vue_vue_type_script_setup_true_lang.js 2.18 kB │ gzip: 1.03 kB │ map: 5.92 kB
201
201
  dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue_vue_type_script_setup_true_lang.js 2.40 kB │ gzip: 1.12 kB │ map: 6.67 kB
202
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
203
+ dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_script_setup_true_lang.js 2.54 kB │ gzip: 1.06 kB │ map: 5.96 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
206
  dist/components/PlAgDataTable/compositions/useGrid.js 2.91 kB │ gzip: 1.29 kB │ map: 6.51 kB
@@ -227,12 +227,12 @@ dist/components/PlAdvancedFilter/FilterEditor.vue_vue_type_script_setup_true_lan
227
227
  dist/components/PlAgDataTable/PlAgDataTableV2.vue_vue_type_script_setup_true_lang.js 12.31 kB │ gzip: 3.90 kB │ map: 29.22 kB
228
228
 
229
229
  [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
230
- - sourcemaps (35%)
231
- - vite:dts (27%)
232
- - vite:vue (10%)
233
- - vite:css-post (8%)
234
- - vite:css (8%)
230
+ - vite:dts (29%)
231
+ - sourcemaps (27%)
232
+ - vite:vue (12%)
233
+ - vite:css-post (12%)
234
+ - vite:css (7%)
235
235
  See https://rolldown.rs/options/checks#plugintimings for more details.
236
236
  
237
- ✓ built in 5.60s
237
+ ✓ built in 6.01s
238
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.76.4 formatter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
3
+ > @platforma-sdk/ui-vue@1.76.5 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 2891ms on 137 files using 8 threads.
11
+ Finished in 2529ms 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.76.4 linter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
3
+ > @platforma-sdk/ui-vue@1.76.5 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 29ms on 120 files with 98 rules using 8 threads.
9
+ Finished in 33ms 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.76.4 types:check /home/runner/_work/platforma/platforma/sdk/ui-vue
3
+ > @platforma-sdk/ui-vue@1.76.5 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,41 @@
1
1
  # @platforma-sdk/ui-vue
2
2
 
3
+ ## 1.76.5
4
+
5
+ ### Patch Changes
6
+
7
+ - b4f9e33: `PlDatasetSelector` filter rows used to render as the dataset's name (e.g.
8
+ "Bulk") instead of the producing block's name (e.g. "Top 10"). Root cause:
9
+ the parent dataset's trace ends with a high-importance
10
+ `samples-and-data/dataset` step ("Bulk", importance 100); with a single
11
+ filter `deriveDistinctLabels` had no peer to disambiguate against and
12
+ picked that step.
13
+
14
+ Fix: `filterMatchesToOptions` now includes the dataset spec as an extra
15
+ entry when calling `deriveDistinctLabels`, then discards its label. The
16
+ algorithm is forced to pick types that distinguish each filter from the
17
+ dataset, surfacing the filter-specific trace step. Filter labels carry the
18
+ dataset name as a prefix (e.g. "Bulk / Top 10"); `PlDatasetSelector` drops
19
+ the now-redundant dataset-name subtitle on filter rows.
20
+
21
+ Filter columns inherit the dataset's `pl7.app/label` annotation; the
22
+ filter-discovery code now suppresses native labels via
23
+ `formatters.native` so the algorithm reaches into the trace for
24
+ disambiguation.
25
+
26
+ `filterMatchesToOptions` signature: `(matches, options)` where
27
+ `FilterMatchOptions = { refsByObjectId, datasetSpec }`. The previous
28
+ trailing `labelOptions?` positional is removed — it had no real callers,
29
+ and the function's native-label suppression is load-bearing so accepting
30
+ arbitrary formatter overrides would risk regressing the fix.
31
+
32
+ - b4f9e33: `PlDatasetSelector`: carry `enrichments` inside the dropdown `Selection`
33
+ value so `onChange` no longer needs a separate `findOption` lookup over
34
+ `props.options`.
35
+ - Updated dependencies [b4f9e33]
36
+ - @platforma-sdk/model@1.76.5
37
+ - @milaboratories/uikit@2.14.9
38
+
3
39
  ## 1.76.4
4
40
 
5
41
  ### 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,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
+ {"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"}
@@ -1 +1 @@
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
+ {"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}. Filter labels carry the dataset name as a\n * prefix (e.g. \"Bulk / Top 10\"), so no separate subtitle is rendered.\n * Enrichments from the matching `DatasetOption` are bundled into the\n * emitted value opaquely — block authors unbundle them in their args\n * resolver.\n */\nexport default {\n name: \"PlDatasetSelector\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport type {\n DatasetOption,\n DatasetSelection,\n LabeledEnrichmentRefs,\n PlRef,\n} 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; enrichments?: LabeledEnrichmentRefs };\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 optional-key presence.\nfunction makeSelection(\n primary: PlRef,\n filter: PlRef | undefined,\n enrichments: LabeledEnrichmentRefs | undefined,\n): Selection {\n return {\n primary,\n ...(filter !== undefined && { filter }),\n ...(enrichments !== undefined && enrichments.length > 0 && { enrichments }),\n };\n}\n\nconst selectionValue = computed<Selection | undefined>(() => {\n const primary = model.value?.primary;\n if (primary === undefined) return undefined;\n // Read enrichments from the current option, not from `model.value`: the\n // stored enrichments are a snapshot at selection time and won't match\n // `dropdownOptions` after `props.options` recomputes (e.g. when the\n // result pool gains or loses an enrichment column).\n const option = props.options?.find((o) => plRefsEqual(o.primary.ref, primary.column, true));\n return makeSelection(primary.column, primary.filter, option?.enrichments);\n});\n\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({\n label: o.primary.label,\n value: makeSelection(o.primary.ref, undefined, o.enrichments),\n });\n for (const filter of o.filters ?? []) {\n out.push({\n label: filter.label,\n value: makeSelection(o.primary.ref, filter.ref, o.enrichments),\n });\n }\n }\n return out;\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 selection.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,17 +1,11 @@
1
1
  import { DatasetOption, DatasetSelection } from '@platforma-sdk/model';
2
2
  /**
3
3
  * Select a dataset or one of its filters in a single dropdown, emitting a
4
- * {@link DatasetSelection}.
5
- *
6
- * Each `DatasetOption` contributes one row for its primary plus one row per
7
- * filterfilters 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).
11
- *
12
- * The emitted value bundles the user's pick (`primary`) with the auto-attached
13
- * `enrichments` payload from the matching `DatasetOption`. Enrichments are
14
- * opaque to the UI — block authors unbundle them inside their args resolver.
4
+ * {@link DatasetSelection}. Filter labels carry the dataset name as a
5
+ * prefix (e.g. "Bulk / Top 10"), so no separate subtitle is rendered.
6
+ * Enrichments from the matching `DatasetOption` are bundled into the
7
+ * emitted value opaquely block authors unbundle them in their args
8
+ * resolver.
15
9
  */
16
10
  declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
17
11
  modelValue?: DatasetSelection | undefined;
@@ -1 +1 @@
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
+ {"version":3,"file":"PlDatasetSelector.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"names":[],"mappings":"AAiJA,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAGjB,MAAM,sBAAsB,CAAC;AAO9B;;;;;;;GAOG;;iBAmHU,gBAAgB,GAAG,SAAS;;IA1GrC,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;;;;iBAyFT,gBAAgB,GAAG,SAAS;;IA1GrC,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,wBAuNK;AAcL,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
@@ -28,44 +28,44 @@ var h = /* @__PURE__ */ r({
28
28
  }),
29
29
  emits: ["update:modelValue"],
30
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
31
+ let i = l(), h = c(r, "modelValue"), g = r;
32
+ function _(e, t, n) {
33
+ return {
34
+ primary: e,
35
+ ...t !== void 0 && { filter: t },
36
+ ...n !== void 0 && n.length > 0 && { enrichments: n }
36
37
  };
37
- }), v = e(() => {
38
+ }
39
+ let v = e(() => {
40
+ let e = h.value?.primary;
41
+ if (e === void 0) return;
42
+ let t = g.options?.find((t) => p(t.primary.ref, e.column, !0));
43
+ return _(e.column, e.filter, t?.enrichments);
44
+ }), y = e(() => {
38
45
  if (g.options === void 0) return;
39
46
  let e = [];
40
47
  for (let t of g.options) {
41
48
  e.push({
42
49
  label: t.primary.label,
43
- value: { primary: t.primary.ref }
50
+ value: _(t.primary.ref, void 0, t.enrichments)
44
51
  });
45
52
  for (let n of t.filters ?? []) e.push({
46
53
  label: n.label,
47
- description: t.primary.label,
48
- value: {
49
- primary: t.primary.ref,
50
- filter: n.ref
51
- }
54
+ value: _(t.primary.ref, n.ref, t.enrichments)
52
55
  });
53
56
  }
54
57
  return e;
55
58
  });
56
- function y(e) {
57
- return g.options?.find((t) => p(t.primary.ref, e, !0));
58
- }
59
59
  function b(e) {
60
60
  if (e === void 0) {
61
61
  h.value = void 0;
62
62
  return;
63
63
  }
64
- h.value = d(f(e.primary, e.filter), y(e.primary)?.enrichments);
64
+ h.value = d(f(e.primary, e.filter), e.enrichments);
65
65
  }
66
66
  return (e, c) => (a(), t(s(m), {
67
- "model-value": _.value,
68
- options: v.value,
67
+ "model-value": v.value,
68
+ options: y.value,
69
69
  label: r.label,
70
70
  helper: r.helper,
71
71
  "loading-options-helper": r.loadingOptionsHelper,
@@ -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 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"}
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}. Filter labels carry the dataset name as a\n * prefix (e.g. \"Bulk / Top 10\"), so no separate subtitle is rendered.\n * Enrichments from the matching `DatasetOption` are bundled into the\n * emitted value opaquely — block authors unbundle them in their args\n * resolver.\n */\nexport default {\n name: \"PlDatasetSelector\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport type {\n DatasetOption,\n DatasetSelection,\n LabeledEnrichmentRefs,\n PlRef,\n} 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; enrichments?: LabeledEnrichmentRefs };\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 optional-key presence.\nfunction makeSelection(\n primary: PlRef,\n filter: PlRef | undefined,\n enrichments: LabeledEnrichmentRefs | undefined,\n): Selection {\n return {\n primary,\n ...(filter !== undefined && { filter }),\n ...(enrichments !== undefined && enrichments.length > 0 && { enrichments }),\n };\n}\n\nconst selectionValue = computed<Selection | undefined>(() => {\n const primary = model.value?.primary;\n if (primary === undefined) return undefined;\n // Read enrichments from the current option, not from `model.value`: the\n // stored enrichments are a snapshot at selection time and won't match\n // `dropdownOptions` after `props.options` recomputes (e.g. when the\n // result pool gains or loses an enrichment column).\n const option = props.options?.find((o) => plRefsEqual(o.primary.ref, primary.column, true));\n return makeSelection(primary.column, primary.filter, option?.enrichments);\n});\n\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({\n label: o.primary.label,\n value: makeSelection(o.primary.ref, undefined, o.enrichments),\n });\n for (const filter of o.filters ?? []) {\n out.push({\n label: filter.label,\n value: makeSelection(o.primary.ref, filter.ref, o.enrichments),\n });\n }\n }\n return out;\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 selection.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":";;;;CAUE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBR,IAAM,IAAQ,GAEV,EAEE,IAAQ,EAAyC,GAAA,aAAE,EAEnD,IAAQ;EAuCd,SAAS,EACP,GACA,GACA,GACW;AACX,UAAO;IACL;IACA,GAAI,MAAW,KAAA,KAAa,EAAE,WAAQ;IACtC,GAAI,MAAgB,KAAA,KAAa,EAAY,SAAS,KAAK,EAAE,gBAAa;IAC3E;;EAGH,IAAM,IAAiB,QAAsC;GAC3D,IAAM,IAAU,EAAM,OAAO;AAC7B,OAAI,MAAY,KAAA,EAAW;GAK3B,IAAM,IAAS,EAAM,SAAS,MAAM,MAAM,EAAY,EAAE,QAAQ,KAAK,EAAQ,QAAQ,GAAK,CAAC;AAC3F,UAAO,EAAc,EAAQ,QAAQ,EAAQ,QAAQ,GAAQ,YAAY;IACzE,EAEI,IAAkB,QAAoD;AAC1E,OAAI,EAAM,YAAY,KAAA,EAAW;GACjC,IAAM,IAA+B,EAAE;AACvC,QAAK,IAAM,KAAK,EAAM,SAAS;AAC7B,MAAI,KAAK;KACP,OAAO,EAAE,QAAQ;KACjB,OAAO,EAAc,EAAE,QAAQ,KAAK,KAAA,GAAW,EAAE,YAAY;KAC9D,CAAC;AACF,SAAK,IAAM,KAAU,EAAE,WAAW,EAAE,CAClC,GAAI,KAAK;KACP,OAAO,EAAO;KACd,OAAO,EAAc,EAAE,QAAQ,KAAK,EAAO,KAAK,EAAE,YAAY;KAC/D,CAAC;;AAGN,UAAO;IACP;EAEF,SAAS,EAAS,GAAkC;AAClD,OAAI,MAAc,KAAA,GAAW;AAC3B,MAAM,QAAQ,KAAA;AACd;;AAEF,KAAM,QAAQ,EACZ,EAAiB,EAAU,SAAS,EAAU,OAAO,EACrD,EAAU,YACX;;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.76.4",
3
+ "version": "1.76.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -28,8 +28,8 @@
28
28
  "zod": "~3.25.76",
29
29
  "@milaboratories/pl-model-common": "1.42.0",
30
30
  "@milaboratories/pf-spec-driver": "1.3.16",
31
- "@milaboratories/uikit": "2.14.8",
32
- "@platforma-sdk/model": "1.76.4"
31
+ "@platforma-sdk/model": "1.76.5",
32
+ "@milaboratories/uikit": "2.14.9"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@faker-js/faker": "^9.2.0",
@@ -45,9 +45,9 @@
45
45
  "typescript": "~5.9.3",
46
46
  "vite": "^8.0.6",
47
47
  "vitest": "^4.1.3",
48
+ "@milaboratories/ts-builder": "1.4.0",
48
49
  "@milaboratories/helpers": "1.14.2",
49
50
  "@milaboratories/build-configs": "2.0.0",
50
- "@milaboratories/ts-builder": "1.4.0",
51
51
  "@milaboratories/ts-configs": "1.2.3"
52
52
  },
53
53
  "scripts": {
@@ -1,17 +1,11 @@
1
1
  <script lang="ts">
2
2
  /**
3
3
  * Select a dataset or one of its filters in a single dropdown, emitting a
4
- * {@link DatasetSelection}.
5
- *
6
- * Each `DatasetOption` contributes one row for its primary plus one row per
7
- * filterfilters 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).
11
- *
12
- * The emitted value bundles the user's pick (`primary`) with the auto-attached
13
- * `enrichments` payload from the matching `DatasetOption`. Enrichments are
14
- * opaque to the UI — block authors unbundle them inside their args resolver.
4
+ * {@link DatasetSelection}. Filter labels carry the dataset name as a
5
+ * prefix (e.g. "Bulk / Top 10"), so no separate subtitle is rendered.
6
+ * Enrichments from the matching `DatasetOption` are bundled into the
7
+ * emitted value opaquely block authors unbundle them in their args
8
+ * resolver.
15
9
  */
16
10
  export default {
17
11
  name: "PlDatasetSelector",
@@ -19,7 +13,12 @@ export default {
19
13
  </script>
20
14
 
21
15
  <script lang="ts" setup>
22
- import type { DatasetOption, DatasetSelection, PlRef } from "@platforma-sdk/model";
16
+ import type {
17
+ DatasetOption,
18
+ DatasetSelection,
19
+ LabeledEnrichmentRefs,
20
+ PlRef,
21
+ } from "@platforma-sdk/model";
23
22
  import { createDatasetSelection, createPrimaryRef, plRefsEqual } from "@platforma-sdk/model";
24
23
  import type { ListOption } from "@milaboratories/uikit";
25
24
  import { PlDropdown } from "@milaboratories/uikit";
@@ -65,39 +64,52 @@ const props = withDefaults(
65
64
  },
66
65
  );
67
66
 
68
- type Selection = { primary: PlRef; filter?: PlRef };
67
+ type Selection = { primary: PlRef; filter?: PlRef; enrichments?: LabeledEnrichmentRefs };
68
+
69
+ // `deepEqual` (used by PlDropdown for matching) treats `{a, b: undefined}` and
70
+ // `{a}` as different shapes, so the option list and the selection value must
71
+ // agree on optional-key presence.
72
+ function makeSelection(
73
+ primary: PlRef,
74
+ filter: PlRef | undefined,
75
+ enrichments: LabeledEnrichmentRefs | undefined,
76
+ ): Selection {
77
+ return {
78
+ primary,
79
+ ...(filter !== undefined && { filter }),
80
+ ...(enrichments !== undefined && enrichments.length > 0 && { enrichments }),
81
+ };
82
+ }
69
83
 
70
84
  const selectionValue = computed<Selection | undefined>(() => {
71
85
  const primary = model.value?.primary;
72
86
  if (primary === undefined) return undefined;
73
- return primary.filter === undefined
74
- ? { primary: primary.column }
75
- : { primary: primary.column, filter: primary.filter };
87
+ // Read enrichments from the current option, not from `model.value`: the
88
+ // stored enrichments are a snapshot at selection time and won't match
89
+ // `dropdownOptions` after `props.options` recomputes (e.g. when the
90
+ // result pool gains or loses an enrichment column).
91
+ const option = props.options?.find((o) => plRefsEqual(o.primary.ref, primary.column, true));
92
+ return makeSelection(primary.column, primary.filter, option?.enrichments);
76
93
  });
77
94
 
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
95
  const dropdownOptions = computed<ListOption<Selection>[] | undefined>(() => {
82
96
  if (props.options === undefined) return undefined;
83
97
  const out: ListOption<Selection>[] = [];
84
98
  for (const o of props.options) {
85
- out.push({ label: o.primary.label, value: { primary: o.primary.ref } });
99
+ out.push({
100
+ label: o.primary.label,
101
+ value: makeSelection(o.primary.ref, undefined, o.enrichments),
102
+ });
86
103
  for (const filter of o.filters ?? []) {
87
104
  out.push({
88
105
  label: filter.label,
89
- description: o.primary.label,
90
- value: { primary: o.primary.ref, filter: filter.ref },
106
+ value: makeSelection(o.primary.ref, filter.ref, o.enrichments),
91
107
  });
92
108
  }
93
109
  }
94
110
  return out;
95
111
  });
96
112
 
97
- function findOption(primary: PlRef): DatasetOption | undefined {
98
- return props.options?.find((o) => plRefsEqual(o.primary.ref, primary, true));
99
- }
100
-
101
113
  function onChange(selection: Selection | undefined) {
102
114
  if (selection === undefined) {
103
115
  model.value = undefined;
@@ -105,7 +117,7 @@ function onChange(selection: Selection | undefined) {
105
117
  }
106
118
  model.value = createDatasetSelection(
107
119
  createPrimaryRef(selection.primary, selection.filter),
108
- findOption(selection.primary)?.enrichments,
120
+ selection.enrichments,
109
121
  );
110
122
  }
111
123
  </script>