@platforma-sdk/ui-vue 1.84.20 → 1.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.84.20 build /home/runner/_work/platforma/platforma/sdk/ui-vue
3
+ > @platforma-sdk/ui-vue@1.85.0 build /home/runner/_work/platforma/platforma/sdk/ui-vue
4
4
  > ts-builder build --target browser-lib
5
5
 
6
6
  Building browser-lib project...
@@ -37,7 +37,7 @@ Building browser-lib project...
37
37
  rendering chunks...
38
38
 
39
39
  [unplugin:dts] Start generate declaration files...
40
- [unplugin:dts] Declaration files built in 4443ms.
40
+ [unplugin:dts] Declaration files built in 4459ms.
41
41
 
42
42
  computing gzip size...
43
43
  dist/components/PlAnnotations/components/PlAnnotations.vue?vue&type=style&index=0&lang.css 0.04 kB │ gzip: 0.06 kB
@@ -110,7 +110,7 @@ dist/components/PlAgCellProgress/PlAgCellProgress.js
110
110
  dist/components/PlAgColumnHeader/PlAgColumnHeader.js 0.23 kB │ gzip: 0.17 kB │ map: 3.65 kB
111
111
  dist/plugins/Monetization/MonetizationSidebar.js 0.23 kB │ gzip: 0.17 kB │ map: 3.72 kB
112
112
  dist/components/PlAgDataTable/PlAgOverlayLoading.js 0.23 kB │ gzip: 0.17 kB │ map: 1.97 kB
113
- dist/components/PlDatasetSelector/PlDatasetSelector.js 0.23 kB │ gzip: 0.16 kB │ map: 4.83 kB
113
+ dist/components/PlDatasetSelector/PlDatasetSelector.js 0.23 kB │ gzip: 0.16 kB │ map: 5.15 kB
114
114
  dist/components/PlTableFastSearch/PlTableFastSearch.js 0.23 kB │ gzip: 0.17 kB │ map: 1.43 kB
115
115
  dist/components/PlAgDataTable/PlAgDataTableSheets.vue_vue_type_style_index_0_lang.module.js 0.23 kB │ gzip: 0.19 kB │ map: 0.42 kB
116
116
  dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.js 0.24 kB │ gzip: 0.17 kB │ map: 1.94 kB
@@ -221,7 +221,7 @@ dist/plugins/Monetization/UserCabinetCard.vue_vue_type_script_setup_true_lang.js
221
221
  dist/components/PlAgRowNumHeader.vue_vue_type_script_setup_true_lang.js 2.10 kB │ gzip: 0.90 kB │ map: 3.66 kB
222
222
  dist/components/BlockLayout.vue_vue_type_script_setup_true_lang.js 2.26 kB │ gzip: 1.06 kB │ map: 6.10 kB
223
223
  dist/components/PlAgDataTable/PlAgDataTableSheets.vue_vue_type_script_setup_true_lang.js 2.55 kB │ gzip: 1.21 kB │ map: 5.15 kB
224
- dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_script_setup_true_lang.js 2.62 kB │ gzip: 1.09 kB │ map: 6.08 kB
224
+ dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_script_setup_true_lang.js 2.64 kB │ gzip: 1.10 kB │ map: 6.41 kB
225
225
  dist/components/PlAnnotations/components/PlAnnotations.vue_vue_type_script_setup_true_lang.js 2.72 kB │ gzip: 1.14 kB │ map: 4.21 kB
226
226
  dist/lib.js 2.73 kB │ gzip: 0.57 kB │ map: 3.98 kB
227
227
  dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue_vue_type_script_setup_true_lang.js 2.87 kB │ gzip: 1.18 kB │ map: 7.63 kB
@@ -247,12 +247,12 @@ dist/components/PlAdvancedFilter/FilterEditor.vue_vue_type_script_setup_true_lan
247
247
  dist/components/PlAgDataTable/PlAgDataTableV2.vue_vue_type_script_setup_true_lang.js 12.76 kB │ gzip: 4.02 kB │ map: 32.97 kB
248
248
 
