@platforma-sdk/ui-vue 1.68.8 → 1.70.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 +13 -13
- 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 +22 -0
- package/dist/components/PlAgDataTable/sources/table-source-v2.js +3 -3
- package/dist/components/PlAgDataTable/sources/table-source-v2.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.style.js +5 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.style.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.css +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.d.ts.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js +40 -23
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.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/table-source-v2.ts +10 -6
- package/src/components/PlAgGridColumnManager/PlAgGridColumnManager.vue +51 -1
- package/src/components/PlDatasetSelector/PlDatasetSelector.vue +24 -23
- package/src/components/PlDatasetSelector/__tests__/PlDatasetSelector.jsdomtest.ts +70 -72
|
@@ -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");
|