@platforma-sdk/ui-vue 1.44.15 → 1.45.5

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 (86) hide show
  1. package/.turbo/turbo-build.log +29 -18
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +22 -0
  4. package/dist/AgGridVue/useAgGridOptions.js +3 -2
  5. package/dist/AgGridVue/useAgGridOptions.js.map +1 -1
  6. package/dist/components/PlAgCsvExporter/export-csv.js +10 -9
  7. package/dist/components/PlAgCsvExporter/export-csv.js.map +1 -1
  8. package/dist/components/PlAgDataTable/PlAgRowCount.vue.js +8 -7
  9. package/dist/components/PlAgDataTable/PlAgRowCount.vue.js.map +1 -1
  10. package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js +10 -9
  11. package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js.map +1 -1
  12. package/dist/components/PlAgRowNumHeader.vue.js +3 -2
  13. package/dist/components/PlAgRowNumHeader.vue.js.map +1 -1
  14. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue.d.ts +4 -4
  15. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js.map +1 -1
  16. package/dist/components/PlAnnotations/components/DynamicForm.vue.d.ts +5 -4
  17. package/dist/components/PlAnnotations/components/DynamicForm.vue2.js +64 -61
  18. package/dist/components/PlAnnotations/components/DynamicForm.vue2.js.map +1 -1
  19. package/dist/components/PlAnnotations/components/FilterSidebar.vue.d.ts +13 -12
  20. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +49 -48
  21. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js.map +1 -1
  22. package/dist/components/PlAnnotations/components/PlAnnotations.vue.d.ts +19 -0
  23. package/dist/components/PlAnnotations/components/PlAnnotations.vue.js +10 -0
  24. package/dist/components/PlAnnotations/components/PlAnnotations.vue.js.map +1 -0
  25. package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js +66 -0
  26. package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js.map +1 -0
  27. package/dist/components/PlAnnotations/components/PlAnnotations.vue3.js +13 -0
  28. package/dist/components/PlAnnotations/components/PlAnnotations.vue3.js.map +1 -0
  29. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue.d.ts +6 -13
  30. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js +35 -78
  31. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js.map +1 -1
  32. package/dist/components/PlAnnotations/index.d.ts +1 -0
  33. package/dist/components/PlAnnotations/types.d.ts +12 -6
  34. package/dist/components/PlAnnotations/utils.d.ts +4 -4
  35. package/dist/components/PlAnnotations/utils.js +2 -11
  36. package/dist/components/PlAnnotations/utils.js.map +1 -1
  37. package/dist/components/PlBtnExportArchive/Item.vue.d.ts +6 -0
  38. package/dist/components/PlBtnExportArchive/Item.vue.js +10 -0
  39. package/dist/components/PlBtnExportArchive/Item.vue.js.map +1 -0
  40. package/dist/components/PlBtnExportArchive/Item.vue2.js +43 -0
  41. package/dist/components/PlBtnExportArchive/Item.vue2.js.map +1 -0
  42. package/dist/components/PlBtnExportArchive/Item.vue3.js +15 -0
  43. package/dist/components/PlBtnExportArchive/Item.vue3.js.map +1 -0
  44. package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue.d.ts +34 -0
  45. package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue.js +10 -0
  46. package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue.js.map +1 -0
  47. package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue2.js +154 -0
  48. package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue2.js.map +1 -0
  49. package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue3.js +13 -0
  50. package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue3.js.map +1 -0
  51. package/dist/components/PlBtnExportArchive/Summary.vue.d.ts +10 -0
  52. package/dist/components/PlBtnExportArchive/Summary.vue.js +10 -0
  53. package/dist/components/PlBtnExportArchive/Summary.vue.js.map +1 -0
  54. package/dist/components/PlBtnExportArchive/Summary.vue2.js +42 -0
  55. package/dist/components/PlBtnExportArchive/Summary.vue2.js.map +1 -0
  56. package/dist/components/PlBtnExportArchive/Summary.vue3.js +13 -0
  57. package/dist/components/PlBtnExportArchive/Summary.vue3.js.map +1 -0
  58. package/dist/components/PlBtnExportArchive/index.d.ts +2 -0
  59. package/dist/components/PlBtnExportArchive/types.d.ts +14 -0
  60. package/dist/index.js +44 -40
  61. package/dist/index.js.map +1 -1
  62. package/dist/lib/util/helpers/dist/prettyBytes.js +68 -0
  63. package/dist/lib/util/helpers/dist/prettyBytes.js.map +1 -0
  64. package/dist/lib.d.ts +1 -0
  65. package/package.json +6 -4
  66. package/src/components/PlAgCsvExporter/export-csv.ts +8 -2
  67. package/src/components/PlAnnotations/components/AnnotationsSidebar.vue +2 -2
  68. package/src/components/PlAnnotations/components/DynamicForm.vue +16 -9
  69. package/src/components/PlAnnotations/components/FilterSidebar.vue +23 -13
  70. package/src/components/PlAnnotations/components/PlAnnotations.vue +92 -0
  71. package/src/components/PlAnnotations/components/PlAnnotationsModal.vue +19 -77
  72. package/src/components/PlAnnotations/index.ts +1 -0
  73. package/src/components/PlAnnotations/types.ts +7 -6
  74. package/src/components/PlAnnotations/utils.ts +5 -13
  75. package/src/components/PlBtnExportArchive/Item.vue +66 -0
  76. package/src/components/PlBtnExportArchive/PlBtnExportArchive.vue +235 -0
  77. package/src/components/PlBtnExportArchive/Summary.vue +56 -0
  78. package/src/components/PlBtnExportArchive/index.ts +2 -0
  79. package/src/components/PlBtnExportArchive/types.ts +17 -0
  80. package/src/lib.ts +2 -0
  81. package/dist/components/PlAnnotations/components/PlAnnotationCreateDialog.vue.d.ts +0 -18
  82. package/dist/components/PlAnnotations/components/PlAnnotationCreateDialog.vue.js +0 -73
  83. package/dist/components/PlAnnotations/components/PlAnnotationCreateDialog.vue.js.map +0 -1
  84. package/dist/components/PlAnnotations/components/PlAnnotationCreateDialog.vue2.js +0 -5
  85. package/dist/components/PlAnnotations/components/PlAnnotationCreateDialog.vue2.js.map +0 -1
  86. package/src/components/PlAnnotations/components/PlAnnotationCreateDialog.vue +0 -64
