@platforma-sdk/ui-vue 1.64.0 → 1.65.3
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 +25 -25
- 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 +19 -0
- package/dist/components/PlAdvancedFilter/FilterEditor.js.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.style.js.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.vue.d.ts +3 -8
- package/dist/components/PlAdvancedFilter/FilterEditor.vue.d.ts.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js +164 -151
- package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js.map +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.js.map +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.style.js +8 -7
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.style.js.map +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.css +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts +24 -8
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts.map +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js +176 -110
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js.map +1 -1
- package/dist/components/PlAdvancedFilter/types.d.ts +2 -0
- package/dist/components/PlAdvancedFilter/types.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.style.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +116 -109
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts +6 -5
- package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-source-v2.js +26 -26
- package/dist/components/PlAgDataTable/sources/table-source-v2.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-state-v2.d.ts +6 -3
- package/dist/components/PlAgDataTable/sources/table-state-v2.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-state-v2.js +182 -97
- package/dist/components/PlAgDataTable/sources/table-state-v2.js.map +1 -1
- package/dist/components/PlAnnotations/components/FilterSidebar.js.map +1 -1
- package/dist/components/PlAnnotations/components/FilterSidebar.style.js.map +1 -1
- package/dist/components/PlAnnotations/components/FilterSidebar.vue.d.ts.map +1 -1
- package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +7 -4
- package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.style.js +5 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.style.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue.css +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue.d.ts +7 -9
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue.d.ts.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js +73 -42
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/util/helpers/dist/functions.js.map +1 -1
- package/dist/lib/util/helpers/dist/objects.js +4 -1
- package/dist/lib/util/helpers/dist/objects.js.map +1 -1
- package/package.json +7 -6
- package/src/components/PlAdvancedFilter/FilterEditor.vue +99 -55
- package/src/components/PlAdvancedFilter/PlAdvancedFilter.vue +163 -95
- package/src/components/PlAdvancedFilter/types.ts +6 -1
- package/src/components/PlAgDataTable/PlAgDataTableV2.vue +24 -6
- package/src/components/PlAgDataTable/sources/table-source-v2.ts +11 -9
- package/src/components/PlAgDataTable/sources/table-state-v2.ts +249 -64
- package/src/components/PlAnnotations/components/FilterSidebar.vue +3 -2
- package/src/components/PlTableFilters/PlTableFiltersV2.vue +75 -21
- package/src/index.ts +4 -0
|
@@ -27,10 +27,10 @@ import { DEFAULT_FILTER_TYPE, DEFAULT_FILTERS } from "./constants";
|
|
|
27
27
|
import OperandButton from "./OperandButton.vue";
|
|
28
28
|
import type { EditableFilter, Operand, PlAdvancedFilterColumnId, SourceOptionInfo } from "./types";
|
|
29
29
|
import { getFilterInfo, getNormalizedSpec, isNumericFilter, isPositionFilter } from "./utils";
|
|
30
|
-
|
|
31
|
-
const filter = defineModel<EditableFilter>("filter", { required: true });
|
|
30
|
+
import { Entries } from "@milaboratories/helpers";
|
|
32
31
|
|
|
33
32
|
const props = defineProps<{
|
|
33
|
+
filter: EditableFilter;
|
|
34
34
|
isLast: boolean;
|
|
35
35
|
operand: Operand;
|
|
36
36
|
enableDnd: boolean;
|
|
@@ -43,9 +43,20 @@ const props = defineProps<{
|
|
|
43
43
|
searchStr: string;
|
|
44
44
|
}) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;
|
|
45
45
|
onDelete: (columnId: PlAdvancedFilterColumnId) => void;
|
|
46
|
+
onUpdateFilter: (filter: EditableFilter) => void;
|
|
46
47
|
onChangeOperand: (op: Operand) => void;
|
|
47
48
|
}>();
|
|
48
49
|
|
|
50
|
+
type AllKeys<U> = U extends unknown ? keyof U : never;
|
|
51
|
+
type ValueOf<U, K extends string> = U extends unknown ? (K extends keyof U ? U[K] : never) : never;
|
|
52
|
+
|
|
53
|
+
function updateFilterProp<K extends AllKeys<EditableFilter> & string>(
|
|
54
|
+
key: K,
|
|
55
|
+
v: ValueOf<EditableFilter, K>,
|
|
56
|
+
) {
|
|
57
|
+
props.onUpdateFilter({ ...props.filter, [key]: v } as EditableFilter);
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
async function getSuggestOptionsFn(
|
|
50
61
|
id: PlAdvancedFilterColumnId,
|
|
51
62
|
type: "value" | "label",
|
|
@@ -76,17 +87,21 @@ async function getMultiSuggestOptionsFn(
|
|
|
76
87
|
throw new Error("Invalid arguments combination");
|
|
77
88
|
}
|
|
78
89
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
function changeFilterType(newType: EditableFilter["type"]) {
|
|
91
|
+
const defaultFilter = DEFAULT_FILTERS[newType];
|
|
92
|
+
|
|
93
|
+
props.onUpdateFilter(
|
|
94
|
+
(Object.entries(defaultFilter) as Entries<EditableFilter>).reduce(
|
|
95
|
+
(res, [key, val]) => {
|
|
96
|
+
res[key] = props.filter[key] ?? val;
|
|
97
|
+
return res;
|
|
98
|
+
},
|
|
99
|
+
{ ...props.filter, type: newType } as Record<
|
|
100
|
+
keyof EditableFilter,
|
|
101
|
+
EditableFilter[keyof EditableFilter]
|
|
102
|
+
>,
|
|
103
|
+
) as EditableFilter,
|
|
104
|
+
);
|
|
90
105
|
}
|
|
91
106
|
|
|
92
107
|
function changeSourceId(newSourceId?: PlAdvancedFilterColumnId) {
|
|
@@ -97,30 +112,28 @@ function changeSourceId(newSourceId?: PlAdvancedFilterColumnId) {
|
|
|
97
112
|
if (!newSourceInfo) {
|
|
98
113
|
return;
|
|
99
114
|
}
|
|
100
|
-
const filterInfo = getFilterInfo(filter.
|
|
115
|
+
const filterInfo = getFilterInfo(props.filter.type);
|
|
101
116
|
const newSourceSpec = getNormalizedSpec(newSourceInfo?.spec);
|
|
102
117
|
if (filterInfo.supportedFor(newSourceSpec)) {
|
|
103
|
-
|
|
104
|
-
filter.value.column = newSourceId;
|
|
118
|
+
props.onUpdateFilter({ ...props.filter, column: newSourceId });
|
|
105
119
|
} else {
|
|
106
|
-
|
|
107
|
-
filter.value = {
|
|
120
|
+
props.onUpdateFilter({
|
|
108
121
|
...DEFAULT_FILTERS[DEFAULT_FILTER_TYPE],
|
|
109
122
|
column: newSourceId,
|
|
110
|
-
};
|
|
123
|
+
});
|
|
111
124
|
}
|
|
112
125
|
}
|
|
113
126
|
|
|
114
127
|
const inconsistentSourceSelected = computed(() => {
|
|
115
128
|
const selectedOption = props.columnOptions.find(
|
|
116
|
-
(op) => op.id === getSourceId(filter.
|
|
129
|
+
(op) => op.id === getSourceId(props.filter.column),
|
|
117
130
|
);
|
|
118
131
|
return selectedOption === undefined;
|
|
119
132
|
});
|
|
120
133
|
const sourceOptions = computed(() => {
|
|
121
134
|
const options = props.columnOptions.map((v) => ({ value: v.id, label: v.label ?? v }));
|
|
122
135
|
if (inconsistentSourceSelected.value) {
|
|
123
|
-
options.unshift({ value: filter.
|
|
136
|
+
options.unshift({ value: props.filter.column, label: "Inconsistent value" });
|
|
124
137
|
}
|
|
125
138
|
return options;
|
|
126
139
|
});
|
|
@@ -186,10 +199,10 @@ function stringifyColumn(value: ColumnAsSourceAndFixedAxes): PlAdvancedFilterCol
|
|
|
186
199
|
|
|
187
200
|
const columnAsSourceAndFixedAxes = computed({
|
|
188
201
|
get: () => {
|
|
189
|
-
return getColumnAsSourceAndFixedAxes(filter.
|
|
202
|
+
return getColumnAsSourceAndFixedAxes(props.filter.column);
|
|
190
203
|
},
|
|
191
204
|
set: (value) => {
|
|
192
|
-
|
|
205
|
+
props.onUpdateFilter({ ...props.filter, column: stringifyColumn(value) });
|
|
193
206
|
},
|
|
194
207
|
});
|
|
195
208
|
function updateAxisFilterValue(idx: number, value: AxisFilterValue | undefined) {
|
|
@@ -214,14 +227,14 @@ const filterTypesOptions = computed(() =>
|
|
|
214
227
|
props.supportedFilters
|
|
215
228
|
.filter(
|
|
216
229
|
(v) =>
|
|
217
|
-
filter.
|
|
230
|
+
props.filter.type === v ||
|
|
218
231
|
(currentSpec.value ? getFilterInfo(v).supportedFor(currentSpec.value) : true),
|
|
219
232
|
)
|
|
220
233
|
.map((v) => ({ value: v, label: getFilterInfo(v).label })),
|
|
221
234
|
);
|
|
222
235
|
|
|
223
236
|
const wildcardOptions = computed(() => {
|
|
224
|
-
if (filter.
|
|
237
|
+
if (props.filter.type !== "patternFuzzyContainSubsequence") {
|
|
225
238
|
return [];
|
|
226
239
|
}
|
|
227
240
|
if (currentOption.value?.alphabet === "nucleotide") {
|
|
@@ -230,15 +243,15 @@ const wildcardOptions = computed(() => {
|
|
|
230
243
|
if (currentOption.value?.alphabet === "aminoacid") {
|
|
231
244
|
return [{ label: "X", value: "X" }];
|
|
232
245
|
}
|
|
233
|
-
return [...new Set(filter.value.
|
|
246
|
+
return [...new Set(props.filter.value.split(""))].sort().map((v) => ({ value: v, label: v }));
|
|
234
247
|
});
|
|
235
248
|
|
|
236
249
|
const stringMatchesError = computed(() => {
|
|
237
|
-
if (filter.
|
|
250
|
+
if (props.filter.type !== "patternMatchesRegularExpression") {
|
|
238
251
|
return false;
|
|
239
252
|
}
|
|
240
253
|
try {
|
|
241
|
-
new RegExp(filter.value
|
|
254
|
+
new RegExp(props.filter.value);
|
|
242
255
|
return false;
|
|
243
256
|
} catch {
|
|
244
257
|
return true;
|
|
@@ -268,24 +281,24 @@ const stringMatchesError = computed(() => {
|
|
|
268
281
|
{{
|
|
269
282
|
inconsistentSourceSelected
|
|
270
283
|
? "Inconsistent value"
|
|
271
|
-
: (currentOption?.label ?? filter.column)
|
|
284
|
+
: (currentOption?.label ?? props.filter.column)
|
|
272
285
|
}}
|
|
273
286
|
</div>
|
|
274
287
|
</div>
|
|
275
|
-
<div :class="$style.closeIcon" @click="onDelete(filter.column)">
|
|
288
|
+
<div :class="$style.closeIcon" @click="onDelete(props.filter.column)">
|
|
276
289
|
<PlIcon16 name="close" />
|
|
277
290
|
</div>
|
|
278
291
|
</div>
|
|
279
292
|
<div v-else :class="$style.top">
|
|
280
293
|
<PlDropdown
|
|
281
|
-
|
|
294
|
+
:model-value="columnAsSourceAndFixedAxes.source"
|
|
282
295
|
:errorStatus="currentError"
|
|
283
296
|
:options="sourceOptions"
|
|
284
297
|
:style="{ width: '100%' }"
|
|
285
298
|
group-position="top-left"
|
|
286
299
|
@update:model-value="changeSourceId"
|
|
287
300
|
/>
|
|
288
|
-
<div :class="$style.closeButton" @click="onDelete(filter.column)">
|
|
301
|
+
<div :class="$style.closeButton" @click="onDelete(props.filter.column)">
|
|
289
302
|
<PlIcon16 name="close" />
|
|
290
303
|
</div>
|
|
291
304
|
</div>
|
|
@@ -293,7 +306,7 @@ const stringMatchesError = computed(() => {
|
|
|
293
306
|
<div v-if="currentOption?.axesToBeFixed?.length" :class="$style.fixedAxesBlock">
|
|
294
307
|
<template v-for="value in currentOption?.axesToBeFixed" :key="value.idx">
|
|
295
308
|
<PlAutocomplete
|
|
296
|
-
|
|
309
|
+
:model-value="columnAsSourceAndFixedAxes.axisFiltersByIndex[value.idx]"
|
|
297
310
|
:label="value.label"
|
|
298
311
|
:options-search="
|
|
299
312
|
(str, type) =>
|
|
@@ -308,81 +321,112 @@ const stringMatchesError = computed(() => {
|
|
|
308
321
|
|
|
309
322
|
<!-- middle - filter type selector - for all filter types -->
|
|
310
323
|
<div
|
|
311
|
-
:class="
|
|
324
|
+
:class="
|
|
325
|
+
props.filter.type === 'isNA' || props.filter.type === 'isNotNA'
|
|
326
|
+
? $style.bottom
|
|
327
|
+
: $style.middle
|
|
328
|
+
"
|
|
312
329
|
>
|
|
313
330
|
<PlDropdown
|
|
314
|
-
|
|
331
|
+
:model-value="props.filter.type"
|
|
315
332
|
:options="filterTypesOptions"
|
|
316
|
-
:group-position="
|
|
317
|
-
|
|
333
|
+
:group-position="
|
|
334
|
+
props.filter.type === 'isNA' || props.filter.type === 'isNotNA' ? 'bottom' : 'middle'
|
|
335
|
+
"
|
|
336
|
+
@update:model-value="(v) => changeFilterType(v!)"
|
|
318
337
|
/>
|
|
319
338
|
</div>
|
|
320
339
|
|
|
321
340
|
<!-- middle - for fuzzy contains filter -->
|
|
322
|
-
<template v-if="filter.type === 'patternFuzzyContainSubsequence'">
|
|
341
|
+
<template v-if="props.filter.type === 'patternFuzzyContainSubsequence'">
|
|
323
342
|
<div :class="$style.middle">
|
|
324
|
-
<PlTextField
|
|
343
|
+
<PlTextField
|
|
344
|
+
:model-value="props.filter.value"
|
|
345
|
+
placeholder="Substring"
|
|
346
|
+
group-position="middle"
|
|
347
|
+
@update:model-value="(v) => updateFilterProp('value', v)"
|
|
348
|
+
/>
|
|
325
349
|
</div>
|
|
326
350
|
<div :class="$style.innerSection">
|
|
327
351
|
<Slider
|
|
328
|
-
|
|
352
|
+
:model-value="props.filter.maxEdits"
|
|
329
353
|
:max="5"
|
|
330
354
|
breakpoints
|
|
331
355
|
label="Maximum number of substitutions and indels"
|
|
356
|
+
@update:model-value="(v) => updateFilterProp('maxEdits', v)"
|
|
357
|
+
/>
|
|
358
|
+
<PlToggleSwitch
|
|
359
|
+
:model-value="props.filter.substitutionsOnly"
|
|
360
|
+
label="Substitutions only"
|
|
361
|
+
@update:model-value="(v) => updateFilterProp('substitutionsOnly', v)"
|
|
332
362
|
/>
|
|
333
|
-
<PlToggleSwitch v-model="filter.substitutionsOnly" label="Substitutions only" />
|
|
334
363
|
</div>
|
|
335
364
|
</template>
|
|
336
365
|
|
|
337
366
|
<!-- bottom element - individual settings for every filter type -->
|
|
338
367
|
<div :class="$style.bottom">
|
|
339
368
|
<PlAutocomplete
|
|
340
|
-
v-if="filter.type === 'patternEquals' || filter.type === 'patternNotEquals'"
|
|
341
|
-
|
|
369
|
+
v-if="props.filter.type === 'patternEquals' || props.filter.type === 'patternNotEquals'"
|
|
370
|
+
:model-value="props.filter.value"
|
|
342
371
|
:options-search="
|
|
343
372
|
(str, type) => getSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str)
|
|
344
373
|
"
|
|
345
374
|
:clearable="true"
|
|
346
375
|
group-position="bottom"
|
|
376
|
+
@update:model-value="(v) => updateFilterProp('value', v)"
|
|
347
377
|
/>
|
|
348
378
|
<PlAutocompleteMulti
|
|
349
|
-
v-if="filter.type === 'inSet' || filter.type === 'notInSet'"
|
|
350
|
-
|
|
379
|
+
v-if="props.filter.type === 'inSet' || props.filter.type === 'notInSet'"
|
|
380
|
+
:model-value="props.filter.value"
|
|
351
381
|
:options-search="
|
|
352
382
|
(str, type) => getMultiSuggestOptionsFn(columnAsSourceAndFixedAxes.source, type, str)
|
|
353
383
|
"
|
|
354
384
|
:disabled="inconsistentSourceSelected"
|
|
355
385
|
group-position="bottom"
|
|
386
|
+
@update:model-value="(v) => updateFilterProp('value', v)"
|
|
387
|
+
/>
|
|
388
|
+
<PlNumberField
|
|
389
|
+
v-if="isNumericFilter(props.filter)"
|
|
390
|
+
:model-value="props.filter.x"
|
|
391
|
+
group-position="bottom"
|
|
392
|
+
@update:model-value="(v) => updateFilterProp('x', v)"
|
|
393
|
+
/>
|
|
394
|
+
<PlNumberField
|
|
395
|
+
v-if="isPositionFilter(props.filter)"
|
|
396
|
+
:model-value="props.filter.n"
|
|
397
|
+
group-position="bottom"
|
|
398
|
+
@update:model-value="(v) => updateFilterProp('n', v)"
|
|
356
399
|
/>
|
|
357
|
-
<PlNumberField v-if="isNumericFilter(filter)" v-model="filter.x" group-position="bottom" />
|
|
358
|
-
<PlNumberField v-if="isPositionFilter(filter)" v-model="filter.n" group-position="bottom" />
|
|
359
400
|
<PlTextField
|
|
360
401
|
v-if="
|
|
361
|
-
filter.type === 'patternContainSubsequence' ||
|
|
362
|
-
filter.type === 'patternNotContainSubsequence'
|
|
402
|
+
props.filter.type === 'patternContainSubsequence' ||
|
|
403
|
+
props.filter.type === 'patternNotContainSubsequence'
|
|
363
404
|
"
|
|
364
|
-
|
|
405
|
+
:model-value="props.filter.value"
|
|
365
406
|
placeholder="Substring"
|
|
366
407
|
group-position="bottom"
|
|
408
|
+
@update:model-value="(v) => updateFilterProp('value', v)"
|
|
367
409
|
/>
|
|
368
410
|
<PlTextField
|
|
369
|
-
v-if="filter.type === 'patternMatchesRegularExpression'"
|
|
370
|
-
|
|
411
|
+
v-if="props.filter.type === 'patternMatchesRegularExpression'"
|
|
412
|
+
:model-value="props.filter.value"
|
|
371
413
|
:error="stringMatchesError ? 'Regular expression is not valid' : undefined"
|
|
372
414
|
placeholder="Regular expression"
|
|
373
415
|
group-position="bottom"
|
|
416
|
+
@update:model-value="(v) => updateFilterProp('value', v)"
|
|
374
417
|
/>
|
|
375
418
|
<PlDropdown
|
|
376
|
-
v-if="filter.type === 'patternFuzzyContainSubsequence'"
|
|
377
|
-
|
|
419
|
+
v-if="props.filter.type === 'patternFuzzyContainSubsequence'"
|
|
420
|
+
:model-value="props.filter.wildcard"
|
|
378
421
|
clearable
|
|
379
422
|
placeholder="Wildcard value"
|
|
380
423
|
:options="wildcardOptions"
|
|
381
424
|
group-position="bottom"
|
|
425
|
+
@update:model-value="(v) => updateFilterProp('wildcard', v)"
|
|
382
426
|
/>
|
|
383
427
|
</div>
|
|
384
428
|
</div>
|
|
385
|
-
<OperandButton :active="operand" :disabled="isLast"
|
|
429
|
+
<OperandButton :active="operand" :disabled="isLast" @select="onChangeOperand" />
|
|
386
430
|
</template>
|
|
387
431
|
|
|
388
432
|
<style module>
|