@platforma-sdk/ui-vue 1.42.15 → 1.42.19
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 +33 -28
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +14 -0
- package/dist/components/PlAgDataTable/PlAgDataTableSheets.vue2.js +5 -5
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +41 -41
- package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-source-v2.js +124 -125
- package/dist/components/PlAgDataTable/sources/table-source-v2.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-state-v2.js +3 -3
- package/dist/components/PlAgDataTable/sources/value-rendering.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/value-rendering.js +24 -25
- package/dist/components/PlAgDataTable/sources/value-rendering.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.d.ts.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.js +7 -86
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js +103 -2
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue3.js +9 -0
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue3.js.map +1 -0
- package/dist/components/PlAgGridColumnManager/useFilteredItems.d.ts +15 -0
- package/dist/components/PlAgGridColumnManager/useFilteredItems.d.ts.map +1 -0
- package/dist/components/PlAgGridColumnManager/useFilteredItems.js +35 -0
- package/dist/components/PlAgGridColumnManager/useFilteredItems.js.map +1 -0
- package/dist/components/PlAnnotations/components/DynamicForm.vue2.js +12 -12
- package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +2 -2
- package/dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue.d.ts.map +1 -1
- package/dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue.js +21 -20
- package/dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/data.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/data.js +170 -185
- package/dist/components/PlMultiSequenceAlignment/data.js.map +1 -1
- package/dist/components/PlTableFilters/filters-state.js +8 -8
- package/dist/components/PlTableFilters/filters_logic.d.ts.map +1 -1
- package/dist/components/PlTableFilters/filters_logic.js +67 -77
- package/dist/components/PlTableFilters/filters_logic.js.map +1 -1
- package/dist/defineApp.js +20 -20
- package/dist/internal/UpdateSerializer.js +3 -3
- package/dist/lib/model/common/dist/index.js +523 -414
- package/dist/lib/model/common/dist/index.js.map +1 -1
- package/dist/lib/ui/uikit/dist/components/DataTable/TableComponent.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAccordion/{ExpandTransition.vue.js → ExpandTransition.vue2.js} +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAccordion/ExpandTransition.vue2.js.map +1 -0
- package/dist/lib/ui/uikit/dist/components/PlAccordion/PlAccordionSection.vue2.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAutocomplete/PlAutocomplete.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlDropdown/PlDropdown.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlDropdownMulti/PlDropdownMulti.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlFileDialog/Local.vue.js +6 -6
- package/dist/lib/ui/uikit/dist/components/PlFileInput/PlFileInput.vue.js +28 -28
- package/dist/lib/ui/uikit/dist/components/PlFileInput/PlFileInput.vue.js.map +1 -1
- package/dist/lib/ui/uikit/dist/components/PlLogView/PlLogView.vue.js +89 -63
- package/dist/lib/ui/uikit/dist/components/PlLogView/PlLogView.vue.js.map +1 -1
- package/dist/lib/ui/uikit/dist/components/PlSlideModal/PlPureSlideModal.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlTextArea/PlTextArea.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlTextField/PlTextField.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/generated/components/svg/images/{SvgRequired.vue.js → SvgRequired.vue2.js} +1 -1
- package/dist/lib/ui/uikit/dist/generated/components/svg/images/SvgRequired.vue2.js.map +1 -0
- package/dist/lib/ui/uikit/dist/helpers/dom.js.map +1 -1
- package/dist/lib/ui/uikit/dist/helpers/downloadContent.js +32 -0
- package/dist/lib/ui/uikit/dist/helpers/downloadContent.js.map +1 -0
- package/dist/lib/ui/uikit/dist/lib/model/common/dist/index.js +201 -159
- package/dist/lib/ui/uikit/dist/lib/model/common/dist/index.js.map +1 -1
- package/dist/lib/ui/uikit/dist/sdk/model/dist/index.js +521 -517
- package/dist/lib/ui/uikit/dist/sdk/model/dist/index.js.map +1 -1
- package/dist/lib.js +52 -50
- package/dist/lib.js.map +1 -1
- package/dist/sdk/model/dist/index.js +410 -406
- package/dist/sdk/model/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/components/PlAgDataTable/sources/table-source-v2.ts +20 -16
- package/src/components/PlAgDataTable/sources/value-rendering.ts +15 -7
- package/src/components/PlAgGridColumnManager/PlAgGridColumnManager.vue +28 -4
- package/src/components/PlAgGridColumnManager/useFilteredItems.ts +68 -0
- package/src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue +1 -0
- package/src/components/PlMultiSequenceAlignment/data.ts +12 -12
- package/src/components/PlTableFilters/filters_logic.ts +18 -15
- package/dist/lib/ui/uikit/dist/components/PlAccordion/ExpandTransition.vue.js.map +0 -1
- package/dist/lib/ui/uikit/dist/generated/components/svg/images/SvgRequired.vue.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.42.
|
|
3
|
+
"version": "1.42.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/lib.js",
|
|
6
6
|
"styles": "dist/lib.js",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"d3-format": "^3.1.0",
|
|
27
27
|
"zod": "~3.23.8",
|
|
28
28
|
"@milaboratories/biowasm-tools": "^1.1.0",
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
29
|
+
"@platforma-sdk/model": "~1.42.16",
|
|
30
|
+
"@milaboratories/uikit": "2.4.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"happy-dom": "^15.11.7",
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
"yarpm": "^1.2.0",
|
|
44
44
|
"fast-json-patch": "^3.1.1",
|
|
45
45
|
"@faker-js/faker": "^9.2.0",
|
|
46
|
-
"@milaboratories/ts-configs": "1.0.5",
|
|
47
46
|
"@milaboratories/build-configs": "1.0.5",
|
|
48
|
-
"@milaboratories/
|
|
49
|
-
"@milaboratories/helpers": "^1.6.19"
|
|
47
|
+
"@milaboratories/ts-configs": "1.0.5",
|
|
48
|
+
"@milaboratories/helpers": "^1.6.19",
|
|
49
|
+
"@milaboratories/eslint-config": "^1.0.4"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"test": "vitest run --passWithNoTests",
|
|
@@ -23,6 +23,10 @@ import {
|
|
|
23
23
|
isColumnHidden,
|
|
24
24
|
matchAxisId,
|
|
25
25
|
isPTableValueAxis,
|
|
26
|
+
readAnnotation,
|
|
27
|
+
Annotation,
|
|
28
|
+
ValueType,
|
|
29
|
+
readAnnotationJson,
|
|
26
30
|
} from '@platforma-sdk/model';
|
|
27
31
|
import type {
|
|
28
32
|
CellStyle,
|
|
@@ -180,12 +184,12 @@ export async function calculateGridOptions({
|
|
|
180
184
|
indices.sort((a, b) => {
|
|
181
185
|
if (specs[a].type !== specs[b].type) return specs[a].type === 'axis' ? -1 : 1;
|
|
182
186
|
|
|
183
|
-
const aPriority = specs[a].spec.
|
|
184
|
-
const bPriority = specs[b].spec.
|
|
187
|
+
const aPriority = readAnnotationJson(specs[a].spec, Annotation.Table.OrderPriority);
|
|
188
|
+
const bPriority = readAnnotationJson(specs[b].spec, Annotation.Table.OrderPriority);
|
|
185
189
|
|
|
186
190
|
if (aPriority === undefined) return bPriority === undefined ? 0 : 1;
|
|
187
191
|
if (bPriority === undefined) return -1;
|
|
188
|
-
return
|
|
192
|
+
return bPriority - aPriority;
|
|
189
193
|
});
|
|
190
194
|
|
|
191
195
|
// fields are indices of columns that would go to columnDefs
|
|
@@ -331,7 +335,7 @@ export function makeColDef(
|
|
|
331
335
|
mainMenuItems: defaultMainMenuItems,
|
|
332
336
|
context: spec,
|
|
333
337
|
field: `${iCol}`,
|
|
334
|
-
headerName: labeledSpec.spec.
|
|
338
|
+
headerName: readAnnotation(labeledSpec.spec, Annotation.Label)?.trim() ?? `Unlabeled ${spec.type} ${iCol}`,
|
|
335
339
|
lockPosition: spec.type === 'axis',
|
|
336
340
|
hide: hiddenColIds?.includes(colId) ?? isColumnOptional(spec.spec),
|
|
337
341
|
valueFormatter: columnRenderingSpec.valueFormatter,
|
|
@@ -358,13 +362,13 @@ export function makeColDef(
|
|
|
358
362
|
headerComponentParams: {
|
|
359
363
|
type: ((): PlAgHeaderComponentType => {
|
|
360
364
|
switch (valueType) {
|
|
361
|
-
case
|
|
362
|
-
case
|
|
363
|
-
case
|
|
364
|
-
case
|
|
365
|
+
case ValueType.Int:
|
|
366
|
+
case ValueType.Long:
|
|
367
|
+
case ValueType.Float:
|
|
368
|
+
case ValueType.Double:
|
|
365
369
|
return 'Number';
|
|
366
|
-
case
|
|
367
|
-
case
|
|
370
|
+
case ValueType.String:
|
|
371
|
+
case ValueType.Bytes:
|
|
368
372
|
return 'Text';
|
|
369
373
|
default:
|
|
370
374
|
throw Error(`unsupported data type: ${valueType}`);
|
|
@@ -373,13 +377,13 @@ export function makeColDef(
|
|
|
373
377
|
} satisfies PlAgHeaderComponentParams,
|
|
374
378
|
cellDataType: (() => {
|
|
375
379
|
switch (valueType) {
|
|
376
|
-
case
|
|
377
|
-
case
|
|
378
|
-
case
|
|
379
|
-
case
|
|
380
|
+
case ValueType.Int:
|
|
381
|
+
case ValueType.Long:
|
|
382
|
+
case ValueType.Float:
|
|
383
|
+
case ValueType.Double:
|
|
380
384
|
return 'number';
|
|
381
|
-
case
|
|
382
|
-
case
|
|
385
|
+
case ValueType.String:
|
|
386
|
+
case ValueType.Bytes:
|
|
383
387
|
return 'text';
|
|
384
388
|
default:
|
|
385
389
|
throw Error(`unsupported data type: ${valueType}`);
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Annotation,
|
|
3
|
+
isPTableAbsent,
|
|
4
|
+
PTableNA,
|
|
5
|
+
readAnnotation,
|
|
6
|
+
ValueType,
|
|
7
|
+
type PTableColumnSpec,
|
|
8
|
+
type PTableValue,
|
|
9
|
+
} from '@platforma-sdk/model';
|
|
2
10
|
import type { ValueFormatterFunc } from 'ag-grid-enterprise';
|
|
3
11
|
import type { PTableHidden } from './common';
|
|
4
12
|
import { isPTableHidden } from './common';
|
|
@@ -26,11 +34,11 @@ export function getColumnRenderingSpec(spec: PTableColumnSpec): ColumnRenderingS
|
|
|
26
34
|
const valueType = spec.type === 'axis' ? spec.spec.type : spec.spec.valueType;
|
|
27
35
|
let renderSpec: ColumnRenderingSpec;
|
|
28
36
|
switch (valueType) {
|
|
29
|
-
case
|
|
30
|
-
case
|
|
31
|
-
case
|
|
32
|
-
case
|
|
33
|
-
const format = spec.spec.
|
|
37
|
+
case ValueType.Int:
|
|
38
|
+
case ValueType.Long:
|
|
39
|
+
case ValueType.Float:
|
|
40
|
+
case ValueType.Double: {
|
|
41
|
+
const format = readAnnotation(spec.spec, Annotation.Format);
|
|
34
42
|
const formatFn = format ? d3.format(format) : undefined;
|
|
35
43
|
renderSpec = {
|
|
36
44
|
valueFormatter: (params) => {
|
|
@@ -51,7 +59,7 @@ export function getColumnRenderingSpec(spec: PTableColumnSpec): ColumnRenderingS
|
|
|
51
59
|
};
|
|
52
60
|
break;
|
|
53
61
|
}
|
|
54
|
-
const fontFamily = spec.spec.
|
|
62
|
+
const fontFamily = readAnnotation(spec.spec, Annotation.Table.FontFamily);
|
|
55
63
|
if (fontFamily) renderSpec.fontFamily = fontFamily;
|
|
56
64
|
return renderSpec;
|
|
57
65
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { PlBtnGhost, PlElementList, PlSearchField, PlSlideModal, usePlBlockPageTitleTeleportTarget } from '@milaboratories/uikit';
|
|
2
3
|
import { type Column, type DisplayedColumnsChangedEvent, type GridApi } from 'ag-grid-enterprise';
|
|
3
|
-
import {
|
|
4
|
-
import { ref, toRefs, watch, computed } from 'vue';
|
|
4
|
+
import { computed, ref, toRefs, watch } from 'vue';
|
|
5
5
|
import { PlAgDataTableRowNumberColId } from '../PlAgDataTable/sources/row-number';
|
|
6
|
+
import { useFilteredItems } from './useFilteredItems';
|
|
6
7
|
|
|
7
8
|
const props = defineProps<{
|
|
8
9
|
/**
|
|
@@ -46,8 +47,16 @@ const items = computed(() => {
|
|
|
46
47
|
}));
|
|
47
48
|
});
|
|
48
49
|
|
|
50
|
+
const query = ref('');
|
|
51
|
+
|
|
49
52
|
const slideModal = ref(false);
|
|
50
53
|
const teleportTarget = usePlBlockPageTitleTeleportTarget('PlAgGridColumnManager');
|
|
54
|
+
|
|
55
|
+
const { filteredItems, segments } = useFilteredItems(() => ({
|
|
56
|
+
items: items.value,
|
|
57
|
+
query: query.value,
|
|
58
|
+
getStrings: (item) => [item.label],
|
|
59
|
+
}));
|
|
51
60
|
</script>
|
|
52
61
|
|
|
53
62
|
<template>
|
|
@@ -60,8 +69,9 @@ const teleportTarget = usePlBlockPageTitleTeleportTarget('PlAgGridColumnManager'
|
|
|
60
69
|
|
|
61
70
|
<PlSlideModal v-model="slideModal" :width="width" close-on-outside-click>
|
|
62
71
|
<template #title>Manage Columns</template>
|
|
72
|
+
<PlSearchField v-model="query" clearable />
|
|
63
73
|
<PlElementList
|
|
64
|
-
:items="
|
|
74
|
+
:items="filteredItems"
|
|
65
75
|
:get-item-key="(item) => item.id"
|
|
66
76
|
:is-draggable="(item) => !item.column.getColDef().lockPosition"
|
|
67
77
|
:on-sort="(fromIndex, toIndex) => {
|
|
@@ -80,12 +90,26 @@ const teleportTarget = usePlBlockPageTitleTeleportTarget('PlAgGridColumnManager'
|
|
|
80
90
|
:is-toggable="(item) => item.id !== PlAgDataTableRowNumberColId"
|
|
81
91
|
:is-pinned="(item) => !!item.column.getColDef().lockPosition"
|
|
82
92
|
:is-pinnable="() => false"
|
|
93
|
+
:disable-dragging="query.length > 0"
|
|
83
94
|
disable-removing
|
|
84
95
|
>
|
|
85
96
|
<template #item-title="{ item }">
|
|
86
|
-
|
|
97
|
+
<span>
|
|
98
|
+
<span
|
|
99
|
+
v-for="(segment, i) of segments.get(item.label)"
|
|
100
|
+
:key="i"
|
|
101
|
+
:class="{ [$style.match]: segment.match }"
|
|
102
|
+
>{{ segment.value }}</span>
|
|
103
|
+
</span>
|
|
87
104
|
</template>
|
|
88
105
|
</PlElementList>
|
|
89
106
|
</PlSlideModal>
|
|
90
107
|
</div>
|
|
91
108
|
</template>
|
|
109
|
+
|
|
110
|
+
<style module>
|
|
111
|
+
.match {
|
|
112
|
+
background-color: var(--color-active-select);
|
|
113
|
+
border-radius: 2px;
|
|
114
|
+
}
|
|
115
|
+
</style>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { computed, type MaybeRefOrGetter, toValue } from 'vue';
|
|
2
|
+
|
|
3
|
+
export function useFilteredItems<T>(
|
|
4
|
+
props: MaybeRefOrGetter<{
|
|
5
|
+
items: T[];
|
|
6
|
+
query: string;
|
|
7
|
+
getStrings: (item: T) => Iterable<string>;
|
|
8
|
+
}>,
|
|
9
|
+
) {
|
|
10
|
+
const result = computed(() => {
|
|
11
|
+
const { items, query, getStrings } = toValue(props);
|
|
12
|
+
const filteredItems: T[] = [];
|
|
13
|
+
const segments = new Map<string, StringSegment[]>();
|
|
14
|
+
for (const item of items) {
|
|
15
|
+
let kept = false;
|
|
16
|
+
for (const string of getStrings(item)) {
|
|
17
|
+
let stringSegments = segments.get(string);
|
|
18
|
+
if (!stringSegments) {
|
|
19
|
+
stringSegments = matchSubstrings(string, query);
|
|
20
|
+
segments.set(string, stringSegments);
|
|
21
|
+
}
|
|
22
|
+
if (!kept && (!query || stringSegments.some(({ match }) => match))) {
|
|
23
|
+
filteredItems.push(item);
|
|
24
|
+
kept = true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return { filteredItems, segments };
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
filteredItems: computed(() => result.value.filteredItems),
|
|
32
|
+
segments: computed(() => result.value.segments),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Very naïve implementation of substring matching, doesn't handle Unicode well
|
|
37
|
+
// Maybe one day we'll have nice things: https://github.com/tc39/ecma402/issues/506
|
|
38
|
+
function matchSubstrings(haystack: string, needle: string): StringSegment[] {
|
|
39
|
+
if (!needle) return [{ value: haystack, match: false }];
|
|
40
|
+
const haystackLower = haystack.toLowerCase();
|
|
41
|
+
const needleLower = needle.toLowerCase();
|
|
42
|
+
const result: StringSegment[] = [];
|
|
43
|
+
let prevEnd = 0;
|
|
44
|
+
while (true) {
|
|
45
|
+
const start = haystackLower.indexOf(needleLower, prevEnd);
|
|
46
|
+
const end = start + needle.length;
|
|
47
|
+
if (start < 0) break;
|
|
48
|
+
if (prevEnd !== start) {
|
|
49
|
+
result.push({ value: haystack.slice(prevEnd, start), match: false });
|
|
50
|
+
}
|
|
51
|
+
const prevSegment = result.at(-1);
|
|
52
|
+
if (prevSegment?.match) {
|
|
53
|
+
prevSegment.value += haystack.slice(start, end);
|
|
54
|
+
} else {
|
|
55
|
+
result.push({ value: haystack.slice(start, end), match: true });
|
|
56
|
+
}
|
|
57
|
+
prevEnd = end;
|
|
58
|
+
}
|
|
59
|
+
if (prevEnd < haystack.length) {
|
|
60
|
+
result.push({ value: haystack.slice(prevEnd), match: false });
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
type StringSegment = {
|
|
66
|
+
value: string;
|
|
67
|
+
match: boolean;
|
|
68
|
+
};
|
|
@@ -22,6 +22,9 @@ import {
|
|
|
22
22
|
type PTableColumnId,
|
|
23
23
|
type PTableSorting,
|
|
24
24
|
pTableValue,
|
|
25
|
+
readAnnotation,
|
|
26
|
+
Annotation,
|
|
27
|
+
readAnnotationJson,
|
|
25
28
|
} from '@platforma-sdk/model';
|
|
26
29
|
import { ref, watch } from 'vue';
|
|
27
30
|
import { highlightByChemicalProperties } from './chemical-properties';
|
|
@@ -68,7 +71,7 @@ async function getSequenceColumnsOptions({
|
|
|
68
71
|
const options = columns.values()
|
|
69
72
|
.filter((column) => sequenceColumnPredicate(column))
|
|
70
73
|
.map(({ spec, columnId }) => ({
|
|
71
|
-
label: spec.
|
|
74
|
+
label: readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',
|
|
72
75
|
value: columnId,
|
|
73
76
|
}))
|
|
74
77
|
.toArray();
|
|
@@ -109,8 +112,8 @@ async function getLabelColumnsOptions({
|
|
|
109
112
|
labelColumn
|
|
110
113
|
? canonicalizeJson({ type: 'column', id: labelColumn.columnId })
|
|
111
114
|
: canonicalizeJson({ type: 'axis', id: axisId }),
|
|
112
|
-
labelColumn?.spec.
|
|
113
|
-
?? axisSpec.
|
|
115
|
+
readAnnotation(labelColumn?.spec, Annotation.Label)
|
|
116
|
+
?? readAnnotation(axisSpec, Annotation.Label)
|
|
114
117
|
?? 'Unlabeled axis',
|
|
115
118
|
);
|
|
116
119
|
}
|
|
@@ -124,11 +127,11 @@ async function getLabelColumnsOptions({
|
|
|
124
127
|
});
|
|
125
128
|
|
|
126
129
|
for (const { columnId, spec } of compatibleColumns) {
|
|
127
|
-
const columnIdJson = canonicalizeJson({ type: 'column', id: columnId });
|
|
130
|
+
const columnIdJson = canonicalizeJson({ type: 'column', id: columnId } satisfies PTableColumnId);
|
|
128
131
|
if (optionMap.has(columnIdJson)) continue;
|
|
129
132
|
optionMap.set(
|
|
130
133
|
columnIdJson,
|
|
131
|
-
spec.
|
|
134
|
+
readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',
|
|
132
135
|
);
|
|
133
136
|
}
|
|
134
137
|
|
|
@@ -168,14 +171,14 @@ async function getMarkupColumnsOptions({
|
|
|
168
171
|
}
|
|
169
172
|
return columns.values()
|
|
170
173
|
.filter((column) =>
|
|
171
|
-
column.spec.
|
|
174
|
+
!!readAnnotationJson(column.spec, Annotation.Sequence.IsAnnotation)
|
|
172
175
|
&& isJsonEqual(sequenceColumn.spec.axesSpec, column.spec.axesSpec)
|
|
173
176
|
&& Object.entries(sequenceColumn.spec.domain ?? {}).every((
|
|
174
177
|
[key, value],
|
|
175
178
|
) => column.spec.domain?.[key] === value),
|
|
176
179
|
).map(({ columnId, spec }) => ({
|
|
177
180
|
value: columnId,
|
|
178
|
-
label: spec.
|
|
181
|
+
label: readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',
|
|
179
182
|
}))
|
|
180
183
|
.toArray();
|
|
181
184
|
}
|
|
@@ -339,7 +342,7 @@ async function getMultipleAlignmentData({
|
|
|
339
342
|
);
|
|
340
343
|
|
|
341
344
|
const sequenceNames = sequenceColumns.map((column) =>
|
|
342
|
-
column.spec.spec.
|
|
345
|
+
readAnnotation(column.spec.spec, Annotation.Label) ?? 'Unlabeled column',
|
|
343
346
|
);
|
|
344
347
|
|
|
345
348
|
const labels = Array.from(
|
|
@@ -386,10 +389,7 @@ async function getMultipleAlignmentData({
|
|
|
386
389
|
return markupAlignedSequence(sequences[row][0], markup);
|
|
387
390
|
},
|
|
388
391
|
);
|
|
389
|
-
const labels
|
|
390
|
-
markupColumn.spec.spec.annotations
|
|
391
|
-
?.['pl7.app/sequence/annotation/mapping'] ?? '{}',
|
|
392
|
-
);
|
|
392
|
+
const labels = readAnnotationJson(markupColumn.spec.spec, Annotation.Sequence.Annotation.Mapping) ?? {};
|
|
393
393
|
result.highlightImage = highlightByMarkup({
|
|
394
394
|
markupRows,
|
|
395
395
|
columnCount: concatenatedSequences.at(0)?.length ?? 0,
|
|
@@ -12,6 +12,12 @@ import {
|
|
|
12
12
|
type PlTableFilter,
|
|
13
13
|
type PTableColumnSpec,
|
|
14
14
|
getRawPlatformaInstance,
|
|
15
|
+
readDomain,
|
|
16
|
+
Annotation,
|
|
17
|
+
Domain,
|
|
18
|
+
readAnnotation,
|
|
19
|
+
parseJson,
|
|
20
|
+
readAnnotationJson,
|
|
15
21
|
} from '@platforma-sdk/model';
|
|
16
22
|
import semver from 'semver';
|
|
17
23
|
import type { ListOption } from '@milaboratories/uikit';
|
|
@@ -127,7 +133,7 @@ export const isFilterDiscrete = (filter: PlTableFilter): filter is PlTableFilter
|
|
|
127
133
|
};
|
|
128
134
|
|
|
129
135
|
export function getColumnName(column: PTableColumnSpec, index: string | number) {
|
|
130
|
-
return column.spec.
|
|
136
|
+
return readAnnotation(column.spec, Annotation.Label)?.trim() ?? 'Unlabeled ' + column.type + ' ' + index.toString();
|
|
131
137
|
}
|
|
132
138
|
|
|
133
139
|
export function getFilterReference(filter: PlTableFilter): undefined | number | string {
|
|
@@ -220,18 +226,16 @@ export function parseNumber(column: PTableColumnSpec, value: string): number {
|
|
|
220
226
|
const type = column.type === 'column' ? column.spec.valueType : column.spec.type;
|
|
221
227
|
if ((type === 'Int' || type === 'Long') && !Number.isInteger(parsed)) throw Error('Model value is not an integer.');
|
|
222
228
|
|
|
223
|
-
const min = column.spec.
|
|
229
|
+
const min = readAnnotationJson(column.spec, Annotation.Min);
|
|
224
230
|
if (min !== undefined) {
|
|
225
|
-
|
|
226
|
-
if (Number.isFinite(minValue) && parsed < Number(min)) {
|
|
231
|
+
if (Number.isFinite(min) && parsed < min) {
|
|
227
232
|
throw Error('Model value is too low.');
|
|
228
233
|
}
|
|
229
234
|
}
|
|
230
235
|
|
|
231
|
-
const max = column.spec.
|
|
236
|
+
const max = readAnnotationJson(column.spec, Annotation.Max);
|
|
232
237
|
if (max !== undefined) {
|
|
233
|
-
|
|
234
|
-
if (Number.isFinite(maxValue) && parsed > Number(max)) {
|
|
238
|
+
if (Number.isFinite(max) && parsed > max) {
|
|
235
239
|
throw Error('Model value is too high.');
|
|
236
240
|
}
|
|
237
241
|
}
|
|
@@ -240,7 +244,7 @@ export function parseNumber(column: PTableColumnSpec, value: string): number {
|
|
|
240
244
|
}
|
|
241
245
|
|
|
242
246
|
export function parseString(column: PTableColumnSpec, value: string): string {
|
|
243
|
-
const alphabet = column.spec.
|
|
247
|
+
const alphabet = readDomain(column.spec, Domain.Alphabet) ?? readAnnotation(column.spec, Annotation.Alphabet);
|
|
244
248
|
if (alphabet === 'nucleotide' && !/^[AaTtGgCcNn]+$/.test(value)) throw Error('Model value is not a nucleotide.');
|
|
245
249
|
if (alphabet === 'aminoacid' && !/^[AaCcDdEeFfGgHhIiKkLlMmNnPpQqRrSsTtVvWwYyXx*_]+$/.test(value)) throw Error('Model value is not an aminoacid.');
|
|
246
250
|
return value;
|
|
@@ -260,8 +264,7 @@ export function makeWildcardOptions(
|
|
|
260
264
|
column: PTableColumnSpec,
|
|
261
265
|
reference: string,
|
|
262
266
|
): ListOption<string>[] {
|
|
263
|
-
const alphabet = column.spec.
|
|
264
|
-
?? column.spec.annotations?.['pl7.app/alphabet'];
|
|
267
|
+
const alphabet = readDomain(column.spec, Domain.Alphabet) ?? readAnnotation(column.spec, Annotation.Alphabet);
|
|
265
268
|
if (alphabet === 'nucleotide') {
|
|
266
269
|
return [{
|
|
267
270
|
label: 'N',
|
|
@@ -283,17 +286,17 @@ export function makeWildcardOptions(
|
|
|
283
286
|
}
|
|
284
287
|
|
|
285
288
|
export function makeDiscreteOptions(column: PTableColumnSpec): ListOption<number | string>[] {
|
|
286
|
-
const discreteValuesAnnotation = column.spec.
|
|
289
|
+
const discreteValuesAnnotation = readAnnotation(column.spec, Annotation.DiscreteValues);
|
|
287
290
|
if (!discreteValuesAnnotation) return [];
|
|
288
291
|
|
|
289
292
|
try {
|
|
290
|
-
const discreteValues
|
|
293
|
+
const discreteValues = parseJson<number[] | string[]>(discreteValuesAnnotation);
|
|
291
294
|
return discreteValues.map((v) => ({
|
|
292
|
-
label: v
|
|
295
|
+
label: `${v}`,
|
|
293
296
|
value: v,
|
|
294
297
|
}));
|
|
295
298
|
} catch (err: unknown) {
|
|
296
|
-
console.error(`Column ${column.id} has invalid '
|
|
299
|
+
console.error(`Column ${column.id} has invalid '${Annotation.DiscreteValues}' annotation: '${discreteValuesAnnotation}'`, err);
|
|
297
300
|
return [];
|
|
298
301
|
}
|
|
299
302
|
}
|
|
@@ -301,7 +304,7 @@ export function makeDiscreteOptions(column: PTableColumnSpec): ListOption<number
|
|
|
301
304
|
export function isAlphabetic(column: PTableColumnSpec): boolean {
|
|
302
305
|
return semver.gt(getRawPlatformaInstance().sdkInfo.sdkVersion, '1.14.0')
|
|
303
306
|
&& (column.type === 'column' ? column.spec.valueType : column.spec.type) === 'String'
|
|
304
|
-
&& (column.spec.
|
|
307
|
+
&& (readDomain(column.spec, Domain.Alphabet) ?? readAnnotation(column.spec, Annotation.Alphabet)) !== undefined;
|
|
305
308
|
}
|
|
306
309
|
|
|
307
310
|
export function makePredicate(alphabetic: boolean, filter: PlTableFilter): SingleValuePredicateV2 {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ExpandTransition.vue.js","sources":["../../../../../../../../../lib/ui/uikit/src/components/PlAccordion/ExpandTransition.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nconst onStart = (el: Element) => {\n el.classList.add('expand-collapse-fix');\n (el as HTMLElement).style.setProperty('--component-height', el.scrollHeight + 'px');\n};\n\nconst onAfter = (el: Element) => {\n (el as HTMLElement).style.removeProperty('--component-height');\n el.classList.remove('expand-collapse-fix');\n};\n</script>\n\n<template>\n <Transition name=\"expand-collapse\" @enter=\"onStart\" @leave=\"onStart\" @after-enter=\"onAfter\" @after-leave=\"onAfter\">\n <slot/>\n </Transition>\n</template>\n\n<style>\n.expand-collapse-fix {\n overflow: hidden;\n}\n\n.expand-collapse-enter-active,\n.expand-collapse-leave-active {\n transition:\n height 0.2s ease-in-out,\n opacity 0.2s ease-in-out;\n height: var(--component-height);\n}\n\n.expand-collapse-enter-from,\n.expand-collapse-leave-to {\n opacity: 0.5;\n height: 0;\n}\n</style>\n"],"names":["onStart","el","onAfter"],"mappings":";;;;AACMA,UAAAA,IAAU,CAACC,MAAgB;AAC5BA,QAAA,UAAU,IAAI,qBAAqB,GACrCA,EAAmB,MAAM,YAAY,sBAAsBA,EAAG,eAAe,IAAI;AAAA,IAAA,GAG9EC,IAAU,CAACD,MAAgB;AAC9BA,QAAmB,MAAM,eAAe,oBAAoB,GAC1DA,EAAA,UAAU,OAAO,qBAAqB;AAAA,IAC3C;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SvgRequired.vue.js","sources":["../../../../../../../../../../../lib/ui/uikit/src/generated/components/svg/images/SvgRequired.vue"],"sourcesContent":["<!-- ⚠️ AUTOGENERATED. DO NOT EDIT. -->\n<script lang=\"ts\">\nimport '../svg-styles.css';\nexport default { name: 'SvgRequired' };\n</script>\n\n<template>\n <div class=\"svg-icon SvgRequired\" style=\"width: 5px; height: 12px\" />\n</template>\n\n<style>\n .SvgRequired { background-image: url(\"data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%225%22%20height%3D%2212%22%20viewBox%3D%220%200%205%2012%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M1.51685%204.8L2.5%203.34159L3.47612%204.8L4.39607%204.12743L3.31461%202.7469L5%202.25133L4.64888%201.16106L3.00562%201.77699L3.06882%200H1.93118L1.99438%201.77699L0.351124%201.16106L0%202.25133L1.68539%202.7469L0.59691%204.12743L1.51685%204.8Z%22%20fill%3D%22%23F1222F%22%2F%3E%3C%2Fsvg%3E\"); }\n</style>\n"],"names":[],"mappings":";;;;;;;;;;;;;AAOoC,MAAA,IAAA;AAAA,EAAA,OAAA;AAAA;;;;;;"}
|