@@ -0,0 +1,235 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ PlBtnGhost,
4
+ PlIcon16,
5
+ PlIcon24,
6
+ useClickOutside,
7
+ } from '@milaboratories/uikit';
8
+ import { ZipWriter } from '@zip.js/zip.js';
9
+ import { reactive, computed, ref } from 'vue';
10
+ import type { ExportItem, ExportsMap, FileExportEntry } from './types';
11
+ import Item from './Item.vue';
12
+ import { getFileNameFromHandle, ChunkedStreamReader } from '@platforma-sdk/model';
13
+ import { getRawPlatformaInstance } from '@platforma-sdk/model';
14
+ import { uniqueId } from '@milaboratories/helpers';
15
+ import Summary from './Summary.vue';
16
+
17
+ type FilePickerAcceptType = {
18
+ description?: string;
19
+ accept?: Record<string, string[]>;
20
+ };
21
+
22
+ const props = defineProps<{
23
+ fileExports?: FileExportEntry[];
24
+ suggestedFileName?: string;
25
+ disabled?: boolean;
26
+ filePickerTypes?: FilePickerAcceptType[];
27
+ strategy?: 'parallel'; // default is sequential
28
+ debugFn?: (fileName: string) => Promise<void>;
29
+ }>();
30
+
31
+ const defaultData = () => ({
32
+ loading: false,
33
+ name: '',
34
+ exports: undefined as ExportsMap | undefined,
35
+ showExports: false,
36
+ });
37
+
38
+ const data = reactive(defaultData());
39
+
40
+ const updateExportsItem = (id: string, partial: Partial<ExportItem>) => {
41
+ const it = data.exports?.get(id);
42
+ if (it) {
43
+ data.exports?.set(id, { ...it, ...partial });
44
+ }
45
+ };
46
+
47
+ const isReadyToExport = computed(() => {
48
+ return props.fileExports !== undefined && !props.disabled;
49
+ });
50
+
51
+ const items = computed(() => {
52
+ return Array.from(data.exports?.values() ?? []);
53
+ });
54
+
55
+ const archive = computed<ExportItem>(() => {
56
+ return {
57
+ fileName: data.name,
58
+ current: items.value.reduce((acc, item) => acc + item.current, 0),
59
+ size: items.value.reduce((acc, item) => acc + item.size, 0),
60
+ status: items.value.some((item) => item.status === 'in-progress') ? 'in-progress' : items.value.every((item) => item.status === 'completed') ? 'completed' : 'pending',
61
+ hasErrors: items.value.some((item) => item.status === 'error'),
62
+ };
63
+ });
64
+
65
+ type ZipRequest = {
66
+ id: string;
67
+ fileName: string;
68
+ size: number;
69
+ stream: ReadableStream<Uint8Array>;
70
+ };
71
+
72
+ const exportRawTsvs = async () => {
73
+ if (data.loading) {
74
+ data.showExports = true;
75
+ return;
76
+ }
77
+
78
+ if (!isReadyToExport.value || !props.fileExports) {
79
+ return;
80
+ }
81
+
82
+ const defaultFileName = `${new Date().toISOString().split('T')[0]}_Export.zip`;
83
+ const defaultTypes = [{
84
+ description: 'ZIP files',
85
+ accept: {
86
+ 'application/zip': ['.zip'],
87
+ },
88
+ }];
89
+
90
+ // @ts-expect-error - type definition issue TODO: fix this
91
+ const newHandle = await window.showSaveFilePicker({
92
+ types: props.filePickerTypes || defaultTypes,
93
+ suggestedName: props.suggestedFileName || defaultFileName,
94
+ });
95
+
96
+ data.loading = true;
97
+ data.name = newHandle.name;
98
+ data.showExports = true;
99
+ data.exports = new Map();
100
+
101
+ try {
102
+ const writableStream = await newHandle.createWritable();
103
+ const zip = new ZipWriter(writableStream, { keepOrder: true, zip64: true, bufferedWrite: false });
104
+ try {
105
+ const requests = [] as ZipRequest[];
106
+
107
+ for (const entry of props.fileExports) {
108
+ const { importHandle, blobHandle, fileName: customFileName } = entry;
109
+ const fileName = customFileName ?? getFileNameFromHandle(importHandle);
110
+ const { handle, size } = blobHandle;
111
+
112
+ const id = uniqueId();
113
+
114
+ data.exports?.set(id, { fileName, current: 0, size, status: 'pending' });
115
+
116
+ const stream = ChunkedStreamReader.create({
117
+ fetchChunk: async ({ from, to }) => {
118
+ if (props.debugFn) {
119
+ await props.debugFn(fileName);
120
+ }
121
+
122
+ return await getRawPlatformaInstance().blobDriver.getContent(handle, { from, to });
123
+ },
124
+ totalSize: size,
125
+ onError: async (error) => {
126
+ updateExportsItem(id, { status: 'error', error });
127
+ await new Promise((resolve) => setTimeout(resolve, 1000)); // primitive for now
128
+ return 'continue';
129
+ },
130
+ });
131
+
132
+ // Create a chunked stream reader for efficient streaming
133
+ requests.push({ id, fileName, size, stream });
134
+ }
135
+
136
+ const processRequest = async (request: ZipRequest) => {
137
+ const { id, fileName, size, stream } = request;
138
+ const update = (partial: Partial<ExportItem>) => {
139
+ const it = data.exports?.get(id);
140
+ if (it) {
141
+ data.exports?.set(id, { ...it, ...partial });
142
+ }
143
+ };
144
+ await zip.add(fileName, stream, {
145
+ bufferedWrite: true,
146
+ onstart: () => {
147
+ update({ status: 'in-progress' });
148
+ return undefined;
149
+ },
150
+ onprogress: (current: number) => {
151
+ update({ current, status: 'in-progress' });
152
+ return undefined;
153
+ },
154
+ onend() {
155
+ update({ current: size, status: 'completed' });
156
+ return undefined;
157
+ },
158
+ });
159
+ };
160
+
161
+ if (props.strategy === 'parallel') {
162
+ await Promise.all(requests.map(processRequest));
163
+ } else {
164
+ for (const request of requests) {
165
+ await processRequest(request);
166
+ }
167
+ }
168
+ } finally {
169
+ await zip.close().catch((error) => {
170
+ console.error('Error closing zip', error);
171
+ });
172
+ }
173
+ } finally {
174
+ data.loading = false;
175
+ }
176
+ };
177
+
178
+ const progressesRef = ref();
179
+
180
+ useClickOutside([progressesRef], () => {
181
+ data.showExports = false;
182
+ });
183
+ </script>
184
+
185
+ <template>
186
+ <PlBtnGhost
187
+ :disabled="!isReadyToExport" :loading="data.loading" :class="{ [$style['has-exports']]: data.exports }"
188
+ @click.stop="exportRawTsvs"
189
+ >
190
+ <slot />
191
+ <template #append>
192
+ <PlIcon24 :class="$style.icon" name="download" />
193
+ </template>
194
+ </PlBtnGhost>
195
+ <Teleport to="body">
196
+ <div v-if="data.exports && data.showExports" ref="progressesRef" :class="$style.progresses">
197
+ <PlIcon16 :class="$style.close" name="close" @click.stop="data.showExports = false" />
198
+ <Summary :item="archive" />
199
+ <div :class="$style.itemsContainer" class="pl-scrollable-y">
200
+ <Item v-for="item in data.exports?.values()" :key="item.fileName" :item="item" />
201
+ </div>
202
+ </div>
203
+ </Teleport>
204
+ </template>
205
+
206
+ <style module>
207
+ .progresses {
208
+ position: fixed;
209
+ top: 8px;
210
+ right: 8px;
211
+ width: 350px;
212
+ height: auto;
213
+ max-height: 400px;
214
+ overflow: auto;
215
+ background: rgba(0, 0, 0, 0.85);
216
+ border-radius: 8px;
217
+ padding: 20px 8px 8px 20px;
218
+ color: white;
219
+ font-size: 12px;
220
+ font-weight: 600;
221
+ z-index: 1000;
222
+
223
+ .itemsContainer {
224
+ max-height: 300px;
225
+ }
226
+
227
+ .close {
228
+ position: absolute;
229
+ top: 8px;
230
+ right: 8px;
231
+ cursor: pointer;
232
+ --icon-color: white;
233
+ }
234
+ }
235
+ </style>
@@ -0,0 +1,56 @@
1
+ <script setup lang="ts">
2
+ import type { ExportItem } from './types';
3
+ import { prettyBytes } from '@milaboratories/helpers';
4
+
5
+ defineProps<{
6
+ item: ExportItem;
7
+ }>();
8
+
9
+ const emit = defineEmits<{
10
+ (e: 'cancel'): void;
11
+ }>();
12
+ </script>
13
+
14
+ <template>
15
+ <div
16
+ :class="$style.summary"
17
+ >
18
+ <div :class="$style.name">{{ item.fileName }}<span v-if="false" @click.stop="emit('cancel')">[TODO: Cancel]</span></div>
19
+ <div v-if="item.status === 'in-progress'" :class="$style.details">
20
+ <span>{{ prettyBytes(item.current, {}) }}</span>
21
+ <span>/</span>
22
+ <span>{{ prettyBytes(item.size, {}) }}</span>
23
+ </div>
24
+ <div v-else-if="item.status === 'completed'" :class="$style.details">
25
+ Done <span>{{ prettyBytes(item.size, {}) }}</span>
26
+ </div>
27
+ <div v-else :class="$style.details">
28
+ Pending
29
+ </div>
30
+ </div>
31
+ </template>
32
+
33
+ <style module>
34
+ .summary {
35
+ display: flex;
36
+ flex-direction: column;
37
+ margin-bottom: 8px;
38
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
39
+ padding-bottom: 8px;
40
+ --name-font-size: 14px;
41
+ --details-font-size: 12px;
42
+ }
43
+
44
+ .name {
45
+ white-space: nowrap;
46
+ overflow: hidden;
47
+ text-overflow: ellipsis;
48
+ font-size: var(--name-font-size);
49
+ font-weight: 600;
50
+ }
51
+ .details {
52
+ font-size: var(--details-font-size);
53
+ font-weight: 400;
54
+ color: rgba(255, 255, 255, 0.6);
55
+ }
56
+ </style>
@@ -0,0 +1,2 @@
1
+ export { default as PlBtnExportArchive } from './PlBtnExportArchive.vue';
2
+ export type { FileExportEntry } from './types';
@@ -0,0 +1,17 @@
1
+ import type { ImportFileHandle, RemoteBlobHandleAndSize } from '@platforma-sdk/model';
2
+
3
+ export type FileExportEntry = {
4
+ importHandle: ImportFileHandle;
5
+ blobHandle: RemoteBlobHandleAndSize;
6
+ fileName?: string;
7
+ };
8
+
9
+ export type ExportItem = {
10
+ fileName: string;
11
+ current: number;
12
+ size: number;
13
+ status: 'pending' | 'in-progress' | 'completed' | 'error';
14
+ error?: unknown;
15
+ };
16
+
17
+ export type ExportsMap = Map<string, ExportItem>;
package/src/lib.ts CHANGED
@@ -32,6 +32,8 @@ export * from './components/PlMultiSequenceAlignment';
32
32
 
