@platforma-sdk/ui-vue 1.33.17 → 1.34.4

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.
Files changed (26) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/lib.css +1 -1
  3. package/dist/lib.js +8355 -8293
  4. package/dist/lib.js.map +1 -1
  5. package/dist/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts +3 -2
  6. package/dist/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts.map +1 -1
  7. package/dist/src/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.d.ts.map +1 -1
  8. package/dist/src/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts +7 -11
  9. package/dist/src/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts.map +1 -1
  10. package/dist/src/components/PlMultiSequenceAlignment/data.d.ts +21 -12
  11. package/dist/src/components/PlMultiSequenceAlignment/data.d.ts.map +1 -1
  12. package/dist/src/components/PlMultiSequenceAlignment/migrations.d.ts +4 -0
  13. package/dist/src/components/PlMultiSequenceAlignment/migrations.d.ts.map +1 -0
  14. package/dist/src/components/PlMultiSequenceAlignment/multi-sequence-alignment.d.ts +0 -5
  15. package/dist/src/components/PlMultiSequenceAlignment/multi-sequence-alignment.d.ts.map +1 -1
  16. package/dist/src/components/PlMultiSequenceAlignment/types.d.ts +0 -4
  17. package/dist/src/components/PlMultiSequenceAlignment/types.d.ts.map +1 -1
  18. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  19. package/package.json +7 -7
  20. package/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue +30 -37
  21. package/src/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue +68 -20
  22. package/src/components/PlMultiSequenceAlignment/Toolbar.vue +5 -5
  23. package/src/components/PlMultiSequenceAlignment/data.ts +140 -146
  24. package/src/components/PlMultiSequenceAlignment/migrations.ts +41 -0
  25. package/src/components/PlMultiSequenceAlignment/multi-sequence-alignment.ts +3 -14
  26. package/src/components/PlMultiSequenceAlignment/types.ts +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/ui-vue",
3
- "version": "1.33.17",
3
+ "version": "1.34.4",
4
4
  "type": "module",
5
5
  "main": "dist/lib.js",
6
6
  "module": "dist/lib.js",
@@ -21,24 +21,24 @@
21
21
  "lru-cache": "^11.1.0",
22
22
  "vue": "^3.5.13",
23
23
  "@milaboratories/biowasm-tools": "^1.1.0",
24
- "@milaboratories/uikit": "^2.2.82",
25
- "@platforma-sdk/model": "^1.33.17"
24
+ "@milaboratories/uikit": "^2.2.83",
25
+ "@platforma-sdk/model": "^1.34.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@faker-js/faker": "^9.2.0",
29
29
  "@types/lodash": "^4.17.16",
30
30
  "@types/node": "~20.16.15",
31
- "@types/semver": "^7.5.8",
31
+ "@types/semver": "^7.7.0",
32
32
  "@vitejs/plugin-vue": "^5.2.3",
33
33
  "@vueuse/core": "~12.4.0",
34
34
  "d3-format": "^3.1.0",
35
35
  "@types/d3-format": "^3.0.4",
36
36
  "canonicalize": "~2.1.0",
37
37
  "happy-dom": "^15.11.7",
38
- "lodash": "^4.17.15",
39
- "rollup-plugin-sourcemaps2": "^0.5.0",
38
+ "lodash": "^4.17.17",
39
+ "rollup-plugin-sourcemaps2": "^0.5.2",
40
40
  "sass": "~1.83.4",
41
- "semver": "^7.6.3",
41
+ "semver": "^7.7.2",
42
42
  "typescript": "~5.5.4",
43
43
  "vite": "^6.3.5",
44
44
  "vitest": "^2.1.9",
@@ -1,7 +1,6 @@
1
1
  <script lang="ts" setup>
2
- import { PlSplash } from '@milaboratories/uikit';
3
2
  import { useObjectUrl } from '@vueuse/core';