249
249
  [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
250
- - sourcemaps (35%)
251
- - unplugin-dts (20%)
252
- - vite:css-post (12%)
253
- - vite:vue (9%)
254
- - vite:build-import-analysis (7%)
250
+ - sourcemaps (36%)
251
+ - unplugin-dts (24%)
252
+ - vite:css-post (10%)
253
+ - vite:vue (10%)
254
+ - vite:css (7%)
255
255
  See https://rolldown.rs/options/checks#plugintimings for more details.
256
256
  
257
- ✓ built in 5.27s
257
+ ✓ built in 5.24s
258
258
  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.84.20 formatter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
3
+ > @platforma-sdk/ui-vue@1.85.0 formatter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
4
4
  > ts-builder formatter --check
5
5
 
6
6
  Checking formatting...
@@ -8,5 +8,5 @@ Checking formatting...
8
8
  Checking formatting...
9
9
 
10
10
  All matched files use the correct format.
11
- Finished in 2345ms on 134 files using 16 threads.
11
+ Finished in 2817ms on 134 files using 16 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.84.20 linter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
3
+ > @platforma-sdk/ui-vue@1.85.0 linter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
4
4
  > ts-builder linter --check
5
5
 
6
6
  Linting project...
7
7
  ↳ oxlint --config /home/runner/_work/platforma/platforma/sdk/ui-vue/.oxlintrc.json --deny-warnings
8
8
  Found 0 warnings and 0 errors.
9
- Finished in 25ms on 117 files with 108 rules using 16 threads.
9
+ Finished in 30ms on 117 files with 108 rules using 16 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.84.20 types:check /home/runner/_work/platforma/platforma/sdk/ui-vue
3
+ > @platforma-sdk/ui-vue@1.85.0 types:check /home/runner/_work/platforma/platforma/sdk/ui-vue
4
4
  > ts-builder type-check --target browser-lib
5
5
 
6
6
  ↳ vue-tsc-ts6.cjs --noEmit --project ./tsconfig.json --customConditions default
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @platforma-sdk/ui-vue
2
2
 
3
+ ## 1.85.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 2a781e0: tableBuilder: setColumnJoin("left" | "full" | "inner") and a per-column join option control how columns added with addColumn / addColumns are joined onto the primaries. The default stays "full". Use "left" with a filtered primary so added columns don't bring back keys the filter removed.
8
+
9
+ buildDatasetOptions: new requireEnrichments option (default true). Set it to false for blocks that only need the dataset and its filters, so blocks that enrich the dataset no longer make them stale when they run.
10
+
11
+ PlDatasetSelector: a stored selection whose requireEnrichments flag differs from the options' is now shown instead of appearing empty.
12
+
13
+ - Updated dependencies [2a781e0]
14
+ - @platforma-sdk/model@1.85.0
15
+ - @milaboratories/uikit@2.15.42
16
+
3
17
  ## 1.84.20
4
18
 
5
19
  ### Patch Changes
@@ -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}. 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 description: o.primary.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 data-testid=\"pl-dataset-selector\"\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 // The option's ref, not the stored one, for the same reason: a ref stored with\n // a different `requireEnrichments` flag than the options carry (e.g. saved\n // before a block changed its `buildDatasetOptions` mode) would not match any\n // option and the selection would show empty.\n const option = props.options?.find((o) => plRefsEqual(o.primary.ref, primary.column, true));\n return makeSelection(option?.primary.ref ?? 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 description: o.primary.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 data-testid=\"pl-dataset-selector\"\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 +1 @@
1
- {"version":3,"file":"PlDatasetSelector.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"names":[],"mappings":"AAoJA,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAGjB,MAAM,sBAAsB,CAAC;AAO9B;;;;;;;GAOG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAKzC,QAAA,MAAM,YAAY;IASd,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;;iBA6ET,gBAAgB,GAAG,SAAS;;;;IA9FrC,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;;iBA6ET,gBAAgB,GAAG,SAAS;;;;;WA3F7B,MAAM;aAFJ,QAAQ,CAAC,aAAa,EAAE,CAAC;YAI1B,MAAM;0BAEQ,MAAM;iBAIf,MAAM;eAER,OAAO;cAER,OAAO;cAEP,OAAO;;cAxBV,MAAM,OAAO;EAyMrB,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"PlDatasetSelector.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"names":[],"mappings":"AAwJA,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAGjB,MAAM,sBAAsB,CAAC;AAO9B;;;;;;;GAOG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAKzC,QAAA,MAAM,YAAY;IASd,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;;iBAiFT,gBAAgB,GAAG,SAAS;;;;IAlGrC,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;;iBAiFT,gBAAgB,GAAG,SAAS;;;;;WA/F7B,MAAM;aAFJ,QAAQ,CAAC,aAAa,EAAE,CAAC;YAI1B,MAAM;0BAEQ,MAAM;iBAIf,MAAM;eAER,OAAO;cAER,OAAO;cAEP,OAAO;;cAxBV,MAAM,OAAO;EA6MrB,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -40,7 +40,7 @@ var h = /* @__PURE__ */ r({
40
40
  let e = h.value?.primary;
41
41
  if (e === void 0) return;
42
42
  let t = g.options?.find((t) => p(t.primary.ref, e.column, !0));
43
- return _(e.column, e.filter, t?.enrichments);
43
+ return _(t?.primary.ref ?? e.column, e.filter, t?.enrichments);
44
44
  }), y = e(() => {
45
45
  if (g.options === void 0) return;
46
46
  let e = [];
@@ -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}. 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 description: o.primary.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 data-testid=\"pl-dataset-selector\"\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,aAAa,EAAE,QAAQ;KACvB,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,EAiBa,EAAA,EAAA,EAAA;GAhBX,eAAY;GACX,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 // The option's ref, not the stored one, for the same reason: a ref stored with\n // a different `requireEnrichments` flag than the options carry (e.g. saved\n // before a block changed its `buildDatasetOptions` mode) would not match any\n // option and the selection would show empty.\n const option = props.options?.find((o) => plRefsEqual(o.primary.ref, primary.column, true));\n return makeSelection(option?.primary.ref ?? 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 description: o.primary.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 data-testid=\"pl-dataset-selector\"\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;GAS3B,IAAM,IAAS,EAAM,SAAS,MAAM,MAAM,EAAY,EAAE,QAAQ,KAAK,EAAQ,QAAQ,GAAK,CAAC;AAC3F,UAAO,EAAc,GAAQ,QAAQ,OAAO,EAAQ,QAAQ,EAAQ,QAAQ,GAAQ,YAAY;IAChG,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,aAAa,EAAE,QAAQ;KACvB,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,EAiBa,EAAA,EAAA,EAAA;GAhBX,eAAY;GACX,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.84.20",
3
+ "version": "1.85.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -26,11 +26,11 @@
26
26
  "lru-cache": "^11.2.2",
27
27
  "vue": "3.5.24",
28
28
  "zod": "~3.25.76",
29
- "@milaboratories/pf-spec-driver": "1.5.8",
30
- "@milaboratories/columns-collection-driver": "0.2.9",
31
29
  "@milaboratories/pl-model-common": "1.53.0",
32
- "@platforma-sdk/model": "1.84.20",
33
- "@milaboratories/uikit": "2.15.41"
30
+ "@milaboratories/columns-collection-driver": "0.2.9",
31
+ "@milaboratories/pf-spec-driver": "1.5.8",
32
+ "@platforma-sdk/model": "1.85.0",
33
+ "@milaboratories/uikit": "2.15.42"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@faker-js/faker": "^9.2.0",
@@ -46,10 +46,10 @@
46
46
  "typescript": "7.0.2",
47
47
  "vite": "^8.0.6",
48
48
  "vitest": "^4.1.3",
49
+ "@milaboratories/ts-builder": "1.7.2",
49
50
  "@milaboratories/helpers": "1.14.5",
50
51
  "@milaboratories/ts-configs": "1.4.0",
51
- "@milaboratories/build-configs": "2.0.2",
52
- "@milaboratories/ts-builder": "1.7.2"
52
+ "@milaboratories/build-configs": "2.0.2"
53
53
  },
54
54
  "scripts": {
55
55
  "dev": "ts-builder serve --target browser-lib",
@@ -88,8 +88,12 @@ const selectionValue = computed<Selection | undefined>(() => {
88
88
  // stored enrichments are a snapshot at selection time and won't match
89
89
  // `dropdownOptions` after `props.options` recomputes (e.g. when the
90
90
  // result pool gains or loses an enrichment column).
91
+ // The option's ref, not the stored one, for the same reason: a ref stored with
92
+ // a different `requireEnrichments` flag than the options carry (e.g. saved
93
+ // before a block changed its `buildDatasetOptions` mode) would not match any
94
+ // option and the selection would show empty.
91
95
  const option = props.options?.find((o) => plRefsEqual(o.primary.ref, primary.column, true));
92
- return makeSelection(primary.column, primary.filter, option?.enrichments);
96
+ return makeSelection(option?.primary.ref ?? primary.column, primary.filter, option?.enrichments);
93
97
  });
94
98
 
95
99
  const dropdownOptions = computed<ListOption<Selection>[] | undefined>(() => {
@@ -179,6 +179,23 @@ describe("PlDatasetSelector", () => {
179
179
  wrapper.unmount();
180
180
  });
181
181
 
182
+ it("shows a stored selection whose requireEnrichments flag differs from the options'", async () => {
183
+ // Options carry the flag (datasetA); the stored ref was saved without it.
184
+ const storedWithoutFlag = createPlRef("1", "out-a");
185
+ const wrapper = mount(PlDatasetSelector, {
186
+ props: {
187
+ modelValue: selection(storedWithoutFlag, filterA1),
188
+ options: optionsWithFilters,
189
+ },
190
+ attachTo: document.body,
191
+ });
192
+ await flushPromises();
193
+
194
+ expect(wrapper.text()).toContain("Top 1000");
195
+ expect(wrapper.emitted("update:modelValue")).toBeUndefined();
196
+ wrapper.unmount();
197
+ });
198
+
182
199
  it("does not emit on mount when a value is provided", async () => {
183
200
  const wrapper = mount(PlDatasetSelector, {
184
201
  props: {