33
33
  export * from './components/PlAnnotations';
34
34
 
35
+ export * from './components/PlBtnExportArchive';
36
+
35
37
  export * from './defineApp';
36
38
 
37
39
  export * from './createModel';
@@ -1,18 +0,0 @@
1
- type __VLS_PublicProps = {
2
- modelValue: boolean;
3
- };
4
- declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
- "update:modelValue": (value: boolean) => any;
6
- } & {
7
- submit: (props: {
8
- type: "byClonotype" | "bySampleAndClonotype";
9
- name: string;
10
- }) => any;
11
- }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
12
- onSubmit?: ((props: {
13
- type: "byClonotype" | "bySampleAndClonotype";
14
- name: string;
15
- }) => any) | undefined;
16
- "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
17
- }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
18
- export default _default;
@@ -1,73 +0,0 @@
1
- import { defineComponent as v, mergeModels as b, useModel as C, ref as P, computed as x, createBlock as g, openBlock as S, unref as t, withCtx as a, createVNode as n, withModifiers as i, createTextVNode as d } from "vue";
2
- import { PlDialogModal as A, PlBtnPrimary as B, PlBtnGhost as M, PlRadioGroup as c, PlTextField as h } from "@milaboratories/uikit";
3
- const G = /* @__PURE__ */ v({
4
- __name: "PlAnnotationCreateDialog",
5
- props: {
6
- modelValue: { type: Boolean, required: !0 },
7
- modelModifiers: {}
8
- },
9
- emits: /* @__PURE__ */ b(["submit"], ["update:modelValue"]),
10
- setup(p, { emit: r }) {
11
- const u = C(p, "modelValue"), s = r, f = [
12
- { label: "Global", value: "byClonotype" },
13
- { label: "Per sample", value: "bySampleAndClonotype" }
14
- ], l = P({
15
- type: "byClonotype",
16
- name: ""
17
- }), m = x(() => l.value.name.length > 3), y = () => {
18
- m.value && s("submit", l.value);
19
- }, V = () => {
20
- u.value = !1;
21
- };
22
- return (k, e) => (S(), g(t(A), {
23
- modelValue: u.value,
24
- "onUpdate:modelValue": e[2] || (e[2] = (o) => u.value = o),
25
- width: "600px"
26
- }, {
27
- title: a(() => e[3] || (e[3] = [
28
- d(" Choose the Annotation Scheme type ")
29
- ])),
30
- default: a(() => [
31
- n(t(c), {
32
- modelValue: l.value.type,
33
- "onUpdate:modelValue": e[0] || (e[0] = (o) => l.value.type = o),
34
- options: f
35
- }, null, 8, ["modelValue"]),
36
- n(t(h), {
37
- modelValue: l.value.name,
38
- "onUpdate:modelValue": e[1] || (e[1] = (o) => l.value.name = o),
39
- label: "Name your Scheme",
40
- "min-length": "3",
41
- "max-length": "40",
42
- placeholder: "Annotation Name",
43
- autofocus: "",
44
- required: ""
45
- }, null, 8, ["modelValue"])
46
- ]),
47
- actions: a(() => [
48
- n(t(B), {
49
- disabled: !m.value,
50
- onClick: i(y, ["stop"])
51
- }, {
52
- default: a(() => e[4] || (e[4] = [
53
- d("Apply")
54
- ])),
55
- _: 1
56
- }, 8, ["disabled"]),
57
- n(t(M), {
58
- onClick: i(V, ["stop"])
59
- }, {
60
- default: a(() => e[5] || (e[5] = [
61
- d("Cancel")
62
- ])),
63
- _: 1
64
- })
65
- ]),
66
- _: 1
67
- }, 8, ["modelValue"]));
68
- }
69
- });
70
- export {
71
- G as default
72
- };
73
- //# sourceMappingURL=PlAnnotationCreateDialog.vue.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlAnnotationCreateDialog.vue.js","sources":["../../../../src/components/PlAnnotations/components/PlAnnotationCreateDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { SimpleOption } from '@milaboratories/uikit';\nimport { PlBtnGhost, PlBtnPrimary, PlDialogModal, PlRadioGroup, PlTextField } from '@milaboratories/uikit';\nimport type { AnnotationMode } from '@platforma-sdk/model';\nimport { computed, ref } from 'vue';\n\n// Models\nconst opened = defineModel<boolean>({ required: true });\n// Emits\nconst emits = defineEmits<{\n (e: 'submit', props: { type: 'byClonotype' | 'bySampleAndClonotype'; name: string }): void;\n}>();\n\nconst annotationSchemaTypes = [\n { label: 'Global', value: 'byClonotype' },\n { label: 'Per sample', value: 'bySampleAndClonotype' },\n] satisfies SimpleOption<AnnotationMode>[];\n\nconst modalState = ref<{\n type: 'byClonotype' | 'bySampleAndClonotype';\n name: string;\n}>({\n type: 'byClonotype',\n name: '',\n});\n\nconst isValidForm = computed(() => {\n return modalState.value.name.length > 3;\n});\n\nconst handleSubmit = () => {\n if (isValidForm.value) {\n emits('submit', modalState.value);\n }\n};\n\nconst handleCancel = () => {\n opened.value = false;\n};\n</script>\n\n<template>\n <PlDialogModal v-model=\"opened\" width=\"600px\">\n <template #title>\n Choose the Annotation Scheme type\n </template>\n <template #default>\n <PlRadioGroup v-model=\"modalState.type\" :options=\"annotationSchemaTypes\" />\n <PlTextField\n v-model=\"modalState.name\"\n label=\"Name your Scheme\"\n min-length=\"3\"\n max-length=\"40\"\n placeholder=\"Annotation Name\"\n autofocus\n required\n />\n </template>\n <template #actions>\n <PlBtnPrimary :disabled=\"!isValidForm\" @click.stop=\"handleSubmit\">Apply</PlBtnPrimary>\n <PlBtnGhost @click.stop=\"handleCancel\">Cancel</PlBtnGhost>\n </template>\n </PlDialogModal>\n</template>\n"],"names":["opened","_useModel","__props","emits","__emit","annotationSchemaTypes","modalState","ref","isValidForm","computed","handleSubmit","handleCancel"],"mappings":";;;;;;;;;;AAOA,UAAMA,IAASC,EAAoBC,GAAA,YAAmB,GAEhDC,IAAQC,GAIRC,IAAwB;AAAA,MAC5B,EAAE,OAAO,UAAU,OAAO,cAAA;AAAA,MAC1B,EAAE,OAAO,cAAc,OAAO,uBAAA;AAAA,IAAuB,GAGjDC,IAAaC,EAGhB;AAAA,MACD,MAAM;AAAA,MACN,MAAM;AAAA,IAAA,CACP,GAEKC,IAAcC,EAAS,MACpBH,EAAW,MAAM,KAAK,SAAS,CACvC,GAEKI,IAAe,MAAM;AACzB,MAAIF,EAAY,SACdL,EAAM,UAAUG,EAAW,KAAK;AAAA,IAEpC,GAEMK,IAAe,MAAM;AACzB,MAAAX,EAAO,QAAQ;AAAA,IACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +0,0 @@
1
- import f from "./PlAnnotationCreateDialog.vue.js";
2
- export {
3
- f as default
4
- };
5
- //# sourceMappingURL=PlAnnotationCreateDialog.vue2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlAnnotationCreateDialog.vue2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,64 +0,0 @@
1
- <script setup lang="ts">
2
- import type { SimpleOption } from '@milaboratories/uikit';
3
- import { PlBtnGhost, PlBtnPrimary, PlDialogModal, PlRadioGroup, PlTextField } from '@milaboratories/uikit';
4
- import type { AnnotationMode } from '@platforma-sdk/model';
5
- import { computed, ref } from 'vue';
6
-
7
- // Models
8
- const opened = defineModel<boolean>({ required: true });
9
- // Emits
10
- const emits = defineEmits<{
11
- (e: 'submit', props: { type: 'byClonotype' | 'bySampleAndClonotype'; name: string }): void;
12
- }>();
13
-
14
- const annotationSchemaTypes = [
15
- { label: 'Global', value: 'byClonotype' },
16
- { label: 'Per sample', value: 'bySampleAndClonotype' },
17
- ] satisfies SimpleOption<AnnotationMode>[];
18
-
19
- const modalState = ref<{
20
- type: 'byClonotype' | 'bySampleAndClonotype';
21
- name: string;
22
- }>({
23
- type: 'byClonotype',
24
- name: '',
25
- });
26
-
27
- const isValidForm = computed(() => {
28
- return modalState.value.name.length > 3;
29
- });
30
-
31
- const handleSubmit = () => {
32
- if (isValidForm.value) {
33
- emits('submit', modalState.value);
34
- }
35
- };
36
-
37
- const handleCancel = () => {
38
- opened.value = false;
39
- };
40
- </script>
41
-
42
- <template>
43
- <PlDialogModal v-model="opened" width="600px">
44
- <template #title>
45
- Choose the Annotation Scheme type
46
- </template>
47
- <template #default>
48
- <PlRadioGroup v-model="modalState.type" :options="annotationSchemaTypes" />
49
- <PlTextField
50
- v-model="modalState.name"
51
- label="Name your Scheme"
52
- min-length="3"
53
- max-length="40"
54
- placeholder="Annotation Name"
55
- autofocus
56
- required
57
- />
58
- </template>
59
- <template #actions>
60
- <PlBtnPrimary :disabled="!isValidForm" @click.stop="handleSubmit">Apply</PlBtnPrimary>
61
- <PlBtnGhost @click.stop="handleCancel">Cancel</PlBtnGhost>
62
- </template>
63
- </PlDialogModal>
64
- </template>