4
- import { computed, reactive } from 'vue';
3
+ import { computed } from 'vue';
5
4
  import Consensus from './Consensus.vue';
6
5
  import { colorizeSegmentedColumns } from './highlight';
7
6
  import {
@@ -9,33 +8,33 @@ import {
9
8
  chemicalPropertiesColors,
10
9
  getColumnChemicalProperties,
11
10
  } from './highlight/chemical-properties';
12
- import { useAlignedSequences } from './multi-sequence-alignment';
13
11
  import { getResidueCounts } from './residue-counts';
14
12
  import SeqLogo from './SeqLogo.vue';
15
- import type { ColorScheme, SequenceRow } from './types';
13
+ import type { ColorScheme } from './types';
16
14
 
17
- const { sequenceRows, colorScheme } = defineProps<{
18
- sequenceRows: SequenceRow[];
15
+ const { sequenceRows, labelRows, colorScheme } = defineProps<{
16
+ sequenceRows: string[][];
17
+ labelRows: string[][];
19
18
  colorScheme: ColorScheme;
20
19
  consensus: boolean;
21
20
  seqLogo: boolean;
22
21
  }>();
23
22
 
24
- const alignedSequences = reactive(useAlignedSequences(
25
- () => sequenceRows.map(({ sequence }) => sequence),
26
- ));
23
+ const concatenatedSequences = computed(() =>
24
+ sequenceRows.map((row) => row.join('')),
25
+ );
27
26
 
28
27
  const residueCounts = computed(
29
- () => getResidueCounts(alignedSequences.data),
28
+ () => getResidueCounts(concatenatedSequences.value),
30
29
  );
31
30
 
32
31
  const segmentedColumns = computed(() => {
33
32
  const columnConsensuses = getColumnChemicalProperties({
34
33
  residueCounts: residueCounts.value,
35
- rowCount: alignedSequences.data.length,
34
+ rowCount: sequenceRows.length,
36
35
  });
37
36
  const segmentedColumns = alignedSequencesToSegmentedColumns({
38
- alignedSequences: alignedSequences.data,
37
+ alignedSequences: concatenatedSequences.value,
39
38
  consensuses: columnConsensuses,
40
39
  });
41
40
  return segmentedColumns;
@@ -71,38 +70,32 @@ const highlightImage = computed(
71
70
  </script>
72
71
 
73
72
  <template>
74
- <PlSplash
75
- :class="['pl-scrollable', $style.root]"
76
- :loading="alignedSequences.loading"
77
- type="transparent"
78
- >
73
+ <div :class="['pl-scrollable', $style.root]">
79
74
  <div :class="$style.corner" />
80
75
  <div :class="$style.header">
81
76
  <Consensus v-if="consensus" :residueCounts />
82
77
  <SeqLogo v-if="seqLogo" :residueCounts />
83
78
  </div>
84
- <template v-if="alignedSequences.data.length">
85
- <div :class="$style['labels-container']">
86
- <template v-for="({ labels }, rowIndex) of sequenceRows">
87
- <div
88
- v-for="(label, labelIndex) of labels"
89
- :key="labelIndex"
90
- :style="{ gridRow: rowIndex + 1 }"
91
- >
92
- {{ label }}
93
- </div>
94
- </template>
95
- </div>
96
- <div :class="$style['sequence-data']">
79
+ <div :class="$style.labels">
80
+ <template v-for="(labelRow, rowIndex) of labelRows">
97
81
  <div
98
- v-for="(sequence, sequenceIndex) of alignedSequences.data"
99
- :key="sequenceIndex"
82
+ v-for="(label, labelIndex) of labelRow"
83
+ :key="labelIndex"
84
+ :style="{ gridRow: rowIndex + 1 }"
100
85
  >
101
- {{ sequence }}
86
+ {{ label }}
102
87
  </div>
88
+ </template>
89
+ </div>
90
+ <div :class="$style.sequences">
91
+ <div
92
+ v-for="(sequence, sequenceIndex) of concatenatedSequences"
93
+ :key="sequenceIndex"
94
+ >
95
+ {{ sequence }}
103
96
  </div>
104
- </template>
105
- </PlSplash>
97
+ </div>
98
+ </div>
106
99
  </template>
107
100
 
108
101
  <style module>
@@ -133,7 +126,7 @@ const highlightImage = computed(
133
126
  z-index: 1;
134
127
  }
135
128
 
136
- .labels-container {
129
+ .labels {
137
130
  grid-area: labels;
138
131
  display: grid;
139
132
  grid-auto-flow: dense;
@@ -147,7 +140,7 @@ const highlightImage = computed(
147
140
  line-height: calc(24 / 14);
148
141
  }
149
142
 
150
- .sequence-data {
143
+ .sequences {
151
144
  grid-area: sequences;
152
145
  display: flex;
153
146
  flex-direction: column;
@@ -1,24 +1,30 @@
1
1
  <script lang="ts" setup>
2
- import { PlAlert } from '@milaboratories/uikit';
2
+ import { PlAlert, PlSplash } from '@milaboratories/uikit';
3
3
  import type {
4
4
  PColumnPredicate,
5
5
  PFrameHandle,
6
6
  PlMultiSequenceAlignmentModel,
7
7
  PlSelectionModel,
8
8
  } from '@platforma-sdk/model';
9
- import { computed, ref } from 'vue';
9
+ import { computed, onBeforeMount, reactive, ref } from 'vue';
10
10
  import {
11
+ sequenceLimit,
11
12
  useLabelColumnsOptions,
13
+ useMultipleAlignmentData,
12
14
  useSequenceColumnsOptions,
13
- useSequenceRows,
14
15
  } from './data';
15
16
  import Legend from './Legend.vue';
17
+ import { runMigrations } from './migrations';
16
18
  import MultiSequenceAlignmentView from './MultiSequenceAlignmentView.vue';
17
19
  import { defaultSettings } from './settings';
18
20
  import Toolbar from './Toolbar.vue';
19
21
 
20
22
  const model = defineModel<PlMultiSequenceAlignmentModel>({ default: {} });
21
23
 
24
+ onBeforeMount(() => {
25
+ runMigrations(model);
26
+ });
27
+
22
28
  const props = defineProps<{
23
29
  /**
24
30
  * Handle to PFrame created using `createPFrameForGraphs`.
@@ -74,36 +80,78 @@ const selectedLabelColumnIds = computed({
74
80
  },
75
81
  });
76
82
 
77
- const sequenceRows = useSequenceRows(() => ({
83
+ const multipleAlignmentData = reactive(useMultipleAlignmentData(() => ({
78
84
  pframe: props.pFrame,
79
85
  sequenceColumnIds: selectedSequenceColumnIds.value,
80
86
  labelColumnIds: selectedLabelColumnIds.value,
81
87
  linkerColumnPredicate: props.linkerColumnPredicate,
82
88
  selection: props.selection,
83
- }));
89
+ })));
84
90
 
85
91
  const settings = ref(defaultSettings);
92
+
93
+ const formatNumber = new Intl.NumberFormat('en').format;
94
+
95
+ const selectedTooManySequences = computed(
96
+ () => props.selection && props.selection.selectedKeys.length > sequenceLimit,
97
+ );
86
98
  </script>
87
99
 
88
100
  <template>
89
- <PlAlert v-if="sequenceRows.length < 2" type="warn">
101
+ <Toolbar
102
+ v-model:sequence-columns="selectedSequenceColumnIds"
103
+ v-model:label-columns="selectedLabelColumnIds"
104
+ v-model:settings="settings"
105
+ :sequence-column-options="sequenceColumns.options"
106
+ :label-column-options="labelColumns.options"
107
+ />
108
+ <PlAlert
109
+ v-if="
110
+ !multipleAlignmentData.loading
111
+ && multipleAlignmentData.data.sequences.length < 2
112
+ "
113
+ type="warn"
114
+ icon
115
+ >
90
116
  Please select at least one sequence column and two or more rows to run
91
117
  alignment
92
118
  </PlAlert>
93
119
  <template v-else>
94
- <Toolbar
95
- v-model:sequence-columns="selectedSequenceColumnIds"
96
- v-model:label-columns="selectedLabelColumnIds"
97
- v-model:settings="settings"
98
- :sequence-column-options="sequenceColumns.options"
99
- :label-column-options="labelColumns.options"
100
- />
101
- <MultiSequenceAlignmentView
102
- :sequenceRows
103
- :colorScheme="settings.colorScheme"
104
- :consensus="settings.consensus"
105
- :seq-logo="settings.seqLogo"
106
- />
107
- <Legend v-if="settings.legend" />
120
+ <PlAlert
121
+ v-if="selectedTooManySequences"
122
+ type="warn"
123
+ icon
124
+ label="Visualization is limited"
125
+ >
126
+ MSA visualization supports {{ formatNumber(2) }} to
127
+ {{ formatNumber(sequenceLimit) }} sequences. Only the first
128
+ {{ formatNumber(sequenceLimit) }} will be desplayed.
129
+ </PlAlert>
130
+ <PlSplash
131
+ type="transparent"
132
+ :class="$style.splash"
133
+ :loading="multipleAlignmentData.loading"
134
+ >
135
+ <template v-if="multipleAlignmentData.data.sequences.length">
136
+ <MultiSequenceAlignmentView
137
+ :sequence-rows="multipleAlignmentData.data.sequences"
138
+ :label-rows="multipleAlignmentData.data.labels"
139
+ :colorScheme="settings.colorScheme"
140
+ :consensus="settings.consensus"
141
+ :seq-logo="settings.seqLogo"
142
+ />
143
+ <Legend v-if="settings.legend" />
144
+ </template>
145
+ </PlSplash>
108
146
  </template>
109
147
  </template>
148
+
149
+ <style module>
150
+ .splash {
151
+ flex: 1;
152
+ display: flex;
153
+ flex-direction: column;
154
+ gap: 12px;
155
+ overflow: hidden;
156
+ }
157
+ </style>
@@ -1,12 +1,12 @@
1
1
  <script setup lang="ts">
2
- import type { ListOption } from '@milaboratories/uikit';
3
2
  import {
3
+ type ListOptionNormalized,
4
4
  PlBtnGhost,
5
5
  PlCheckbox,
6
6
  PlDropdown,
7
7
  PlDropdownMulti,
8
8
  } from '@milaboratories/uikit';
9
- import type { PObjectId, PTableColumnIdJson } from '@platforma-sdk/model';
9
+ import type { PObjectId, PTableColumnId } from '@platforma-sdk/model';
10
10
  import type { Settings } from './settings';
11
11
 
12
12
  const sequenceColumns = defineModel<PObjectId[]>(
@@ -14,7 +14,7 @@ const sequenceColumns = defineModel<PObjectId[]>(
14
14
  { required: true },
15
15
  );
16
16
 
17
- const labelColumns = defineModel<PTableColumnIdJson[]>(
17
+ const labelColumns = defineModel<PTableColumnId[]>(
18
18
  'labelColumns',
19
19
  { required: true },
20
20
  );
@@ -25,8 +25,8 @@ const settings = defineModel<Settings>(
25
25
  );
26
26
 
27
27
  defineProps<{
28
- sequenceColumnOptions: ListOption<PObjectId>[];
29
- labelColumnOptions: ListOption<PTableColumnIdJson>[];
28
+ sequenceColumnOptions: ListOptionNormalized<PObjectId>[];
29
+ labelColumnOptions: ListOptionNormalized<PTableColumnId>[];
30
30
  }>();
31
31
  </script>
32
32