@platforma-sdk/ui-vue 1.69.0 → 1.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +12 -12
- 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 +24 -0
- package/dist/components/PlAgDataTable/sources/common.d.ts +1 -2
- package/dist/components/PlAgDataTable/sources/common.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/common.js +1 -1
- package/dist/components/PlAgDataTable/sources/common.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/value-rendering.d.ts +1 -1
- package/dist/components/PlAgDataTable/sources/value-rendering.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/value-rendering.js +10 -8
- package/dist/components/PlAgDataTable/sources/value-rendering.js.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.js +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.js.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.style.css +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue.d.ts +9 -19
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js +22 -23
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js.map +1 -1
- package/package.json +6 -6
- package/src/components/PlAgDataTable/sources/common.ts +2 -4
- package/src/components/PlAgDataTable/sources/value-rendering.ts +16 -7
- package/src/components/PlDatasetSelector/PlDatasetSelector.vue +24 -23
- package/src/components/PlDatasetSelector/__tests__/PlDatasetSelector.jsdomtest.ts +70 -72
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.71.0 build /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder build --target browser-lib
|
|
5
5
|
|
|
6
6
|
Building browser-lib project...
|
|
@@ -16,7 +16,7 @@ Building browser-lib project...
|
|
|
16
16
|
rendering chunks...
|
|
17
17
|
|
|
18
18
|
[vite:dts] Start generate declaration files...
|
|
19
|
-
[vite:dts] Declaration files built in
|
|
19
|
+
[vite:dts] Declaration files built in 4672ms.
|
|
20
20
|
|
|
21
21
|
computing gzip size...
|
|
22
22
|
dist/components/PlAnnotations/components/PlAnnotations.vue?vue&type=style&index=0&lang.css 0.04 kB │ gzip: 0.06 kB
|
|
@@ -24,7 +24,7 @@ dist/components/PlAgCellStatusTag/PlAgCellStatusTag.vue_vue_type_style_index_0_l
|
|
|
24
24
|
dist/components/BlockLayout.vue?vue&type=style&index=0&lang.css 0.05 kB │ gzip: 0.07 kB
|
|
25
25
|
dist/components/PlAgDataTable/PlAgDataTableSheets.vue?vue&type=style&index=0&lang.css 0.06 kB │ gzip: 0.08 kB
|
|
26
26
|
dist/components/PlAnnotations/components/PlAnnotationsModal.vue?vue&type=style&index=0&lang.css 0.07 kB │ gzip: 0.08 kB
|
|
27
|
-
dist/components/PlDatasetSelector/PlDatasetSelector.
|
|
27
|
+
dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_style_index_0_scoped_95f2adf4_lang.css 0.08 kB │ gzip: 0.09 kB
|
|
28
28
|
dist/components/PlAgDataTable/PlAgDataTableV2.vue?vue&type=style&index=0&lang.css 0.09 kB │ gzip: 0.10 kB
|
|
29
29
|
dist/components/PlAnnotations/components/FilterSidebar.vue?vue&type=style&index=0&lang.css 0.11 kB │ gzip: 0.09 kB
|
|
30
30
|
dist/components/PlAgChartHistogramCell/PlAgChartHistogramCell.vue_vue_type_style_index_0_lang.css 0.16 kB │ gzip: 0.13 kB
|
|
@@ -100,10 +100,10 @@ dist/components/PlAdvancedFilter/index.js
|
|
|
100
100
|
dist/components/PlAgDataTable/PlAgDataTableV2.vue_vue_type_style_index_0_lang.module.js 0.25 kB │ gzip: 0.20 kB │ map: 0.45 kB
|
|
101
101
|
dist/components/PlAnnotations/components/PlAnnotationsModal.vue_vue_type_style_index_0_lang.module.js 0.25 kB │ gzip: 0.20 kB │ map: 0.46 kB
|
|
102
102
|
dist/lib/util/helpers/dist/functions.js 0.26 kB │ gzip: 0.20 kB │ map: 5.18 kB
|
|
103
|
-
dist/components/PlAgDataTable/sources/common.js 0.26 kB │ gzip: 0.20 kB │ map: 0.60 kB
|
|
104
103
|
dist/components/PlAnnotations/utils.js 0.26 kB │ gzip: 0.23 kB │ map: 1.02 kB
|
|
105
104
|
dist/components/PlBtnExportArchive/Summary.vue_vue_type_style_index_0_lang.module.js 0.26 kB │ gzip: 0.20 kB │ map: 0.50 kB
|
|
106
105
|
dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.js 0.27 kB │ gzip: 0.17 kB │ map: 2.36 kB
|
|
106
|
+
dist/components/PlAgDataTable/sources/common.js 0.27 kB │ gzip: 0.21 kB │ map: 0.55 kB
|
|
107
107
|
dist/components/PlAdvancedFilter/OperandButton.vue_vue_type_style_index_0_lang.module.js 0.27 kB │ gzip: 0.21 kB │ map: 0.50 kB
|
|
108
108
|
dist/components/PlBtnExportArchive/Item.vue_vue_type_style_index_0_lang.module.js 0.28 kB │ gzip: 0.21 kB │ map: 0.54 kB
|
|
109
109
|
dist/components/PlAgDataTable/pl-ag-overlay-loading.module.js 0.29 kB │ gzip: 0.20 kB │ map: 0.52 kB
|
|
@@ -169,12 +169,12 @@ dist/components/PlAgDataTable/compositions/useFilterableColumns.js
|
|
|
169
169
|
dist/components/PlAgDataTable/sources/focus-row.js 0.95 kB │ gzip: 0.51 kB │ map: 2.22 kB
|
|
170
170
|
dist/plugins/Monetization/validation.js 0.99 kB │ gzip: 0.49 kB │ map: 2.58 kB
|
|
171
171
|
dist/AgGridVue/selection.js 1.00 kB │ gzip: 0.42 kB │ map: 3.18 kB
|
|
172
|
-
dist/components/PlAgDataTable/sources/value-rendering.js 1.06 kB │ gzip: 0.52 kB │ map: 2.99 kB
|
|
173
172
|
dist/components/PlAgChartHistogramCell/PlAgChartHistogramCell.vue_vue_type_script_setup_true_lang.js 1.10 kB │ gzip: 0.61 kB │ map: 1.88 kB
|
|
174
173
|
dist/components/PlAgCellFile/PlAgCellFile.vue_vue_type_script_setup_true_lang.js 1.14 kB │ gzip: 0.64 kB │ map: 2.93 kB
|
|
175
174
|
dist/plugins/Monetization/RunStatus.vue_vue_type_script_setup_true_lang.js 1.16 kB │ gzip: 0.62 kB │ map: 3.04 kB
|
|
176
175
|
dist/components/PlAgGridColumnManager/useFilteredItems.js 1.18 kB │ gzip: 0.61 kB │ map: 3.48 kB
|
|
177
176
|
dist/lib/util/helpers/dist/objects.js 1.20 kB │ gzip: 0.58 kB │ map: 9.83 kB
|
|
177
|
+
dist/components/PlAgDataTable/sources/value-rendering.js 1.21 kB │ gzip: 0.59 kB │ map: 3.54 kB
|
|
178
178
|
dist/createModel.js 1.22 kB │ gzip: 0.61 kB │ map: 3.11 kB
|
|
179
179
|
dist/utils.js 1.26 kB │ gzip: 0.62 kB │ map: 3.40 kB
|
|
180
180
|
dist/lib/util/helpers/dist/prettyBytes.js 1.29 kB │ gzip: 0.67 kB │ map: 3.79 kB
|
|
@@ -207,7 +207,7 @@ dist/components/PlAgDataTable/compositions/useGrid.js
|
|
|
207
207
|
dist/components/PlAgColumnHeader/PlAgColumnHeader.vue_vue_type_script_setup_true_lang.js 2.93 kB │ gzip: 1.26 kB │ map: 7.97 kB
|
|
208
208
|
dist/components/PlAgDataTable/sources/row-number.js 2.99 kB │ gzip: 1.31 kB │ map: 7.42 kB
|
|
209
209
|
dist/defineApp.js 3.01 kB │ gzip: 1.05 kB │ map: 14.38 kB
|
|
210
|
-
dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_script_setup_true_lang.js 3.
|
|
210
|
+
dist/components/PlDatasetSelector/PlDatasetSelector.vue_vue_type_script_setup_true_lang.js 3.18 kB │ gzip: 1.24 kB │ map: 7.33 kB
|
|
211
211
|
dist/plugins/Monetization/LimitCard.vue_vue_type_script_setup_true_lang.js 3.31 kB │ gzip: 1.15 kB │ map: 9.08 kB
|
|
212
212
|
dist/composition/fileContent.js 3.78 kB │ gzip: 1.45 kB │ map: 12.95 kB
|
|
213
213
|
dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue_vue_type_script_setup_true_lang.js 3.83 kB │ gzip: 1.64 kB │ map: 6.89 kB
|
|
@@ -228,12 +228,12 @@ dist/components/PlAdvancedFilter/FilterEditor.vue_vue_type_script_setup_true_lan
|
|
|
228
228
|
dist/components/PlAgDataTable/PlAgDataTableV2.vue_vue_type_script_setup_true_lang.js 12.31 kB │ gzip: 3.90 kB │ map: 29.22 kB
|
|
229
229
|
|
|
230
230
|
[33m[33m[PLUGIN_TIMINGS] Warning:[0m Your build spent significant time in plugins. Here is a breakdown:
|
|
231
|
-
-
|
|
232
|
-
-
|
|
233
|
-
- vite:
|
|
234
|
-
- vite:
|
|
235
|
-
- vite:css (
|
|
231
|
+
- sourcemaps (30%)
|
|
232
|
+
- vite:dts (26%)
|
|
233
|
+
- vite:css-post (12%)
|
|
234
|
+
- vite:vue (11%)
|
|
235
|
+
- vite:css (7%)
|
|
236
236
|
See https://rolldown.rs/options/checks#plugintimings for more details.
|
|
237
237
|
[39m
|
|
238
|
-
[32m✓ built in 5.
|
|
238
|
+
[32m✓ built in 5.47s[39m
|
|
239
239
|
Build completed successfully
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @platforma-sdk/ui-vue@1.
|
|
3
|
+
> @platforma-sdk/ui-vue@1.71.0 formatter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder formatter --check
|
|
5
5
|
|
|
6
6
|
Checking formatting...
|
|
@@ -8,5 +8,5 @@ Checking formatting...
|
|
|
8
8
|
Checking formatting...
|
|
9
9
|
|
|
10
10
|
All matched files use the correct format.
|
|
11
|
-
Finished in
|
|
11
|
+
Finished in 5486ms 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.71.0 linter:check /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder linter --check
|
|
5
5
|
|
|
6
6
|
Linting project...
|
|
7
7
|
↳ oxlint --config /home/runner/_work/platforma/platforma/sdk/ui-vue/.oxlintrc.json --deny-warnings
|
|
8
8
|
Found 0 warnings and 0 errors.
|
|
9
|
-
Finished in
|
|
9
|
+
Finished in 53ms 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.71.0 types:check /home/runner/_work/platforma/platforma/sdk/ui-vue
|
|
4
4
|
> ts-builder type-check --target browser-lib
|
|
5
5
|
|
|
6
6
|
↳ vue-tsc.js --noEmit --project ./tsconfig.json --customConditions ,
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @platforma-sdk/ui-vue
|
|
2
2
|
|
|
3
|
+
## 1.71.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6369956: Show table with partial data
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [6369956]
|
|
12
|
+
- @milaboratories/pl-model-common@1.38.0
|
|
13
|
+
- @platforma-sdk/model@1.71.0
|
|
14
|
+
- @milaboratories/pf-spec-driver@1.3.8
|
|
15
|
+
- @milaboratories/uikit@2.13.2
|
|
16
|
+
|
|
17
|
+
## 1.70.0
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [a40505e]
|
|
22
|
+
- @milaboratories/pl-model-common@1.37.0
|
|
23
|
+
- @platforma-sdk/model@1.70.0
|
|
24
|
+
- @milaboratories/pf-spec-driver@1.3.7
|
|
25
|
+
- @milaboratories/uikit@2.13.1
|
|
26
|
+
|
|
3
27
|
## 1.69.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { PTableValue } from '@platforma-sdk/model';
|
|
2
1
|
export declare const PTableHidden: {
|
|
3
2
|
readonly type: "hidden";
|
|
4
3
|
};
|
|
5
4
|
export type PTableHidden = typeof PTableHidden;
|
|
6
|
-
export declare function isPTableHidden(value:
|
|
5
|
+
export declare function isPTableHidden(value: unknown): value is PTableHidden;
|
|
7
6
|
//# sourceMappingURL=common.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAgDataTable/sources/common.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAgDataTable/sources/common.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;CAA8B,CAAC;AACxD,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC;AAE/C,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/components/PlAgDataTable/sources/common.ts
|
|
2
2
|
var e = { type: "hidden" };
|
|
3
3
|
function t(e) {
|
|
4
|
-
return typeof e == "object" && !!e && e.type === "hidden";
|
|
4
|
+
return typeof e == "object" && !!e && "type" in e && e.type === "hidden";
|
|
5
5
|
}
|
|
6
6
|
//#endregion
|
|
7
7
|
export { e as PTableHidden, t as isPTableHidden };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[],"sources":["../../../../src/components/PlAgDataTable/sources/common.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../../../../src/components/PlAgDataTable/sources/common.ts"],"sourcesContent":["export const PTableHidden = { type: \"hidden\" } as const;\nexport type PTableHidden = typeof PTableHidden;\n\nexport function isPTableHidden(value: unknown): value is PTableHidden {\n return typeof value === \"object\" && value !== null && \"type\" in value && value.type === \"hidden\";\n}\n"],"mappings":";AAAA,IAAa,IAAe,EAAE,MAAM,UAAU;AAG9C,SAAgB,EAAe,GAAuC;AACpE,QAAO,OAAO,KAAU,cAAY,KAAkB,UAAU,KAAS,EAAM,SAAS"}
|
|
@@ -2,7 +2,7 @@ import { PTableColumnSpec, PTableValue } from '@platforma-sdk/model';
|
|
|
2
2
|
import { ValueFormatterFunc } from 'ag-grid-enterprise';
|
|
3
3
|
import { PTableHidden } from './common';
|
|
4
4
|
import { PlAgDataTableV2Row } from '../types';
|
|
5
|
-
export declare function formatSpecialValues(value: PTableValue | PTableHidden |
|
|
5
|
+
export declare function formatSpecialValues(value: undefined | PTableValue | PTableHidden, dataStatus: undefined | "absent" | "error" | "computing" | "ready"): string | undefined;
|
|
6
6
|
export type ColumnRenderingSpec = {
|
|
7
7
|
valueFormatter: ValueFormatterFunc<PlAgDataTableV2Row, PTableValue | PTableHidden>;
|
|
8
8
|
fontFamily?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-rendering.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAgDataTable/sources/value-rendering.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"value-rendering.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAgDataTable/sources/value-rendering.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,YAAY,EAC7C,UAAU,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,GACjE,MAAM,GAAG,SAAS,CAcpB;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,kBAAkB,CAAC,kBAAkB,EAAE,WAAW,GAAG,YAAY,CAAC,CAAC;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,mBAAmB,CAoClF"}
|
|
@@ -2,8 +2,10 @@ import { isPTableHidden as e } from "./common.js";
|
|
|
2
2
|
import { Annotation as t, PTableNA as n, ValueType as r, readAnnotation as i } from "@platforma-sdk/model";
|
|
3
3
|
import * as a from "d3-format";
|
|
4
4
|
//#region src/components/PlAgDataTable/sources/value-rendering.ts
|
|
5
|
-
function o(t) {
|
|
6
|
-
if (
|
|
5
|
+
function o(t, r) {
|
|
6
|
+
if (r === "absent") return "absent";
|
|
7
|
+
if (r === "error") return "error";
|
|
8
|
+
if (r === "computing") return "computing...";
|
|
7
9
|
if (e(t)) return "loading...";
|
|
8
10
|
if (t === n) return "";
|
|
9
11
|
}
|
|
@@ -14,17 +16,17 @@ function s(e) {
|
|
|
14
16
|
case r.Long:
|
|
15
17
|
case r.Float:
|
|
16
18
|
case r.Double: {
|
|
17
|
-
let n = i(e.spec, t.Format), r = n ? a.format(n) : void 0;
|
|
19
|
+
let n = i(e.spec, t.Format), r = i(e.spec, t.DataStatus), c = n ? a.format(n) : void 0;
|
|
18
20
|
s = { valueFormatter: (e) => {
|
|
19
|
-
let t = o(e.value);
|
|
20
|
-
return t === void 0 ?
|
|
21
|
+
let t = o(e.value, r);
|
|
22
|
+
return t === void 0 ? c ? c(Number(e.value)) : e.value?.toString() ?? "" : t;
|
|
21
23
|
} };
|
|
22
24
|
break;
|
|
23
25
|
}
|
|
24
26
|
default:
|
|
25
|
-
s = { valueFormatter: (
|
|
26
|
-
let
|
|
27
|
-
return
|
|
27
|
+
s = { valueFormatter: (n) => {
|
|
28
|
+
let r = o(n.value, i(e.spec, t.DataStatus));
|
|
29
|
+
return r === void 0 ? n.value?.toString() ?? "" : r;
|
|
28
30
|
} };
|
|
29
31
|
break;
|
|
30
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-rendering.js","names":[],"sources":["../../../../src/components/PlAgDataTable/sources/value-rendering.ts"],"sourcesContent":["import {\n Annotation,\n PTableNA,\n readAnnotation,\n ValueType,\n type PTableColumnSpec,\n type PTableValue,\n} from \"@platforma-sdk/model\";\nimport type { ValueFormatterFunc } from \"ag-grid-enterprise\";\nimport type { PTableHidden } from \"./common\";\nimport { isPTableHidden } from \"./common\";\nimport * as d3 from \"d3-format\";\nimport type { PlAgDataTableV2Row } from \"../types\";\n\nexport function formatSpecialValues(\n value: PTableValue | PTableHidden |
|
|
1
|
+
{"version":3,"file":"value-rendering.js","names":[],"sources":["../../../../src/components/PlAgDataTable/sources/value-rendering.ts"],"sourcesContent":["import {\n Annotation,\n PTableNA,\n readAnnotation,\n ValueType,\n type PTableColumnSpec,\n type PTableValue,\n} from \"@platforma-sdk/model\";\nimport type { ValueFormatterFunc } from \"ag-grid-enterprise\";\nimport type { PTableHidden } from \"./common\";\nimport { isPTableHidden } from \"./common\";\nimport * as d3 from \"d3-format\";\nimport type { PlAgDataTableV2Row } from \"../types\";\n\nexport function formatSpecialValues(\n value: undefined | PTableValue | PTableHidden,\n dataStatus: undefined | \"absent\" | \"error\" | \"computing\" | \"ready\",\n): string | undefined {\n if (dataStatus === \"absent\") {\n return \"absent\";\n } else if (dataStatus === \"error\") {\n return \"error\";\n } else if (dataStatus === \"computing\") {\n return \"computing...\";\n } else if (isPTableHidden(value)) {\n return \"loading...\";\n } else if (value === PTableNA) {\n return \"\";\n } else {\n return undefined;\n }\n}\n\nexport type ColumnRenderingSpec = {\n valueFormatter: ValueFormatterFunc<PlAgDataTableV2Row, PTableValue | PTableHidden>;\n fontFamily?: string;\n};\n\nexport function getColumnRenderingSpec(spec: PTableColumnSpec): ColumnRenderingSpec {\n const valueType = spec.type === \"axis\" ? spec.spec.type : spec.spec.valueType;\n let renderSpec: ColumnRenderingSpec;\n switch (valueType) {\n case ValueType.Int:\n case ValueType.Long:\n case ValueType.Float:\n case ValueType.Double: {\n const format = readAnnotation(spec.spec, Annotation.Format);\n const dataStatus = readAnnotation(spec.spec, Annotation.DataStatus);\n const formatFn = format ? d3.format(format) : undefined;\n renderSpec = {\n valueFormatter: (params) => {\n const formatted = formatSpecialValues(params.value, dataStatus);\n if (formatted !== undefined) return formatted;\n return formatFn ? formatFn(Number(params.value)) : (params.value?.toString() ?? \"\");\n },\n };\n break;\n }\n default:\n renderSpec = {\n valueFormatter: (params) => {\n const formatted = formatSpecialValues(\n params.value,\n readAnnotation(spec.spec, Annotation.DataStatus),\n );\n if (formatted !== undefined) return formatted;\n return params.value?.toString() ?? \"\";\n },\n };\n break;\n }\n const fontFamily = readAnnotation(spec.spec, Annotation.Table.FontFamily);\n if (fontFamily) renderSpec.fontFamily = fontFamily;\n return renderSpec;\n}\n"],"mappings":";;;;AAcA,SAAgB,EACd,GACA,GACoB;AACpB,KAAI,MAAe,SACjB,QAAO;KACE,MAAe,QACxB,QAAO;KACE,MAAe,YACxB,QAAO;KACE,EAAe,EAAM,CAC9B,QAAO;KACE,MAAU,EACnB,QAAO;;AAWX,SAAgB,EAAuB,GAA6C;CAClF,IAAM,IAAY,EAAK,SAAS,SAAS,EAAK,KAAK,OAAO,EAAK,KAAK,WAChE;AACJ,SAAQ,GAAR;EACE,KAAK,EAAU;EACf,KAAK,EAAU;EACf,KAAK,EAAU;EACf,KAAK,EAAU,QAAQ;GACrB,IAAM,IAAS,EAAe,EAAK,MAAM,EAAW,OAAO,EACrD,IAAa,EAAe,EAAK,MAAM,EAAW,WAAW,EAC7D,IAAW,IAAS,EAAG,OAAO,EAAO,GAAG,KAAA;AAC9C,OAAa,EACX,iBAAiB,MAAW;IAC1B,IAAM,IAAY,EAAoB,EAAO,OAAO,EAAW;AAE/D,WADI,MAAc,KAAA,IACX,IAAW,EAAS,OAAO,EAAO,MAAM,CAAC,GAAI,EAAO,OAAO,UAAU,IAAI,KAD5C;MAGvC;AACD;;EAEF;AACE,OAAa,EACX,iBAAiB,MAAW;IAC1B,IAAM,IAAY,EAChB,EAAO,OACP,EAAe,EAAK,MAAM,EAAW,WAAW,CACjD;AAED,WADI,MAAc,KAAA,IACX,EAAO,OAAO,UAAU,IAAI,KADC;MAGvC;AACD;;CAEJ,IAAM,IAAa,EAAe,EAAK,MAAM,EAAW,MAAM,WAAW;AAEzE,QADI,MAAY,EAAW,aAAa,IACjC"}
|
|
@@ -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"}
|
|
@@ -2,7 +2,7 @@ import e from "../../_virtual/_plugin-vue_export-helper.js";
|
|
|
2
2
|
import t from "./PlDatasetSelector.vue2.js";
|
|
3
3
|
import './PlDatasetSelector.style.css';/* empty css */
|
|
4
4
|
//#region src/components/PlDatasetSelector/PlDatasetSelector.vue
|
|
5
|
-
var n = /* @__PURE__ */ e(t, [["__scopeId", "data-v-
|
|
5
|
+
var n = /* @__PURE__ */ e(t, [["__scopeId", "data-v-95f2adf4"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { n as default };
|
|
8
8
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlDatasetSelector.js","names":[],"sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Select a dataset and (optionally) a filter column, emitting a
|
|
1
|
+
{"version":3,"file":"PlDatasetSelector.js","names":[],"sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.\n *\n * Behaves like {@link PlDropdownRef} when none of the offered datasets carry\n * filter options. When the selected dataset has compatible filters, a second\n * dropdown appears with the filters plus a \"No filter\" entry.\n *\n * The emitted value bundles the user's pick (`primary`) with the auto-attached\n * `enrichments` payload from the matching `DatasetOption`. Enrichments are\n * opaque to the UI — block authors unbundle them inside their args resolver.\n */\nexport default {\n name: \"PlDatasetSelector\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport type { DatasetOption, DatasetSelection, PlRef } from \"@platforma-sdk/model\";\nimport { createDatasetSelection, createPrimaryRef, plRefsEqual } from \"@platforma-sdk/model\";\nimport type { ListOption } from \"@milaboratories/uikit\";\nimport { PlDropdown, PlDropdownRef } from \"@milaboratories/uikit\";\nimport { computed } from \"vue\";\n\nconst slots = defineSlots<{\n tooltip?: () => unknown;\n}>();\n\nconst model = defineModel<DatasetSelection | undefined>();\n\nconst props = withDefaults(\n defineProps<{\n /** Available datasets, each optionally carrying compatible filter choices. */\n options?: Readonly<DatasetOption[]>;\n /** Label above the dataset dropdown. */\n label?: string;\n /** Helper text below the dataset dropdown (shown when there is no error). */\n helper?: string;\n /** Helper text shown while `options` is undefined (loading). */\n loadingOptionsHelper?: string;\n /** Error message displayed below the dataset dropdown. */\n error?: unknown;\n /** Placeholder when no dataset is selected. */\n placeholder?: string;\n /** Label above the filter dropdown. */\n filterLabel?: string;\n /** Placeholder for the filter dropdown. */\n filterPlaceholder?: string;\n /** Label of the \"no filter\" entry prepended to the filter options. */\n noFilterLabel?: string;\n /** Show a clear button on the dataset dropdown. */\n clearable?: boolean;\n /** Mark the dataset dropdown as required. */\n required?: boolean;\n /** Disable all interaction. */\n disabled?: boolean;\n }>(),\n {\n options: undefined,\n label: undefined,\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n filterLabel: \"\",\n filterPlaceholder: \"...\",\n noFilterLabel: \"No filter\",\n clearable: false,\n required: false,\n disabled: false,\n },\n);\n\nconst selectedDataset = computed<PlRef | undefined>(() => model.value?.primary.column);\n\nconst selectedFilter = computed<PlRef | undefined>(() => model.value?.primary.filter);\n\nconst currentDatasetOption = computed<DatasetOption | undefined>(() => {\n const dataset = selectedDataset.value;\n if (!dataset) return undefined;\n return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));\n});\n\n// PlDropdownRef expects `Option[]`; project the primary out of each entry.\nconst primaryOptions = computed<readonly { ref: PlRef; label: string }[] | undefined>(() =>\n props.options?.map((o) => o.primary),\n);\n\nconst hasFilters = computed(() => (currentDatasetOption.value?.filters?.length ?? 0) > 0);\n\n/**\n * Filter dropdown options. The first entry (`null`) is the \"No filter\" choice —\n * null distinguishes it from `undefined` (dropdown clear button, disabled here).\n */\nconst filterOptions = computed<ListOption<PlRef | null>[]>(() => {\n const filters = currentDatasetOption.value?.filters;\n if (!filters) return [];\n return [\n { label: props.noFilterLabel, value: null } as ListOption<PlRef | null>,\n ...filters.map((f) => ({ label: f.label, value: f.ref }) as ListOption<PlRef | null>),\n ];\n});\n\nconst filterValue = computed<PlRef | null>(() => selectedFilter.value ?? null);\n\nfunction emitValue(dataset: PlRef | undefined, filter: PlRef | undefined) {\n if (dataset === undefined) {\n model.value = undefined;\n return;\n }\n // Resolve from `props.options` directly — `currentDatasetOption` may not\n // have recomputed yet when this runs synchronously inside a change handler.\n const option = props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));\n model.value = createDatasetSelection(createPrimaryRef(dataset, filter), option?.enrichments);\n}\n\nfunction onDatasetChange(dataset: PlRef | undefined) {\n emitValue(dataset, undefined);\n}\n\nfunction onFilterChange(value: PlRef | null | undefined) {\n const dataset = selectedDataset.value;\n if (!dataset) return;\n emitValue(dataset, value ?? undefined);\n}\n</script>\n\n<template>\n <div class=\"pl-dataset-selector\">\n <PlDropdownRef\n :model-value=\"selectedDataset\"\n :options=\"primaryOptions\"\n :label=\"label\"\n :helper=\"helper\"\n :loading-options-helper=\"loadingOptionsHelper\"\n :error=\"error\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n :required=\"required\"\n :disabled=\"disabled\"\n @update:model-value=\"onDatasetChange\"\n >\n <template v-if=\"slots.tooltip\" #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlDropdownRef>\n <PlDropdown\n v-if=\"hasFilters\"\n :model-value=\"filterValue\"\n :options=\"filterOptions\"\n :label=\"filterLabel\"\n :placeholder=\"filterPlaceholder\"\n :disabled=\"disabled\"\n @update:model-value=\"onFilterChange\"\n />\n </div>\n</template>\n\n<style scoped>\n.pl-dataset-selector {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.pl-dataset-selector[data-v-
|
|
1
|
+
.pl-dataset-selector[data-v-95f2adf4]{flex-direction:column;gap:12px;display:flex}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { DatasetOption,
|
|
1
|
+
import { DatasetOption, DatasetSelection } from '@platforma-sdk/model';
|
|
2
2
|
/**
|
|
3
|
-
* Select a dataset and (optionally) a filter column, emitting a
|
|
3
|
+
* Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.
|
|
4
4
|
*
|
|
5
5
|
* Behaves like {@link PlDropdownRef} when none of the offered datasets carry
|
|
6
6
|
* filter options. When the selected dataset has compatible filters, a second
|
|
7
7
|
* dropdown appears with the filters plus a "No filter" entry.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* The emitted value bundles the user's pick (`primary`) with the auto-attached
|
|
10
|
+
* `enrichments` payload from the matching `DatasetOption`. Enrichments are
|
|
11
|
+
* opaque to the UI — block authors unbundle them inside their args resolver.
|
|
12
12
|
*/
|
|
13
13
|
declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
14
|
-
modelValue?:
|
|
14
|
+
modelValue?: DatasetSelection | undefined;
|
|
15
15
|
} & {
|
|
16
16
|
/** Available datasets, each optionally carrying compatible filter choices. */
|
|
17
17
|
options?: Readonly<DatasetOption[]>;
|
|
@@ -38,14 +38,9 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
38
38
|
/** Disable all interaction. */
|
|
39
39
|
disabled?: boolean;
|
|
40
40
|
}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
41
|
-
"update:modelValue": (value:
|
|
42
|
-
__isRef: true;
|
|
43
|
-
blockId: string;
|
|
44
|
-
name: string;
|
|
45
|
-
requireEnrichments?: true | undefined;
|
|
46
|
-
}> | undefined) => any;
|
|
41
|
+
"update:modelValue": (value: DatasetSelection | undefined) => any;
|
|
47
42
|
}, string, import('vue').PublicProps, Readonly<{
|
|
48
|
-
modelValue?:
|
|
43
|
+
modelValue?: DatasetSelection | undefined;
|
|
49
44
|
} & {
|
|
50
45
|
/** Available datasets, each optionally carrying compatible filter choices. */
|
|
51
46
|
options?: Readonly<DatasetOption[]>;
|
|
@@ -72,12 +67,7 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<{
|
|
|
72
67
|
/** Disable all interaction. */
|
|
73
68
|
disabled?: boolean;
|
|
74
69
|
}> & Readonly<{
|
|
75
|
-
"onUpdate:modelValue"?: ((value:
|
|
76
|
-
__isRef: true;
|
|
77
|
-
blockId: string;
|
|
78
|
-
name: string;
|
|
79
|
-
requireEnrichments?: true | undefined;
|
|
80
|
-
}> | undefined) => any) | undefined;
|
|
70
|
+
"onUpdate:modelValue"?: ((value: DatasetSelection | undefined) => any) | undefined;
|
|
81
71
|
}>, {
|
|
82
72
|
error: undefined;
|
|
83
73
|
label: string;
|
|
@@ -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":"AAuKA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAS,MAAM,sBAAsB,CAAC;AAOnF;;;;;;;;;;GAUG;;iBA2HU,gBAAgB,GAAG,SAAS;;IAlHrC,8EAA8E;cACpE,QAAQ,CAAC,aAAa,EAAE,CAAC;IACnC,wCAAwC;YAChC,MAAM;IACd,6EAA6E;aACpE,MAAM;IACf,gEAAgE;2BACzC,MAAM;IAC7B,0DAA0D;YAClD,OAAO;IACf,+CAA+C;kBACjC,MAAM;IACpB,uCAAuC;kBACzB,MAAM;IACpB,2CAA2C;wBACvB,MAAM;IAC1B,sEAAsE;oBACtD,MAAM;IACtB,mDAAmD;gBACvC,OAAO;IACnB,6CAA6C;eAClC,OAAO;IAClB,+BAA+B;eACpB,OAAO;;;;iBA2FT,gBAAgB,GAAG,SAAS;;IAlHrC,8EAA8E;cACpE,QAAQ,CAAC,aAAa,EAAE,CAAC;IACnC,wCAAwC;YAChC,MAAM;IACd,6EAA6E;aACpE,MAAM;IACf,gEAAgE;2BACzC,MAAM;IAC7B,0DAA0D;YAClD,OAAO;IACf,+CAA+C;kBACjC,MAAM;IACpB,uCAAuC;kBACzB,MAAM;IACpB,2CAA2C;wBACvB,MAAM;IAC1B,sEAAsE;oBACtD,MAAM;IACtB,mDAAmD;gBACvC,OAAO;IACnB,6CAA6C;eAClC,OAAO;IAClB,+BAA+B;eACpB,OAAO;;;;;WApBV,MAAM;iBAQA,MAAM;aAVV,QAAQ,CAAC,aAAa,EAAE,CAAC;YAI1B,MAAM;0BAEQ,MAAM;eAYjB,OAAO;cAER,OAAO;cAEP,OAAO;iBAVJ,MAAM;uBAEA,MAAM;mBAEV,MAAM;;cAvBd,MAAM,OAAO;;cAAb,MAAM,OAAO;;AAFzB,wBAqQK;AAcL,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed as e, createBlock as t, createCommentVNode as n, createElementBlock as r, createSlots as i, createVNode as a, defineComponent as o, mergeModels as s, openBlock as c, renderSlot as l, unref as u, useModel as d, useSlots as f, withCtx as p } from "vue";
|
|
2
|
-
import {
|
|
2
|
+
import { createDatasetSelection as m, createPrimaryRef as h, plRefsEqual as g } from "@platforma-sdk/model";
|
|
3
3
|
import { PlDropdown as _, PlDropdownRef as v } from "@milaboratories/uikit";
|
|
4
4
|
//#region src/components/PlDatasetSelector/PlDatasetSelector.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
@@ -32,16 +32,10 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
32
32
|
}),
|
|
33
33
|
emits: ["update:modelValue"],
|
|
34
34
|
setup(o) {
|
|
35
|
-
let s = f(), b = d(o, "modelValue"), x = o, S = e(() => {
|
|
36
|
-
let e = b.value;
|
|
37
|
-
if (e !== void 0) return h(e) ? e.column : e;
|
|
38
|
-
}), C = e(() => {
|
|
39
|
-
let e = b.value;
|
|
40
|
-
return h(e) ? e.filter : void 0;
|
|
41
|
-
}), w = e(() => {
|
|
35
|
+
let s = f(), b = d(o, "modelValue"), x = o, S = e(() => b.value?.primary.column), C = e(() => b.value?.primary.filter), w = e(() => {
|
|
42
36
|
let e = S.value;
|
|
43
|
-
if (e) return x.options?.find((t) => g(t.ref, e, !0));
|
|
44
|
-
}), T = e(() => (w.value?.filters?.length ?? 0) > 0),
|
|
37
|
+
if (e) return x.options?.find((t) => g(t.primary.ref, e, !0));
|
|
38
|
+
}), T = e(() => x.options?.map((e) => e.primary)), E = e(() => (w.value?.filters?.length ?? 0) > 0), D = e(() => {
|
|
45
39
|
let e = w.value?.filters;
|
|
46
40
|
return e ? [{
|
|
47
41
|
label: x.noFilterLabel,
|
|
@@ -50,20 +44,25 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
50
44
|
label: e.label,
|
|
51
45
|
value: e.ref
|
|
52
46
|
}))] : [];
|
|
53
|
-
}),
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
}), O = e(() => C.value ?? null);
|
|
48
|
+
function k(e, t) {
|
|
49
|
+
if (e === void 0) {
|
|
50
|
+
b.value = void 0;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
let n = x.options?.find((t) => g(t.primary.ref, e, !0));
|
|
54
|
+
b.value = m(h(e, t), n?.enrichments);
|
|
59
55
|
}
|
|
60
56
|
function A(e) {
|
|
57
|
+
k(e, void 0);
|
|
58
|
+
}
|
|
59
|
+
function j(e) {
|
|
61
60
|
let t = S.value;
|
|
62
|
-
t &&
|
|
61
|
+
t && k(t, e ?? void 0);
|
|
63
62
|
}
|
|
64
63
|
return (e, d) => (c(), r("div", y, [a(u(v), {
|
|
65
64
|
"model-value": S.value,
|
|
66
|
-
options:
|
|
65
|
+
options: T.value,
|
|
67
66
|
label: o.label,
|
|
68
67
|
helper: o.helper,
|
|
69
68
|
"loading-options-helper": o.loadingOptionsHelper,
|
|
@@ -72,7 +71,7 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
72
71
|
clearable: o.clearable,
|
|
73
72
|
required: o.required,
|
|
74
73
|
disabled: o.disabled,
|
|
75
|
-
"onUpdate:modelValue":
|
|
74
|
+
"onUpdate:modelValue": A
|
|
76
75
|
}, i({ _: 2 }, [s.tooltip ? {
|
|
77
76
|
name: "tooltip",
|
|
78
77
|
fn: p(() => [l(e.$slots, "tooltip", {}, void 0, !0)]),
|
|
@@ -88,14 +87,14 @@ var y = { class: "pl-dataset-selector" }, b = /* @__PURE__ */ o({
|
|
|
88
87
|
"clearable",
|
|
89
88
|
"required",
|
|
90
89
|
"disabled"
|
|
91
|
-
]),
|
|
90
|
+
]), E.value ? (c(), t(u(_), {
|
|
92
91
|
key: 0,
|
|
93
|
-
"model-value":
|
|
94
|
-
options:
|
|
92
|
+
"model-value": O.value,
|
|
93
|
+
options: D.value,
|
|
95
94
|
label: o.filterLabel,
|
|
96
95
|
placeholder: o.filterPlaceholder,
|
|
97
96
|
disabled: o.disabled,
|
|
98
|
-
"onUpdate:modelValue":
|
|
97
|
+
"onUpdate:modelValue": j
|
|
99
98
|
}, null, 8, [
|
|
100
99
|
"model-value",
|
|
101
100
|
"options",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlDatasetSelector.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Select a dataset and (optionally) a filter column, emitting a
|
|
1
|
+
{"version":3,"file":"PlDatasetSelector.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlDatasetSelector/PlDatasetSelector.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.\n *\n * Behaves like {@link PlDropdownRef} when none of the offered datasets carry\n * filter options. When the selected dataset has compatible filters, a second\n * dropdown appears with the filters plus a \"No filter\" entry.\n *\n * The emitted value bundles the user's pick (`primary`) with the auto-attached\n * `enrichments` payload from the matching `DatasetOption`. Enrichments are\n * opaque to the UI — block authors unbundle them inside their args resolver.\n */\nexport default {\n name: \"PlDatasetSelector\",\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport type { DatasetOption, DatasetSelection, PlRef } from \"@platforma-sdk/model\";\nimport { createDatasetSelection, createPrimaryRef, plRefsEqual } from \"@platforma-sdk/model\";\nimport type { ListOption } from \"@milaboratories/uikit\";\nimport { PlDropdown, PlDropdownRef } from \"@milaboratories/uikit\";\nimport { computed } from \"vue\";\n\nconst slots = defineSlots<{\n tooltip?: () => unknown;\n}>();\n\nconst model = defineModel<DatasetSelection | undefined>();\n\nconst props = withDefaults(\n defineProps<{\n /** Available datasets, each optionally carrying compatible filter choices. */\n options?: Readonly<DatasetOption[]>;\n /** Label above the dataset dropdown. */\n label?: string;\n /** Helper text below the dataset dropdown (shown when there is no error). */\n helper?: string;\n /** Helper text shown while `options` is undefined (loading). */\n loadingOptionsHelper?: string;\n /** Error message displayed below the dataset dropdown. */\n error?: unknown;\n /** Placeholder when no dataset is selected. */\n placeholder?: string;\n /** Label above the filter dropdown. */\n filterLabel?: string;\n /** Placeholder for the filter dropdown. */\n filterPlaceholder?: string;\n /** Label of the \"no filter\" entry prepended to the filter options. */\n noFilterLabel?: string;\n /** Show a clear button on the dataset dropdown. */\n clearable?: boolean;\n /** Mark the dataset dropdown as required. */\n required?: boolean;\n /** Disable all interaction. */\n disabled?: boolean;\n }>(),\n {\n options: undefined,\n label: undefined,\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n placeholder: \"...\",\n filterLabel: \"\",\n filterPlaceholder: \"...\",\n noFilterLabel: \"No filter\",\n clearable: false,\n required: false,\n disabled: false,\n },\n);\n\nconst selectedDataset = computed<PlRef | undefined>(() => model.value?.primary.column);\n\nconst selectedFilter = computed<PlRef | undefined>(() => model.value?.primary.filter);\n\nconst currentDatasetOption = computed<DatasetOption | undefined>(() => {\n const dataset = selectedDataset.value;\n if (!dataset) return undefined;\n return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));\n});\n\n// PlDropdownRef expects `Option[]`; project the primary out of each entry.\nconst primaryOptions = computed<readonly { ref: PlRef; label: string }[] | undefined>(() =>\n props.options?.map((o) => o.primary),\n);\n\nconst hasFilters = computed(() => (currentDatasetOption.value?.filters?.length ?? 0) > 0);\n\n/**\n * Filter dropdown options. The first entry (`null`) is the \"No filter\" choice —\n * null distinguishes it from `undefined` (dropdown clear button, disabled here).\n */\nconst filterOptions = computed<ListOption<PlRef | null>[]>(() => {\n const filters = currentDatasetOption.value?.filters;\n if (!filters) return [];\n return [\n { label: props.noFilterLabel, value: null } as ListOption<PlRef | null>,\n ...filters.map((f) => ({ label: f.label, value: f.ref }) as ListOption<PlRef | null>),\n ];\n});\n\nconst filterValue = computed<PlRef | null>(() => selectedFilter.value ?? null);\n\nfunction emitValue(dataset: PlRef | undefined, filter: PlRef | undefined) {\n if (dataset === undefined) {\n model.value = undefined;\n return;\n }\n // Resolve from `props.options` directly — `currentDatasetOption` may not\n // have recomputed yet when this runs synchronously inside a change handler.\n const option = props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));\n model.value = createDatasetSelection(createPrimaryRef(dataset, filter), option?.enrichments);\n}\n\nfunction onDatasetChange(dataset: PlRef | undefined) {\n emitValue(dataset, undefined);\n}\n\nfunction onFilterChange(value: PlRef | null | undefined) {\n const dataset = selectedDataset.value;\n if (!dataset) return;\n emitValue(dataset, value ?? undefined);\n}\n</script>\n\n<template>\n <div class=\"pl-dataset-selector\">\n <PlDropdownRef\n :model-value=\"selectedDataset\"\n :options=\"primaryOptions\"\n :label=\"label\"\n :helper=\"helper\"\n :loading-options-helper=\"loadingOptionsHelper\"\n :error=\"error\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n :required=\"required\"\n :disabled=\"disabled\"\n @update:model-value=\"onDatasetChange\"\n >\n <template v-if=\"slots.tooltip\" #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlDropdownRef>\n <PlDropdown\n v-if=\"hasFilters\"\n :model-value=\"filterValue\"\n :options=\"filterOptions\"\n :label=\"filterLabel\"\n :placeholder=\"filterPlaceholder\"\n :disabled=\"disabled\"\n @update:model-value=\"onFilterChange\"\n />\n </div>\n</template>\n\n<style scoped>\n.pl-dataset-selector {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n</style>\n"],"mappings":";;;;;CAaE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWR,IAAM,IAAQ,GAEV,EAEE,IAAQ,EAAyC,GAAA,aAAE,EAEnD,IAAQ,GA2CR,IAAkB,QAAkC,EAAM,OAAO,QAAQ,OAAO,EAEhF,IAAiB,QAAkC,EAAM,OAAO,QAAQ,OAAO,EAE/E,IAAuB,QAA0C;GACrE,IAAM,IAAU,EAAgB;AAC3B,SACL,QAAO,EAAM,SAAS,MAAM,MAAM,EAAY,EAAE,QAAQ,KAAK,GAAS,GAAK,CAAC;IAC5E,EAGI,IAAiB,QACrB,EAAM,SAAS,KAAK,MAAM,EAAE,QAAQ,CACrC,EAEK,IAAa,SAAgB,EAAqB,OAAO,SAAS,UAAU,KAAK,EAAE,EAMnF,IAAgB,QAA2C;GAC/D,IAAM,IAAU,EAAqB,OAAO;AAE5C,UADK,IACE,CACL;IAAE,OAAO,EAAM;IAAe,OAAO;IAAM,EAC3C,GAAG,EAAQ,KAAK,OAAO;IAAE,OAAO,EAAE;IAAO,OAAO,EAAE;IAAK,EAA8B,CACtF,GAJoB,EAAE;IAKvB,EAEI,IAAc,QAA6B,EAAe,SAAS,KAAK;EAE9E,SAAS,EAAU,GAA4B,GAA2B;AACxE,OAAI,MAAY,KAAA,GAAW;AACzB,MAAM,QAAQ,KAAA;AACd;;GAIF,IAAM,IAAS,EAAM,SAAS,MAAM,MAAM,EAAY,EAAE,QAAQ,KAAK,GAAS,GAAK,CAAC;AACpF,KAAM,QAAQ,EAAuB,EAAiB,GAAS,EAAO,EAAE,GAAQ,YAAY;;EAG9F,SAAS,EAAgB,GAA4B;AACnD,KAAU,GAAS,KAAA,EAAU;;EAG/B,SAAS,EAAe,GAAiC;GACvD,IAAM,IAAU,EAAgB;AAC3B,QACL,EAAU,GAAS,KAAS,KAAA,EAAU;;yBAKtC,EA2BM,OA3BN,GA2BM,CA1BJ,EAgBgB,EAAA,EAAA,EAAA;GAfb,eAAa,EAAA;GACb,SAAS,EAAA;GACT,OAAO,EAAA;GACP,QAAQ,EAAA;GACR,0BAAwB,EAAA;GACxB,OAAO,EAAA;GACP,aAAa,EAAA;GACb,WAAW,EAAA;GACX,UAAU,EAAA;GACV,UAAU,EAAA;GACV,uBAAoB;kBAEL,EAAM,UAAA;SAAU;eACP,CAAvB,EAAuB,EAAA,QAAA,WAAA,EAAA,EAAA,KAAA,GAAA,GAAA,CAAA,CAAA;;;;;;;;;;;;;MAInB,EAAA,SAAA,GAAA,EADR,EAQE,EAAA,EAAA,EAAA;;GANC,eAAa,EAAA;GACb,SAAS,EAAA;GACT,OAAO,EAAA;GACP,aAAa,EAAA;GACb,UAAU,EAAA;GACV,uBAAoB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.71.0",
|
|
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/pf-spec-driver": "1.3.
|
|
30
|
-
"@milaboratories/
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
29
|
+
"@milaboratories/pf-spec-driver": "1.3.8",
|
|
30
|
+
"@milaboratories/pl-model-common": "1.38.0",
|
|
31
|
+
"@milaboratories/uikit": "2.13.2",
|
|
32
|
+
"@platforma-sdk/model": "1.71.0"
|
|
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/helpers": "1.14.1",
|
|
48
49
|
"@milaboratories/build-configs": "2.0.0",
|
|
49
50
|
"@milaboratories/ts-configs": "1.2.3",
|
|
50
|
-
"@milaboratories/helpers": "1.14.1",
|
|
51
51
|
"@milaboratories/ts-builder": "1.3.2"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import type { PTableValue } from "@platforma-sdk/model";
|
|
2
|
-
|
|
3
1
|
export const PTableHidden = { type: "hidden" } as const;
|
|
4
2
|
export type PTableHidden = typeof PTableHidden;
|
|
5
3
|
|
|
6
|
-
export function isPTableHidden(value:
|
|
7
|
-
return typeof value === "object" && value !== null && value.type === "hidden";
|
|
4
|
+
export function isPTableHidden(value: unknown): value is PTableHidden {
|
|
5
|
+
return typeof value === "object" && value !== null && "type" in value && value.type === "hidden";
|
|
8
6
|
}
|
|
@@ -13,10 +13,15 @@ import * as d3 from "d3-format";
|
|
|
13
13
|
import type { PlAgDataTableV2Row } from "../types";
|
|
14
14
|
|
|
15
15
|
export function formatSpecialValues(
|
|
16
|
-
value:
|
|
16
|
+
value: undefined | PTableValue | PTableHidden,
|
|
17
|
+
dataStatus: undefined | "absent" | "error" | "computing" | "ready",
|
|
17
18
|
): string | undefined {
|
|
18
|
-
if (
|
|
19
|
-
return "
|
|
19
|
+
if (dataStatus === "absent") {
|
|
20
|
+
return "absent";
|
|
21
|
+
} else if (dataStatus === "error") {
|
|
22
|
+
return "error";
|
|
23
|
+
} else if (dataStatus === "computing") {
|
|
24
|
+
return "computing...";
|
|
20
25
|
} else if (isPTableHidden(value)) {
|
|
21
26
|
return "loading...";
|
|
22
27
|
} else if (value === PTableNA) {
|
|
@@ -40,12 +45,13 @@ export function getColumnRenderingSpec(spec: PTableColumnSpec): ColumnRenderingS
|
|
|
40
45
|
case ValueType.Float:
|
|
41
46
|
case ValueType.Double: {
|
|
42
47
|
const format = readAnnotation(spec.spec, Annotation.Format);
|
|
48
|
+
const dataStatus = readAnnotation(spec.spec, Annotation.DataStatus);
|
|
43
49
|
const formatFn = format ? d3.format(format) : undefined;
|
|
44
50
|
renderSpec = {
|
|
45
51
|
valueFormatter: (params) => {
|
|
46
|
-
const formatted = formatSpecialValues(params.value);
|
|
52
|
+
const formatted = formatSpecialValues(params.value, dataStatus);
|
|
47
53
|
if (formatted !== undefined) return formatted;
|
|
48
|
-
return formatFn ? formatFn(Number(params.value)) : params.value
|
|
54
|
+
return formatFn ? formatFn(Number(params.value)) : (params.value?.toString() ?? "");
|
|
49
55
|
},
|
|
50
56
|
};
|
|
51
57
|
break;
|
|
@@ -53,9 +59,12 @@ export function getColumnRenderingSpec(spec: PTableColumnSpec): ColumnRenderingS
|
|
|
53
59
|
default:
|
|
54
60
|
renderSpec = {
|
|
55
61
|
valueFormatter: (params) => {
|
|
56
|
-
const formatted = formatSpecialValues(
|
|
62
|
+
const formatted = formatSpecialValues(
|
|
63
|
+
params.value,
|
|
64
|
+
readAnnotation(spec.spec, Annotation.DataStatus),
|
|
65
|
+
);
|
|
57
66
|
if (formatted !== undefined) return formatted;
|
|
58
|
-
return params.value
|
|
67
|
+
return params.value?.toString() ?? "";
|
|
59
68
|
},
|
|
60
69
|
};
|
|
61
70
|
break;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/**
|
|
3
|
-
* Select a dataset and (optionally) a filter column, emitting a
|
|
3
|
+
* Select a dataset and (optionally) a filter column, emitting a {@link DatasetSelection}.
|
|
4
4
|
*
|
|
5
5
|
* Behaves like {@link PlDropdownRef} when none of the offered datasets carry
|
|
6
6
|
* filter options. When the selected dataset has compatible filters, a second
|
|
7
7
|
* dropdown appears with the filters plus a "No filter" entry.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* The emitted value bundles the user's pick (`primary`) with the auto-attached
|
|
10
|
+
* `enrichments` payload from the matching `DatasetOption`. Enrichments are
|
|
11
|
+
* opaque to the UI — block authors unbundle them inside their args resolver.
|
|
12
12
|
*/
|
|
13
13
|
export default {
|
|
14
14
|
name: "PlDatasetSelector",
|
|
@@ -16,8 +16,8 @@ export default {
|
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
18
|
<script lang="ts" setup>
|
|
19
|
-
import type { DatasetOption,
|
|
20
|
-
import {
|
|
19
|
+
import type { DatasetOption, DatasetSelection, PlRef } from "@platforma-sdk/model";
|
|
20
|
+
import { createDatasetSelection, createPrimaryRef, plRefsEqual } from "@platforma-sdk/model";
|
|
21
21
|
import type { ListOption } from "@milaboratories/uikit";
|
|
22
22
|
import { PlDropdown, PlDropdownRef } from "@milaboratories/uikit";
|
|
23
23
|
import { computed } from "vue";
|
|
@@ -26,11 +26,7 @@ const slots = defineSlots<{
|
|
|
26
26
|
tooltip?: () => unknown;
|
|
27
27
|
}>();
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
* v-model value. Accepts `PrimaryRef`, plain `PlRef` (treated as unfiltered),
|
|
31
|
-
* or `undefined`. Writes always emit `PrimaryRef` or `undefined`.
|
|
32
|
-
*/
|
|
33
|
-
const model = defineModel<PrimaryRef | PlRef | undefined>();
|
|
29
|
+
const model = defineModel<DatasetSelection | undefined>();
|
|
34
30
|
|
|
35
31
|
const props = withDefaults(
|
|
36
32
|
defineProps<{
|
|
@@ -75,23 +71,21 @@ const props = withDefaults(
|
|
|
75
71
|
},
|
|
76
72
|
);
|
|
77
73
|
|
|
78
|
-
const selectedDataset = computed<PlRef | undefined>(() =>
|
|
79
|
-
const v = model.value;
|
|
80
|
-
if (v === undefined) return undefined;
|
|
81
|
-
return isPrimaryRef(v) ? v.column : v;
|
|
82
|
-
});
|
|
74
|
+
const selectedDataset = computed<PlRef | undefined>(() => model.value?.primary.column);
|
|
83
75
|
|
|
84
|
-
const selectedFilter = computed<PlRef | undefined>(() =>
|
|
85
|
-
const v = model.value;
|
|
86
|
-
return isPrimaryRef(v) ? v.filter : undefined;
|
|
87
|
-
});
|
|
76
|
+
const selectedFilter = computed<PlRef | undefined>(() => model.value?.primary.filter);
|
|
88
77
|
|
|
89
78
|
const currentDatasetOption = computed<DatasetOption | undefined>(() => {
|
|
90
79
|
const dataset = selectedDataset.value;
|
|
91
80
|
if (!dataset) return undefined;
|
|
92
|
-
return props.options?.find((o) => plRefsEqual(o.ref, dataset, true));
|
|
81
|
+
return props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));
|
|
93
82
|
});
|
|
94
83
|
|
|
84
|
+
// PlDropdownRef expects `Option[]`; project the primary out of each entry.
|
|
85
|
+
const primaryOptions = computed<readonly { ref: PlRef; label: string }[] | undefined>(() =>
|
|
86
|
+
props.options?.map((o) => o.primary),
|
|
87
|
+
);
|
|
88
|
+
|
|
95
89
|
const hasFilters = computed(() => (currentDatasetOption.value?.filters?.length ?? 0) > 0);
|
|
96
90
|
|
|
97
91
|
/**
|
|
@@ -110,7 +104,14 @@ const filterOptions = computed<ListOption<PlRef | null>[]>(() => {
|
|
|
110
104
|
const filterValue = computed<PlRef | null>(() => selectedFilter.value ?? null);
|
|
111
105
|
|
|
112
106
|
function emitValue(dataset: PlRef | undefined, filter: PlRef | undefined) {
|
|
113
|
-
|
|
107
|
+
if (dataset === undefined) {
|
|
108
|
+
model.value = undefined;
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Resolve from `props.options` directly — `currentDatasetOption` may not
|
|
112
|
+
// have recomputed yet when this runs synchronously inside a change handler.
|
|
113
|
+
const option = props.options?.find((o) => plRefsEqual(o.primary.ref, dataset, true));
|
|
114
|
+
model.value = createDatasetSelection(createPrimaryRef(dataset, filter), option?.enrichments);
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
function onDatasetChange(dataset: PlRef | undefined) {
|
|
@@ -128,7 +129,7 @@ function onFilterChange(value: PlRef | null | undefined) {
|
|
|
128
129
|
<div class="pl-dataset-selector">
|
|
129
130
|
<PlDropdownRef
|
|
130
131
|
:model-value="selectedDataset"
|
|
131
|
-
:options="
|
|
132
|
+
:options="primaryOptions"
|
|
132
133
|
:label="label"
|
|
133
134
|
:helper="helper"
|
|
134
135
|
:loading-options-helper="loadingOptionsHelper"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { flushPromises, mount } from "@vue/test-utils";
|
|
2
|
-
import type { DatasetOption,
|
|
3
|
-
import { createPlRef, createPrimaryRef } from "@platforma-sdk/model";
|
|
2
|
+
import type { DatasetOption, DatasetSelection } from "@platforma-sdk/model";
|
|
3
|
+
import { createDatasetSelection, createPlRef, createPrimaryRef } from "@platforma-sdk/model";
|
|
4
4
|
import { describe, expect, it } from "vitest";
|
|
5
5
|
import PlDatasetSelector from "../PlDatasetSelector.vue";
|
|
6
6
|
|
|
@@ -9,27 +9,41 @@ const datasetB = createPlRef("2", "out-b", true);
|
|
|
9
9
|
const filterA1 = createPlRef("1", "filter-a1");
|
|
10
10
|
const filterA2 = createPlRef("1", "filter-a2");
|
|
11
11
|
|
|
12
|
+
import type { PObjectId } from "@platforma-sdk/model";
|
|
13
|
+
const enrichmentA = "enrichment-a" as PObjectId;
|
|
14
|
+
const enrichmentsA = [
|
|
15
|
+
{ ref: { __isEnrichment: "v1" as const, hit: enrichmentA }, label: "Enrichment A" },
|
|
16
|
+
];
|
|
17
|
+
|
|
12
18
|
const optionsWithFilters: DatasetOption[] = [
|
|
13
19
|
{
|
|
14
|
-
label: "Dataset A",
|
|
15
|
-
ref: datasetA,
|
|
20
|
+
primary: { label: "Dataset A", ref: datasetA },
|
|
16
21
|
filters: [
|
|
17
22
|
{ label: "Top 1000", ref: filterA1 },
|
|
18
23
|
{ label: "High quality", ref: filterA2 },
|
|
19
24
|
],
|
|
25
|
+
enrichments: enrichmentsA,
|
|
20
26
|
},
|
|
21
27
|
// Dataset B has no filters — filter dropdown must stay hidden.
|
|
22
|
-
{ label: "Dataset B", ref: datasetB },
|
|
28
|
+
{ primary: { label: "Dataset B", ref: datasetB } },
|
|
23
29
|
];
|
|
24
30
|
|
|
25
31
|
const datasetC = createPlRef("3", "out-c", true);
|
|
26
32
|
|
|
27
|
-
const optionsNoFilters: DatasetOption[] = [{ label: "Dataset B", ref: datasetB }];
|
|
33
|
+
const optionsNoFilters: DatasetOption[] = [{ primary: { label: "Dataset B", ref: datasetB } }];
|
|
28
34
|
|
|
29
35
|
const optionsWithEmptyFilters: DatasetOption[] = [
|
|
30
|
-
{ label: "Dataset C", ref: datasetC, filters: [] },
|
|
36
|
+
{ primary: { label: "Dataset C", ref: datasetC }, filters: [] },
|
|
31
37
|
];
|
|
32
38
|
|
|
39
|
+
function selection(
|
|
40
|
+
ref: typeof datasetA,
|
|
41
|
+
filter?: typeof filterA1,
|
|
42
|
+
enrichments?: typeof enrichmentsA,
|
|
43
|
+
): DatasetSelection {
|
|
44
|
+
return createDatasetSelection(createPrimaryRef(ref, filter), enrichments);
|
|
45
|
+
}
|
|
46
|
+
|
|
33
47
|
async function pickOption(index: number) {
|
|
34
48
|
const options = [...document.body.querySelectorAll(".dropdown-list-item")] as HTMLElement[];
|
|
35
49
|
options[index].click();
|
|
@@ -53,7 +67,7 @@ describe("PlDatasetSelector", () => {
|
|
|
53
67
|
|
|
54
68
|
it("shows the filter dropdown when the selected dataset has filters", async () => {
|
|
55
69
|
const wrapper = mount(PlDatasetSelector, {
|
|
56
|
-
props: { modelValue:
|
|
70
|
+
props: { modelValue: selection(datasetA), options: optionsWithFilters },
|
|
57
71
|
attachTo: document.body,
|
|
58
72
|
});
|
|
59
73
|
await flushPromises();
|
|
@@ -64,7 +78,7 @@ describe("PlDatasetSelector", () => {
|
|
|
64
78
|
|
|
65
79
|
it("hides the filter dropdown when the selected dataset has no filters", async () => {
|
|
66
80
|
const wrapper = mount(PlDatasetSelector, {
|
|
67
|
-
props: { modelValue:
|
|
81
|
+
props: { modelValue: selection(datasetB), options: optionsWithFilters },
|
|
68
82
|
attachTo: document.body,
|
|
69
83
|
});
|
|
70
84
|
await flushPromises();
|
|
@@ -73,63 +87,69 @@ describe("PlDatasetSelector", () => {
|
|
|
73
87
|
wrapper.unmount();
|
|
74
88
|
});
|
|
75
89
|
|
|
76
|
-
it("emits
|
|
90
|
+
it("emits DatasetSelection bundling primary + enrichments when dataset changes", async () => {
|
|
77
91
|
const wrapper = mount(PlDatasetSelector, {
|
|
78
92
|
props: {
|
|
79
|
-
modelValue:
|
|
93
|
+
modelValue: selection(datasetA, filterA1, enrichmentsA),
|
|
80
94
|
options: optionsWithFilters,
|
|
81
|
-
"onUpdate:modelValue": (e
|
|
95
|
+
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
96
|
+
wrapper.setProps({ modelValue: e }),
|
|
82
97
|
},
|
|
83
98
|
attachTo: document.body,
|
|
84
99
|
});
|
|
85
100
|
await flushPromises();
|
|
86
101
|
|
|
87
|
-
// Open the dataset dropdown (the first input — dataset comes first).
|
|
88
102
|
const inputs = wrapper.findAll("input");
|
|
89
103
|
await inputs[0].trigger("focus");
|
|
90
|
-
|
|
91
|
-
// Dataset A is already selected (index 0); pick Dataset B (index 1).
|
|
104
|
+
// Dataset A is index 0; pick Dataset B (index 1) — has no enrichments.
|
|
92
105
|
await pickOption(1);
|
|
93
106
|
|
|
94
107
|
const emitted = wrapper.emitted("update:modelValue");
|
|
95
108
|
expect(emitted).toBeDefined();
|
|
96
|
-
const last = emitted![emitted!.length - 1][0] as
|
|
97
|
-
expect(last).toEqual({
|
|
109
|
+
const last = emitted![emitted!.length - 1][0] as DatasetSelection;
|
|
110
|
+
expect(last).toEqual({
|
|
111
|
+
__isDatasetSelection: "v1",
|
|
112
|
+
primary: { __isPrimaryRef: "v1", column: datasetB },
|
|
113
|
+
});
|
|
98
114
|
wrapper.unmount();
|
|
99
115
|
});
|
|
100
116
|
|
|
101
|
-
it("emits
|
|
117
|
+
it("emits DatasetSelection with filter set when a filter is picked", async () => {
|
|
102
118
|
const wrapper = mount(PlDatasetSelector, {
|
|
103
119
|
props: {
|
|
104
|
-
modelValue:
|
|
120
|
+
modelValue: selection(datasetA, undefined, enrichmentsA),
|
|
105
121
|
options: optionsWithFilters,
|
|
106
|
-
"onUpdate:modelValue": (e
|
|
122
|
+
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
123
|
+
wrapper.setProps({ modelValue: e }),
|
|
107
124
|
},
|
|
108
125
|
attachTo: document.body,
|
|
109
126
|
});
|
|
110
127
|
await flushPromises();
|
|
111
128
|
|
|
112
|
-
// Open the filter dropdown — it's the second input in the component.
|
|
113
129
|
const inputs = wrapper.findAll("input");
|
|
114
130
|
expect(inputs.length).toBe(2);
|
|
115
131
|
await inputs[1].trigger("focus");
|
|
116
|
-
|
|
117
|
-
// Options are: [No filter, Top 1000, High quality]. Pick "Top 1000" (index 1).
|
|
132
|
+
// Options: [No filter, Top 1000, High quality]. Pick "Top 1000".
|
|
118
133
|
await pickOption(1);
|
|
119
134
|
|
|
120
135
|
const emitted = wrapper.emitted("update:modelValue");
|
|
121
136
|
expect(emitted).toBeDefined();
|
|
122
|
-
const last = emitted![emitted!.length - 1][0] as
|
|
123
|
-
expect(last).toEqual({
|
|
137
|
+
const last = emitted![emitted!.length - 1][0] as DatasetSelection;
|
|
138
|
+
expect(last).toEqual({
|
|
139
|
+
__isDatasetSelection: "v1",
|
|
140
|
+
primary: { __isPrimaryRef: "v1", column: datasetA, filter: filterA1 },
|
|
141
|
+
enrichments: enrichmentsA,
|
|
142
|
+
});
|
|
124
143
|
wrapper.unmount();
|
|
125
144
|
});
|
|
126
145
|
|
|
127
|
-
it("emits
|
|
146
|
+
it("emits DatasetSelection with no filter key when 'No filter' is picked", async () => {
|
|
128
147
|
const wrapper = mount(PlDatasetSelector, {
|
|
129
148
|
props: {
|
|
130
|
-
modelValue:
|
|
149
|
+
modelValue: selection(datasetA, filterA1, enrichmentsA),
|
|
131
150
|
options: optionsWithFilters,
|
|
132
|
-
"onUpdate:modelValue": (e
|
|
151
|
+
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
152
|
+
wrapper.setProps({ modelValue: e }),
|
|
133
153
|
},
|
|
134
154
|
attachTo: document.body,
|
|
135
155
|
});
|
|
@@ -137,43 +157,20 @@ describe("PlDatasetSelector", () => {
|
|
|
137
157
|
|
|
138
158
|
const inputs = wrapper.findAll("input");
|
|
139
159
|
await inputs[1].trigger("focus");
|
|
140
|
-
//
|
|
141
|
-
await pickOption(0);
|
|
160
|
+
await pickOption(0); // "No filter"
|
|
142
161
|
|
|
143
162
|
const emitted = wrapper.emitted("update:modelValue");
|
|
144
163
|
expect(emitted).toBeDefined();
|
|
145
|
-
const last = emitted![emitted!.length - 1][0] as
|
|
146
|
-
expect(last).toEqual({ __isPrimaryRef: "v1", column: datasetA });
|
|
147
|
-
expect("filter" in last).toBe(false);
|
|
148
|
-
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it("accepts plain PlRef as modelValue for backward compat (filterless dataset)", async () => {
|
|
152
|
-
const wrapper = mount(PlDatasetSelector, {
|
|
153
|
-
props: { modelValue: datasetB, options: optionsWithFilters },
|
|
154
|
-
attachTo: document.body,
|
|
155
|
-
});
|
|
156
|
-
await flushPromises();
|
|
157
|
-
|
|
158
|
-
expect(wrapper.find(".pl-dataset-selector").element.children.length).toBe(1);
|
|
159
|
-
wrapper.unmount();
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("accepts plain PlRef as modelValue for backward compat (dataset with filters)", async () => {
|
|
163
|
-
const wrapper = mount(PlDatasetSelector, {
|
|
164
|
-
props: { modelValue: datasetA, options: optionsWithFilters },
|
|
165
|
-
attachTo: document.body,
|
|
166
|
-
});
|
|
167
|
-
await flushPromises();
|
|
168
|
-
|
|
169
|
-
// PlRef matching dataset A — filter dropdown should appear since A has filters.
|
|
170
|
-
expect(wrapper.find(".pl-dataset-selector").element.children.length).toBe(2);
|
|
164
|
+
const last = emitted![emitted!.length - 1][0] as DatasetSelection;
|
|
165
|
+
expect(last.primary).toEqual({ __isPrimaryRef: "v1", column: datasetA });
|
|
166
|
+
expect("filter" in last.primary).toBe(false);
|
|
167
|
+
expect(last.enrichments).toEqual(enrichmentsA);
|
|
171
168
|
wrapper.unmount();
|
|
172
169
|
});
|
|
173
170
|
|
|
174
171
|
it("hides filter dropdown when dataset has filters: [] (empty array)", async () => {
|
|
175
172
|
const wrapper = mount(PlDatasetSelector, {
|
|
176
|
-
props: { modelValue:
|
|
173
|
+
props: { modelValue: selection(datasetC), options: optionsWithEmptyFilters },
|
|
177
174
|
attachTo: document.body,
|
|
178
175
|
});
|
|
179
176
|
await flushPromises();
|
|
@@ -182,25 +179,22 @@ describe("PlDatasetSelector", () => {
|
|
|
182
179
|
wrapper.unmount();
|
|
183
180
|
});
|
|
184
181
|
|
|
185
|
-
it("
|
|
182
|
+
it("does not emit on mount when no filter is selected", async () => {
|
|
186
183
|
const wrapper = mount(PlDatasetSelector, {
|
|
187
184
|
props: {
|
|
188
|
-
modelValue:
|
|
185
|
+
modelValue: selection(datasetA),
|
|
189
186
|
options: optionsWithFilters,
|
|
190
|
-
"onUpdate:modelValue": (e
|
|
187
|
+
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
188
|
+
wrapper.setProps({ modelValue: e }),
|
|
191
189
|
},
|
|
192
190
|
attachTo: document.body,
|
|
193
191
|
});
|
|
194
192
|
await flushPromises();
|
|
195
193
|
|
|
196
|
-
// No emission on mount — the component does not auto-select a filter.
|
|
197
194
|
expect(wrapper.emitted("update:modelValue")).toBeUndefined();
|
|
198
195
|
|
|
199
|
-
// Filter dropdown is visible.
|
|
200
196
|
const inputs = wrapper.findAll("input");
|
|
201
197
|
expect(inputs.length).toBe(2);
|
|
202
|
-
|
|
203
|
-
// Open filter dropdown and verify "No filter" is the first option.
|
|
204
198
|
await inputs[1].trigger("focus");
|
|
205
199
|
const items = document.body.querySelectorAll(".dropdown-list-item");
|
|
206
200
|
expect(items.length).toBe(3); // No filter, Top 1000, High quality
|
|
@@ -208,12 +202,13 @@ describe("PlDatasetSelector", () => {
|
|
|
208
202
|
wrapper.unmount();
|
|
209
203
|
});
|
|
210
204
|
|
|
211
|
-
it("emits
|
|
205
|
+
it("emits DatasetSelection without enrichments when the option carries none", async () => {
|
|
212
206
|
const wrapper = mount(PlDatasetSelector, {
|
|
213
207
|
props: {
|
|
214
208
|
modelValue: undefined,
|
|
215
209
|
options: optionsNoFilters,
|
|
216
|
-
"onUpdate:modelValue": (e
|
|
210
|
+
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
211
|
+
wrapper.setProps({ modelValue: e }),
|
|
217
212
|
},
|
|
218
213
|
attachTo: document.body,
|
|
219
214
|
});
|
|
@@ -225,25 +220,28 @@ describe("PlDatasetSelector", () => {
|
|
|
225
220
|
|
|
226
221
|
const emitted = wrapper.emitted("update:modelValue");
|
|
227
222
|
expect(emitted).toBeDefined();
|
|
228
|
-
const last = emitted![emitted!.length - 1][0] as
|
|
229
|
-
expect(last).toEqual({
|
|
230
|
-
|
|
223
|
+
const last = emitted![emitted!.length - 1][0] as DatasetSelection;
|
|
224
|
+
expect(last).toEqual({
|
|
225
|
+
__isDatasetSelection: "v1",
|
|
226
|
+
primary: { __isPrimaryRef: "v1", column: datasetB },
|
|
227
|
+
});
|
|
228
|
+
expect("enrichments" in last).toBe(false);
|
|
231
229
|
wrapper.unmount();
|
|
232
230
|
});
|
|
233
231
|
|
|
234
232
|
it("emits undefined when cleared via the dataset dropdown", async () => {
|
|
235
233
|
const wrapper = mount(PlDatasetSelector, {
|
|
236
234
|
props: {
|
|
237
|
-
modelValue:
|
|
235
|
+
modelValue: selection(datasetA, filterA1, enrichmentsA),
|
|
238
236
|
options: optionsWithFilters,
|
|
239
237
|
clearable: true,
|
|
240
|
-
"onUpdate:modelValue": (e
|
|
238
|
+
"onUpdate:modelValue": (e: DatasetSelection | undefined) =>
|
|
239
|
+
wrapper.setProps({ modelValue: e }),
|
|
241
240
|
},
|
|
242
241
|
attachTo: document.body,
|
|
243
242
|
});
|
|
244
243
|
await flushPromises();
|
|
245
244
|
|
|
246
|
-
// PlDropdown's clear button carries the ".clear" class.
|
|
247
245
|
const clearBtn = wrapper.find(".clear");
|
|
248
246
|
expect(clearBtn.exists()).toBe(true);
|
|
249
247
|
await clearBtn.trigger("click");
|