@milaboratories/uikit 2.13.4 → 2.14.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.
@@ -1,6 +1,6 @@
1
1
   WARN  Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @milaboratories/uikit@2.13.4 build /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.14.0 build /home/runner/_work/platforma/platforma/lib/ui/uikit
4
4
  > ts-builder build --target browser-lib --build-config ./build.browser-lib.config.js
5
5
 
6
6
  Building browser-lib project...
@@ -24,7 +24,7 @@ Using custom config: ./build.browser-lib.config.js
24
24
  rendering chunks...
25
25
 
26
26
  [vite:dts] Start generate declaration files...
27
- [vite:dts] Declaration files built in 9300ms.
27
+ [vite:dts] Declaration files built in 6537ms.
28
28
 
29
29
  computing gzip size...
30
30
  dist/components/PlClipboard/PlClipboard.vue?vue&type=style&index=0&lang.css 0.04 kB │ gzip: 0.06 kB
@@ -534,14 +534,6 @@ dist/composition/useQuery.js
534
534
  dist/assets/icons/icon-assets-min/16_settings.js 0.64 kB │ gzip: 0.37 kB │ map: 0.71 kB
535
535
  dist/assets/icons/icon-assets-min/24_table-upload.js 0.64 kB │ gzip: 0.38 kB │ map: 0.73 kB
536
536
  dist/assets/icons/icon-assets-min/16_data-dimentions.js 0.64 kB │ gzip: 0.42 kB │ map: 0.74 kB
537
- [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
538
- - vite:asset (42%)
539
- - vite:css-post (12%)
540
- - vite:dts (9%)
541
- - sourcemaps (9%)
542
- - vite:css (8%)
543
- See https://rolldown.rs/options/checks#plugintimings for more details.
544
- 
545
537
  dist/assets/icons/icon-assets-min/16_clipboard.js 0.64 kB │ gzip: 0.38 kB │ map: 0.72 kB
546
538
  dist/components/PlFileDialog/utils.js 0.64 kB │ gzip: 0.43 kB │ map: 2.18 kB
547
539
  dist/assets/icons/icon-assets-min/24_frame-type-none.js 0.65 kB │ gzip: 0.30 kB │ map: 0.72 kB
@@ -597,6 +589,14 @@ dist/assets/icons/icon-assets-min/24_folder-parent.js
597
589
  dist/assets/icons/icon-assets-min/24_file-doc-add.js 0.74 kB │ gzip: 0.43 kB │ map: 0.83 kB
598
590
  dist/assets/icons/icon-assets-min/24_filter.js 0.74 kB │ gzip: 0.44 kB │ map: 0.83 kB
599
591
  dist/assets/icons/icon-assets-min/24_cpu.js 0.74 kB │ gzip: 0.42 kB │ map: 0.82 kB
592
+ [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
593
+ - vite:asset (40%)
594
+ - sourcemaps (12%)
595
+ - vite:dts (11%)
596
+ - vite:vue (11%)
597
+ - vite:css-post (8%)
598
+ See https://rolldown.rs/options/checks#plugintimings for more details.
599
+ 
600
600
  dist/components/PlChartHistogram/createGridlines.js 0.75 kB │ gzip: 0.42 kB │ map: 2.52 kB
601
601
  dist/assets/icons/icon-assets-min/24_cloud-online.js 0.76 kB │ gzip: 0.47 kB │ map: 0.84 kB
602
602
  dist/generated/icons-16.js 0.76 kB │ gzip: 0.44 kB │ map: 1.35 kB
@@ -783,7 +783,7 @@ dist/components/PlFileInput/PlFileInput.vue_vue_type_script_setup_true_lang.js
783
783
  dist/components/SliderRange.vue_vue_type_script_setup_true_lang.js 5.92 kB │ gzip: 2.13 kB │ map: 12.27 kB
784
784
  dist/components/PlNumberField/PlNumberField.vue_vue_type_script_setup_true_lang.js 6.24 kB │ gzip: 2.28 kB │ map: 17.67 kB
785
785
  dist/components/PlDropdownLine/PlDropdownLine.vue_vue_type_script_setup_true_lang.js 7.23 kB │ gzip: 2.55 kB │ map: 21.04 kB
786
- dist/components/PlFileDialog/Remote.vue_vue_type_script_setup_true_lang.js 7.32 kB │ gzip: 2.76 kB │ map: 15.25 kB
786
+ dist/components/PlFileDialog/Remote.vue_vue_type_script_setup_true_lang.js 7.32 kB │ gzip: 2.76 kB │ map: 15.24 kB
787
787
  dist/components/SliderRangeTriple.vue_vue_type_script_setup_true_lang.js 7.35 kB │ gzip: 2.43 kB │ map: 15.58 kB
788
788
  dist/components/PlDropdownMulti/PlDropdownMulti.vue_vue_type_script_setup_true_lang.js 7.54 kB │ gzip: 2.76 kB │ map: 22.56 kB
789
789
  dist/components/PlDropdownLegacy/PlDropdownLegacy.vue_vue_type_script_setup_true_lang.js 7.78 kB │ gzip: 2.80 kB │ map: 15.70 kB
@@ -796,5 +796,5 @@ dist/composition/filters/metadata.js
796
796
  dist/index.js 12.53 kB │ gzip: 2.96 kB │ map: 21.32 kB
797
797
  dist/components/PlSvg/PlSvg.vue_vue_type_script_setup_true_lang.js 39.41 kB │ gzip: 3.40 kB │ map: 8.66 kB
798
798
 
799
- ✓ built in 12.01s
799
+ ✓ built in 9.08s
800
800
  Build completed successfully
@@ -1,6 +1,6 @@
1
1
   WARN  Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @milaboratories/uikit@2.13.4 formatter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.14.0 formatter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
4
4
  > ts-builder formatter --check
5
5
 
6
6
  Checking formatting...
@@ -8,5 +8,5 @@ Checking formatting...
8
8
  Checking formatting...
9
9
 
10
10
  All matched files use the correct format.
11
- Finished in 5497ms on 381 files using 8 threads.
11
+ Finished in 6098ms on 381 files using 8 threads.
12
12
  Format check completed successfully
@@ -1,10 +1,10 @@
1
1
   WARN  Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @milaboratories/uikit@2.13.4 linter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.14.0 linter:check /home/runner/_work/platforma/platforma/lib/ui/uikit
4
4
  > ts-builder linter --check
5
5
 
6
6
  Linting project...
7
7
  ↳ oxlint --config /home/runner/_work/platforma/platforma/lib/ui/uikit/.oxlintrc.json --deny-warnings
8
8
  Found 0 warnings and 0 errors.
9
- Finished in 36ms on 308 files with 98 rules using 8 threads.
9
+ Finished in 32ms on 308 files with 98 rules using 8 threads.
10
10
  Linting completed successfully
@@ -1,6 +1,6 @@
1
1
   WARN  Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @milaboratories/uikit@2.13.4 types:check /home/runner/_work/platforma/platforma/lib/ui/uikit
3
+ > @milaboratories/uikit@2.14.0 types:check /home/runner/_work/platforma/platforma/lib/ui/uikit
4
4
  > ts-builder type-check --target browser-lib
5
5
 
6
6
  ↳ vue-tsc.js --noEmit --project ./tsconfig.json --customConditions ,
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @milaboratories/uikit
2
2
 
3
+ ## 2.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 72a9e61: Support signatures tracking and strict security mode of backend
8
+
9
+ ### Patch Changes
10
+
11
+ - @platforma-sdk/model@1.74.0
12
+ - @milaboratories/helpers@1.14.1
13
+
14
+ ## 2.13.5
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [114448e]
19
+ - @platforma-sdk/model@1.73.3
20
+
3
21
  ## 2.13.4
4
22
 
5
23
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"Remote.js","names":[],"sources":["../../../src/components/PlFileDialog/Remote.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { useEventListener } from \"../../composition/useEventListener\";\nimport type { ImportedFiles } from \"../../types\";\nimport { between, notEmpty, tapIf } from \"@milaboratories/helpers\";\nimport { getRawPlatformaInstance, type StorageHandle } from \"@platforma-sdk/model\";\nimport { computed, onMounted, reactive, ref, toRef, watch } from \"vue\";\nimport { PlDropdown } from \"../PlDropdown\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport Shortcuts from \"./Shortcuts.vue\";\nimport { PlMaskIcon16 } from \"../PlMaskIcon16\";\nimport { PlSearchField } from \"../PlSearchField\";\nimport style from \"./pl-file-dialog.module.scss\";\nimport { defaultData, useVisibleItems, vTextOverflown } from \"./remote-helpers\";\nimport { getFilePathBreadcrumbs, normalizeExtensions, type FileDialogItem } from \"./utils\";\n\n// note that on a Mac, a click combined with the control key is intercepted by the operating system and used to open a context menu, so ctrlKey is not detectable on click events.\nconst isCtrlOrMeta = (ev: KeyboardEvent | MouseEvent) => ev.ctrlKey || ev.metaKey;\n\ndefineEmits<{\n (e: \"update:modelValue\", value: boolean): void;\n (e: \"import:files\", value: ImportedFiles): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue: boolean;\n extensions?: string[]; // with dot, like ['.fastq.gz', '.fastq']\n multi?: boolean;\n title?: string;\n autoSelectStorage?: boolean;\n submit: () => void;\n }>(),\n {\n extensions: undefined,\n title: undefined,\n autoSelectStorage: true,\n },\n);\n\nconst data = reactive(defaultData());\n\nconst resetData = () => {\n data.search = \"\";\n data.error = \"\";\n data.lastSelected = undefined;\n};\n\nconst extensions = computed(() => normalizeExtensions(props.extensions));\n\nconst visibleItems = useVisibleItems(data);\n\nconst lookup = computed(() => {\n return {\n modelValue: props.modelValue,\n dirPath: data.dirPath,\n storageHandle: data.storageEntry?.handle,\n };\n});\n\nconst query = (storageHandle: StorageHandle, dirPath: string) => {\n if (!getRawPlatformaInstance()) {\n return;\n }\n\n if (data.currentLoadingPath === dirPath) {\n return;\n }\n\n data.currentLoadingPath = dirPath;\n\n getRawPlatformaInstance()\n .lsDriver.listFiles(storageHandle, dirPath)\n .then((res) => {\n if (dirPath !== data.dirPath) {\n return;\n }\n\n data.items = notEmpty(res)\n .entries.map((item) => ({\n path: item.fullPath,\n name: item.name,\n isDir: item.type === \"dir\",\n canBeSelected:\n item.type === \"file\" &&\n (!extensions.value || extensions.value.some((ext) => item.fullPath.endsWith(ext))),\n handle: item.type === \"file\" ? item.handle : undefined,\n selected: false,\n }))\n .sort((a, b) => {\n if (a.isDir && !b.isDir) return -1;\n if (!a.isDir && b.isDir) return 1;\n // localeCompare for unicode alphabets\n return a.name.localeCompare(b.name);\n })\n .map((it, id) => ({ id, ...it }));\n\n data.lastSelected = undefined;\n })\n .catch((err) => (data.error = String(err)))\n .finally(() => {\n data.currentLoadingPath = undefined;\n });\n};\n\nconst load = () => {\n resetData();\n const { storageHandle, dirPath, modelValue } = lookup.value;\n if (storageHandle && modelValue) {\n query(storageHandle, dirPath);\n }\n};\n\nconst breadcrumbs = computed(() => getFilePathBreadcrumbs(data.dirPath));\n\nconst selectedFiles = computed(() =>\n data.items.filter((f) => f.canBeSelected && f.selected && !f.isDir),\n);\n\nconst isReady = computed(() => selectedFiles.value.length > 0 && data.storageEntry?.handle);\n\nconst getFilesToImport = () => ({\n storageHandle: notEmpty(data.storageEntry?.handle),\n files: selectedFiles.value.map((f) => f.handle!),\n});\n\nconst setDirPath = (dirPath: string) => {\n data.dirPath = dirPath;\n};\n\nconst selectFile = (ev: MouseEvent, file: FileDialogItem) => {\n const { shiftKey } = ev;\n\n const ctrlOrMetaKey = isCtrlOrMeta(ev);\n\n const { lastSelected } = data;\n\n ev.preventDefault();\n\n const items = visibleItems.value;\n\n if (file.canBeSelected) {\n if (!props.multi) {\n items.forEach((f) => (f.selected = false));\n }\n\n file.selected = !file.selected;\n\n if (!props.multi) {\n return;\n }\n\n if (!ctrlOrMetaKey && !shiftKey) {\n items.forEach((f) => {\n if (f.id !== file.id) {\n f.selected = false;\n }\n });\n }\n\n if (shiftKey && lastSelected !== undefined) {\n items.forEach((f) => {\n if (between(f.id, lastSelected, file.id)) {\n f.selected = true;\n }\n });\n }\n\n if (file.selected) {\n data.lastSelected = file.id;\n }\n }\n};\n\nconst changeAll = (selected: boolean) => {\n if (selected && !props.multi) {\n return;\n }\n\n visibleItems.value\n .filter((f) => f.canBeSelected)\n .forEach((file) => {\n file.selected = selected;\n });\n};\n\nconst selectAll = () => changeAll(true);\n\nconst deselectAll = () => changeAll(false);\n\nconst loadAvailableStorages = () => {\n resetData();\n deselectAll();\n if (!getRawPlatformaInstance()) {\n console.warn(\"platforma API is not found\");\n return;\n }\n getRawPlatformaInstance()\n .lsDriver.getStorageList()\n .then((storageEntries) => {\n // local storage is always returned by the ML, so we need to remove it from remote dialog manually\n storageEntries = storageEntries.filter(\n (it) => it.name !== \"local\" && !it.name.startsWith(\"local_disk_\"),\n );\n\n data.storageOptions = storageEntries.map((it) => ({\n text: it.name,\n value: it,\n }));\n\n if (props.autoSelectStorage) {\n tapIf(storageEntries[0], (entry) => {\n data.storageEntry = entry;\n });\n }\n })\n .catch((err) => (data.error = String(err)));\n};\n\nwatch(\n toRef(data, \"storageEntry\"),\n (entry) => {\n resetData();\n data.dirPath = entry?.initialFullPath ?? \"\";\n },\n { immediate: true },\n);\n\nwatch([() => data.dirPath, () => data.storageEntry], () => {\n load();\n});\n\nwatch(\n () => props.modelValue,\n (isOpen) => {\n if (isOpen) {\n loadAvailableStorages();\n } else {\n Object.assign(data, defaultData());\n }\n },\n { immediate: true },\n);\n\nuseEventListener(document, \"keydown\", (ev: KeyboardEvent) => {\n if (!props.modelValue) {\n return;\n }\n\n if (ev.target !== document.body) {\n return;\n }\n\n const ctrlOrMetaKey = isCtrlOrMeta(ev);\n\n if (ctrlOrMetaKey && ev.code === \"KeyA\") {\n ev.preventDefault();\n selectAll();\n }\n\n if (ctrlOrMetaKey && ev.shiftKey && ev.code === \"Period\") {\n ev.preventDefault();\n data.showHiddenItems = !data.showHiddenItems;\n }\n\n if (ev.code === \"Enter\") {\n props.submit();\n }\n});\n\ndefineExpose({\n isReady,\n getFilesToImport,\n});\n\nonMounted(loadAvailableStorages);\n\nconst lsContainerRef = ref<HTMLElement | undefined>();\n</script>\n\n<template>\n <div :class=\"style.remote\" @click.stop=\"deselectAll\">\n <div :class=\"style.search\">\n <div>\n <PlDropdown\n v-model=\"data.storageEntry\"\n label=\"Select storage\"\n :options=\"data.storageOptions\"\n />\n </div>\n <div>\n <PlSearchField v-model=\"data.search\" label=\"Search in folder\" clearable />\n </div>\n </div>\n <div :class=\"style['ls-container']\" ref=\"lsContainerRef\">\n <div :class=\"style['ls-head']\">\n <div :class=\"style['breadcrumbs']\">\n <template v-for=\"(s, i) in breadcrumbs\" :key=\"i\">\n <div :title=\"s.path\" @click=\"setDirPath(s.path)\">{{ s.name }}</div>\n <PlIcon16 v-if=\"s.index !== breadcrumbs.length - 1\" name=\"chevron-right\" />\n </template>\n </div>\n <div :class=\"style.selected\">\n <span>Selected: {{ selectedFiles.length }}</span>\n <Shortcuts :container=\"lsContainerRef\" />\n </div>\n </div>\n <div v-if=\"data.currentLoadingPath !== undefined\" class=\"ls-loader\">\n <i class=\"mask-24 mask-loading loader-icon\" />\n </div>\n <div v-else-if=\"!data.storageEntry\" :class=\"style['ls-empty']\">\n <div :class=\"style.cat\" />\n <div :class=\"style.message\">Select storage to preview</div>\n </div>\n <div v-else-if=\"data.error\" :class=\"style['ls-error']\">\n <div :class=\"style.cat\" />\n <div :class=\"style.message\">{{ data.error }}</div>\n </div>\n <div v-else :class=\"style['ls-body']\">\n <template v-for=\"file in visibleItems\" :key=\"file.id\">\n <div v-if=\"file.isDir\" :class=\"style.isDir\" @click=\"setDirPath(file.path)\">\n <PlIcon16 name=\"chevron-right\" />\n <span v-text-overflown :title=\"file.name\">{{ file.name }}</span>\n </div>\n <div\n v-else\n :class=\"{ [style.canBeSelected]: file.canBeSelected, [style.selected]: file.selected }\"\n @click.stop=\"(ev) => selectFile(ev, file)\"\n >\n <PlMaskIcon16 name=\"box\" :class=\"style.isFile\" />\n <span v-text-overflown :title=\"file.name\">{{ file.name }}</span>\n </div>\n </template>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Remote.js","names":[],"sources":["../../../src/components/PlFileDialog/Remote.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { useEventListener } from \"../../composition/useEventListener\";\nimport type { ImportedFiles } from \"../../types\";\nimport { between, notEmpty, tapIf } from \"@milaboratories/helpers\";\nimport { getRawPlatformaInstance, type StorageHandle } from \"@platforma-sdk/model\";\nimport { computed, onMounted, reactive, ref, toRef, watch } from \"vue\";\nimport { PlDropdown } from \"../PlDropdown\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport Shortcuts from \"./Shortcuts.vue\";\nimport { PlMaskIcon16 } from \"../PlMaskIcon16\";\nimport { PlSearchField } from \"../PlSearchField\";\nimport style from \"./pl-file-dialog.module.scss\";\nimport { defaultData, useVisibleItems, vTextOverflown } from \"./remote-helpers\";\nimport { getFilePathBreadcrumbs, normalizeExtensions, type FileDialogItem } from \"./utils\";\n\n// note that on a Mac, a click combined with the control key is intercepted by the operating system and used to open a context menu, so ctrlKey is not detectable on click events.\nconst isCtrlOrMeta = (ev: KeyboardEvent | MouseEvent) => ev.ctrlKey || ev.metaKey;\n\ndefineEmits<{\n (e: \"update:modelValue\", value: boolean): void;\n (e: \"import:files\", value: ImportedFiles): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue: boolean;\n extensions?: string[]; // with dot, like ['.fastq.gz', '.fastq']\n multi?: boolean;\n title?: string;\n autoSelectStorage?: boolean;\n submit: () => void;\n }>(),\n {\n extensions: undefined,\n title: undefined,\n autoSelectStorage: true,\n },\n);\n\nconst data = reactive(defaultData());\n\nconst resetData = () => {\n data.search = \"\";\n data.error = \"\";\n data.lastSelected = undefined;\n};\n\nconst extensions = computed(() => normalizeExtensions(props.extensions));\n\nconst visibleItems = useVisibleItems(data);\n\nconst lookup = computed(() => {\n return {\n modelValue: props.modelValue,\n dirPath: data.dirPath,\n storageHandle: data.storageEntry?.handle,\n };\n});\n\nconst query = (storageHandle: StorageHandle, dirPath: string) => {\n if (!getRawPlatformaInstance()) {\n return;\n }\n\n if (data.currentLoadingPath === dirPath) {\n return;\n }\n\n data.currentLoadingPath = dirPath;\n\n getRawPlatformaInstance()\n .lsDriver.listFiles(storageHandle, dirPath)\n .then((res) => {\n if (dirPath !== data.dirPath) {\n return;\n }\n\n data.items = notEmpty(res)\n .entries.map((item) => ({\n path: item.fullPath,\n name: item.name,\n isDir: item.type === \"dir\",\n canBeSelected:\n item.type === \"file\" &&\n (!extensions.value || extensions.value.some((ext) => item.fullPath.endsWith(ext))),\n handle: item.type === \"file\" ? item.handle : undefined,\n selected: false,\n }))\n .sort((a, b) => {\n if (a.isDir && !b.isDir) return -1;\n if (!a.isDir && b.isDir) return 1;\n // localeCompare for unicode alphabets\n return a.name.localeCompare(b.name);\n })\n .map((it, id) => ({ id, ...it }));\n\n data.lastSelected = undefined;\n })\n .catch((err) => (data.error = String(err)))\n .finally(() => {\n data.currentLoadingPath = undefined;\n });\n};\n\nconst load = () => {\n resetData();\n const { storageHandle, dirPath, modelValue } = lookup.value;\n if (storageHandle && modelValue) {\n query(storageHandle, dirPath);\n }\n};\n\nconst breadcrumbs = computed(() => getFilePathBreadcrumbs(data.dirPath));\n\nconst selectedFiles = computed(() =>\n data.items.filter((f) => f.canBeSelected && f.selected && !f.isDir),\n);\n\nconst isReady = computed(() => selectedFiles.value.length > 0 && data.storageEntry?.handle);\n\nconst getFilesToImport = () => ({\n storageHandle: notEmpty(data.storageEntry?.handle),\n files: selectedFiles.value.map((f) => f.handle!),\n});\n\nconst setDirPath = (dirPath: string) => {\n data.dirPath = dirPath;\n};\n\nconst selectFile = (ev: MouseEvent, file: FileDialogItem) => {\n const { shiftKey } = ev;\n\n const ctrlOrMetaKey = isCtrlOrMeta(ev);\n\n const { lastSelected } = data;\n\n ev.preventDefault();\n\n const items = visibleItems.value;\n\n if (file.canBeSelected) {\n if (!props.multi) {\n items.forEach((f) => (f.selected = false));\n }\n\n file.selected = !file.selected;\n\n if (!props.multi) {\n return;\n }\n\n if (!ctrlOrMetaKey && !shiftKey) {\n items.forEach((f) => {\n if (f.id !== file.id) {\n f.selected = false;\n }\n });\n }\n\n if (shiftKey && lastSelected !== undefined) {\n items.forEach((f) => {\n if (between(f.id, lastSelected, file.id)) {\n f.selected = true;\n }\n });\n }\n\n if (file.selected) {\n data.lastSelected = file.id;\n }\n }\n};\n\nconst changeAll = (selected: boolean) => {\n if (selected && !props.multi) {\n return;\n }\n\n visibleItems.value\n .filter((f) => f.canBeSelected)\n .forEach((file) => {\n file.selected = selected;\n });\n};\n\nconst selectAll = () => changeAll(true);\n\nconst deselectAll = () => changeAll(false);\n\nconst loadAvailableStorages = () => {\n resetData();\n deselectAll();\n if (!getRawPlatformaInstance()) {\n console.warn(\"platforma API is not found\");\n return;\n }\n getRawPlatformaInstance()\n .lsDriver.getStorageList()\n .then((storageEntries) => {\n // local storage is always returned by the ML, so we need to remove it from remote dialog manually\n storageEntries = storageEntries.filter(\n (it) => it.id !== \"local\" && !it.id.startsWith(\"local_disk_\"),\n );\n\n data.storageOptions = storageEntries.map((it) => ({\n text: it.name,\n value: it,\n }));\n\n if (props.autoSelectStorage) {\n tapIf(storageEntries[0], (entry) => {\n data.storageEntry = entry;\n });\n }\n })\n .catch((err) => (data.error = String(err)));\n};\n\nwatch(\n toRef(data, \"storageEntry\"),\n (entry) => {\n resetData();\n data.dirPath = entry?.initialFullPath ?? \"\";\n },\n { immediate: true },\n);\n\nwatch([() => data.dirPath, () => data.storageEntry], () => {\n load();\n});\n\nwatch(\n () => props.modelValue,\n (isOpen) => {\n if (isOpen) {\n loadAvailableStorages();\n } else {\n Object.assign(data, defaultData());\n }\n },\n { immediate: true },\n);\n\nuseEventListener(document, \"keydown\", (ev: KeyboardEvent) => {\n if (!props.modelValue) {\n return;\n }\n\n if (ev.target !== document.body) {\n return;\n }\n\n const ctrlOrMetaKey = isCtrlOrMeta(ev);\n\n if (ctrlOrMetaKey && ev.code === \"KeyA\") {\n ev.preventDefault();\n selectAll();\n }\n\n if (ctrlOrMetaKey && ev.shiftKey && ev.code === \"Period\") {\n ev.preventDefault();\n data.showHiddenItems = !data.showHiddenItems;\n }\n\n if (ev.code === \"Enter\") {\n props.submit();\n }\n});\n\ndefineExpose({\n isReady,\n getFilesToImport,\n});\n\nonMounted(loadAvailableStorages);\n\nconst lsContainerRef = ref<HTMLElement | undefined>();\n</script>\n\n<template>\n <div :class=\"style.remote\" @click.stop=\"deselectAll\">\n <div :class=\"style.search\">\n <div>\n <PlDropdown\n v-model=\"data.storageEntry\"\n label=\"Select storage\"\n :options=\"data.storageOptions\"\n />\n </div>\n <div>\n <PlSearchField v-model=\"data.search\" label=\"Search in folder\" clearable />\n </div>\n </div>\n <div :class=\"style['ls-container']\" ref=\"lsContainerRef\">\n <div :class=\"style['ls-head']\">\n <div :class=\"style['breadcrumbs']\">\n <template v-for=\"(s, i) in breadcrumbs\" :key=\"i\">\n <div :title=\"s.path\" @click=\"setDirPath(s.path)\">{{ s.name }}</div>\n <PlIcon16 v-if=\"s.index !== breadcrumbs.length - 1\" name=\"chevron-right\" />\n </template>\n </div>\n <div :class=\"style.selected\">\n <span>Selected: {{ selectedFiles.length }}</span>\n <Shortcuts :container=\"lsContainerRef\" />\n </div>\n </div>\n <div v-if=\"data.currentLoadingPath !== undefined\" class=\"ls-loader\">\n <i class=\"mask-24 mask-loading loader-icon\" />\n </div>\n <div v-else-if=\"!data.storageEntry\" :class=\"style['ls-empty']\">\n <div :class=\"style.cat\" />\n <div :class=\"style.message\">Select storage to preview</div>\n </div>\n <div v-else-if=\"data.error\" :class=\"style['ls-error']\">\n <div :class=\"style.cat\" />\n <div :class=\"style.message\">{{ data.error }}</div>\n </div>\n <div v-else :class=\"style['ls-body']\">\n <template v-for=\"file in visibleItems\" :key=\"file.id\">\n <div v-if=\"file.isDir\" :class=\"style.isDir\" @click=\"setDirPath(file.path)\">\n <PlIcon16 name=\"chevron-right\" />\n <span v-text-overflown :title=\"file.name\">{{ file.name }}</span>\n </div>\n <div\n v-else\n :class=\"{ [style.canBeSelected]: file.canBeSelected, [style.selected]: file.selected }\"\n @click.stop=\"(ev) => selectFile(ev, file)\"\n >\n <PlMaskIcon16 name=\"box\" :class=\"style.isFile\" />\n <span v-text-overflown :title=\"file.name\">{{ file.name }}</span>\n </div>\n </template>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -85,7 +85,7 @@ var te = ["title", "onClick"], ne = {
85
85
  return;
86
86
  }
87
87
  P().lsDriver.getStorageList().then((e) => {
88
- e = e.filter((e) => e.name !== "local" && !e.name.startsWith("local_disk_")), B.storageOptions = e.map((e) => ({
88
+ e = e.filter((e) => e.id !== "local" && !e.id.startsWith("local_disk_")), B.storageOptions = e.map((e) => ({
89
89
  text: e.name,
90
90
  value: e
91
91
  })), z.autoSelectStorage && N(e[0], (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"Remote.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlFileDialog/Remote.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { useEventListener } from \"../../composition/useEventListener\";\nimport type { ImportedFiles } from \"../../types\";\nimport { between, notEmpty, tapIf } from \"@milaboratories/helpers\";\nimport { getRawPlatformaInstance, type StorageHandle } from \"@platforma-sdk/model\";\nimport { computed, onMounted, reactive, ref, toRef, watch } from \"vue\";\nimport { PlDropdown } from \"../PlDropdown\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport Shortcuts from \"./Shortcuts.vue\";\nimport { PlMaskIcon16 } from \"../PlMaskIcon16\";\nimport { PlSearchField } from \"../PlSearchField\";\nimport style from \"./pl-file-dialog.module.scss\";\nimport { defaultData, useVisibleItems, vTextOverflown } from \"./remote-helpers\";\nimport { getFilePathBreadcrumbs, normalizeExtensions, type FileDialogItem } from \"./utils\";\n\n// note that on a Mac, a click combined with the control key is intercepted by the operating system and used to open a context menu, so ctrlKey is not detectable on click events.\nconst isCtrlOrMeta = (ev: KeyboardEvent | MouseEvent) => ev.ctrlKey || ev.metaKey;\n\ndefineEmits<{\n (e: \"update:modelValue\", value: boolean): void;\n (e: \"import:files\", value: ImportedFiles): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue: boolean;\n extensions?: string[]; // with dot, like ['.fastq.gz', '.fastq']\n multi?: boolean;\n title?: string;\n autoSelectStorage?: boolean;\n submit: () => void;\n }>(),\n {\n extensions: undefined,\n title: undefined,\n autoSelectStorage: true,\n },\n);\n\nconst data = reactive(defaultData());\n\nconst resetData = () => {\n data.search = \"\";\n data.error = \"\";\n data.lastSelected = undefined;\n};\n\nconst extensions = computed(() => normalizeExtensions(props.extensions));\n\nconst visibleItems = useVisibleItems(data);\n\nconst lookup = computed(() => {\n return {\n modelValue: props.modelValue,\n dirPath: data.dirPath,\n storageHandle: data.storageEntry?.handle,\n };\n});\n\nconst query = (storageHandle: StorageHandle, dirPath: string) => {\n if (!getRawPlatformaInstance()) {\n return;\n }\n\n if (data.currentLoadingPath === dirPath) {\n return;\n }\n\n data.currentLoadingPath = dirPath;\n\n getRawPlatformaInstance()\n .lsDriver.listFiles(storageHandle, dirPath)\n .then((res) => {\n if (dirPath !== data.dirPath) {\n return;\n }\n\n data.items = notEmpty(res)\n .entries.map((item) => ({\n path: item.fullPath,\n name: item.name,\n isDir: item.type === \"dir\",\n canBeSelected:\n item.type === \"file\" &&\n (!extensions.value || extensions.value.some((ext) => item.fullPath.endsWith(ext))),\n handle: item.type === \"file\" ? item.handle : undefined,\n selected: false,\n }))\n .sort((a, b) => {\n if (a.isDir && !b.isDir) return -1;\n if (!a.isDir && b.isDir) return 1;\n // localeCompare for unicode alphabets\n return a.name.localeCompare(b.name);\n })\n .map((it, id) => ({ id, ...it }));\n\n data.lastSelected = undefined;\n })\n .catch((err) => (data.error = String(err)))\n .finally(() => {\n data.currentLoadingPath = undefined;\n });\n};\n\nconst load = () => {\n resetData();\n const { storageHandle, dirPath, modelValue } = lookup.value;\n if (storageHandle && modelValue) {\n query(storageHandle, dirPath);\n }\n};\n\nconst breadcrumbs = computed(() => getFilePathBreadcrumbs(data.dirPath));\n\nconst selectedFiles = computed(() =>\n data.items.filter((f) => f.canBeSelected && f.selected && !f.isDir),\n);\n\nconst isReady = computed(() => selectedFiles.value.length > 0 && data.storageEntry?.handle);\n\nconst getFilesToImport = () => ({\n storageHandle: notEmpty(data.storageEntry?.handle),\n files: selectedFiles.value.map((f) => f.handle!),\n});\n\nconst setDirPath = (dirPath: string) => {\n data.dirPath = dirPath;\n};\n\nconst selectFile = (ev: MouseEvent, file: FileDialogItem) => {\n const { shiftKey } = ev;\n\n const ctrlOrMetaKey = isCtrlOrMeta(ev);\n\n const { lastSelected } = data;\n\n ev.preventDefault();\n\n const items = visibleItems.value;\n\n if (file.canBeSelected) {\n if (!props.multi) {\n items.forEach((f) => (f.selected = false));\n }\n\n file.selected = !file.selected;\n\n if (!props.multi) {\n return;\n }\n\n if (!ctrlOrMetaKey && !shiftKey) {\n items.forEach((f) => {\n if (f.id !== file.id) {\n f.selected = false;\n }\n });\n }\n\n if (shiftKey && lastSelected !== undefined) {\n items.forEach((f) => {\n if (between(f.id, lastSelected, file.id)) {\n f.selected = true;\n }\n });\n }\n\n if (file.selected) {\n data.lastSelected = file.id;\n }\n }\n};\n\nconst changeAll = (selected: boolean) => {\n if (selected && !props.multi) {\n return;\n }\n\n visibleItems.value\n .filter((f) => f.canBeSelected)\n .forEach((file) => {\n file.selected = selected;\n });\n};\n\nconst selectAll = () => changeAll(true);\n\nconst deselectAll = () => changeAll(false);\n\nconst loadAvailableStorages = () => {\n resetData();\n deselectAll();\n if (!getRawPlatformaInstance()) {\n console.warn(\"platforma API is not found\");\n return;\n }\n getRawPlatformaInstance()\n .lsDriver.getStorageList()\n .then((storageEntries) => {\n // local storage is always returned by the ML, so we need to remove it from remote dialog manually\n storageEntries = storageEntries.filter(\n (it) => it.name !== \"local\" && !it.name.startsWith(\"local_disk_\"),\n );\n\n data.storageOptions = storageEntries.map((it) => ({\n text: it.name,\n value: it,\n }));\n\n if (props.autoSelectStorage) {\n tapIf(storageEntries[0], (entry) => {\n data.storageEntry = entry;\n });\n }\n })\n .catch((err) => (data.error = String(err)));\n};\n\nwatch(\n toRef(data, \"storageEntry\"),\n (entry) => {\n resetData();\n data.dirPath = entry?.initialFullPath ?? \"\";\n },\n { immediate: true },\n);\n\nwatch([() => data.dirPath, () => data.storageEntry], () => {\n load();\n});\n\nwatch(\n () => props.modelValue,\n (isOpen) => {\n if (isOpen) {\n loadAvailableStorages();\n } else {\n Object.assign(data, defaultData());\n }\n },\n { immediate: true },\n);\n\nuseEventListener(document, \"keydown\", (ev: KeyboardEvent) => {\n if (!props.modelValue) {\n return;\n }\n\n if (ev.target !== document.body) {\n return;\n }\n\n const ctrlOrMetaKey = isCtrlOrMeta(ev);\n\n if (ctrlOrMetaKey && ev.code === \"KeyA\") {\n ev.preventDefault();\n selectAll();\n }\n\n if (ctrlOrMetaKey && ev.shiftKey && ev.code === \"Period\") {\n ev.preventDefault();\n data.showHiddenItems = !data.showHiddenItems;\n }\n\n if (ev.code === \"Enter\") {\n props.submit();\n }\n});\n\ndefineExpose({\n isReady,\n getFilesToImport,\n});\n\nonMounted(loadAvailableStorages);\n\nconst lsContainerRef = ref<HTMLElement | undefined>();\n</script>\n\n<template>\n <div :class=\"style.remote\" @click.stop=\"deselectAll\">\n <div :class=\"style.search\">\n <div>\n <PlDropdown\n v-model=\"data.storageEntry\"\n label=\"Select storage\"\n :options=\"data.storageOptions\"\n />\n </div>\n <div>\n <PlSearchField v-model=\"data.search\" label=\"Search in folder\" clearable />\n </div>\n </div>\n <div :class=\"style['ls-container']\" ref=\"lsContainerRef\">\n <div :class=\"style['ls-head']\">\n <div :class=\"style['breadcrumbs']\">\n <template v-for=\"(s, i) in breadcrumbs\" :key=\"i\">\n <div :title=\"s.path\" @click=\"setDirPath(s.path)\">{{ s.name }}</div>\n <PlIcon16 v-if=\"s.index !== breadcrumbs.length - 1\" name=\"chevron-right\" />\n </template>\n </div>\n <div :class=\"style.selected\">\n <span>Selected: {{ selectedFiles.length }}</span>\n <Shortcuts :container=\"lsContainerRef\" />\n </div>\n </div>\n <div v-if=\"data.currentLoadingPath !== undefined\" class=\"ls-loader\">\n <i class=\"mask-24 mask-loading loader-icon\" />\n </div>\n <div v-else-if=\"!data.storageEntry\" :class=\"style['ls-empty']\">\n <div :class=\"style.cat\" />\n <div :class=\"style.message\">Select storage to preview</div>\n </div>\n <div v-else-if=\"data.error\" :class=\"style['ls-error']\">\n <div :class=\"style.cat\" />\n <div :class=\"style.message\">{{ data.error }}</div>\n </div>\n <div v-else :class=\"style['ls-body']\">\n <template v-for=\"file in visibleItems\" :key=\"file.id\">\n <div v-if=\"file.isDir\" :class=\"style.isDir\" @click=\"setDirPath(file.path)\">\n <PlIcon16 name=\"chevron-right\" />\n <span v-text-overflown :title=\"file.name\">{{ file.name }}</span>\n </div>\n <div\n v-else\n :class=\"{ [style.canBeSelected]: file.canBeSelected, [style.selected]: file.selected }\"\n @click.stop=\"(ev) => selectFile(ev, file)\"\n >\n <PlMaskIcon16 name=\"box\" :class=\"style.isFile\" />\n <span v-text-overflown :title=\"file.name\">{{ file.name }}</span>\n </div>\n </template>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"Remote.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlFileDialog/Remote.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { useEventListener } from \"../../composition/useEventListener\";\nimport type { ImportedFiles } from \"../../types\";\nimport { between, notEmpty, tapIf } from \"@milaboratories/helpers\";\nimport { getRawPlatformaInstance, type StorageHandle } from \"@platforma-sdk/model\";\nimport { computed, onMounted, reactive, ref, toRef, watch } from \"vue\";\nimport { PlDropdown } from \"../PlDropdown\";\nimport { PlIcon16 } from \"../PlIcon16\";\nimport Shortcuts from \"./Shortcuts.vue\";\nimport { PlMaskIcon16 } from \"../PlMaskIcon16\";\nimport { PlSearchField } from \"../PlSearchField\";\nimport style from \"./pl-file-dialog.module.scss\";\nimport { defaultData, useVisibleItems, vTextOverflown } from \"./remote-helpers\";\nimport { getFilePathBreadcrumbs, normalizeExtensions, type FileDialogItem } from \"./utils\";\n\n// note that on a Mac, a click combined with the control key is intercepted by the operating system and used to open a context menu, so ctrlKey is not detectable on click events.\nconst isCtrlOrMeta = (ev: KeyboardEvent | MouseEvent) => ev.ctrlKey || ev.metaKey;\n\ndefineEmits<{\n (e: \"update:modelValue\", value: boolean): void;\n (e: \"import:files\", value: ImportedFiles): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue: boolean;\n extensions?: string[]; // with dot, like ['.fastq.gz', '.fastq']\n multi?: boolean;\n title?: string;\n autoSelectStorage?: boolean;\n submit: () => void;\n }>(),\n {\n extensions: undefined,\n title: undefined,\n autoSelectStorage: true,\n },\n);\n\nconst data = reactive(defaultData());\n\nconst resetData = () => {\n data.search = \"\";\n data.error = \"\";\n data.lastSelected = undefined;\n};\n\nconst extensions = computed(() => normalizeExtensions(props.extensions));\n\nconst visibleItems = useVisibleItems(data);\n\nconst lookup = computed(() => {\n return {\n modelValue: props.modelValue,\n dirPath: data.dirPath,\n storageHandle: data.storageEntry?.handle,\n };\n});\n\nconst query = (storageHandle: StorageHandle, dirPath: string) => {\n if (!getRawPlatformaInstance()) {\n return;\n }\n\n if (data.currentLoadingPath === dirPath) {\n return;\n }\n\n data.currentLoadingPath = dirPath;\n\n getRawPlatformaInstance()\n .lsDriver.listFiles(storageHandle, dirPath)\n .then((res) => {\n if (dirPath !== data.dirPath) {\n return;\n }\n\n data.items = notEmpty(res)\n .entries.map((item) => ({\n path: item.fullPath,\n name: item.name,\n isDir: item.type === \"dir\",\n canBeSelected:\n item.type === \"file\" &&\n (!extensions.value || extensions.value.some((ext) => item.fullPath.endsWith(ext))),\n handle: item.type === \"file\" ? item.handle : undefined,\n selected: false,\n }))\n .sort((a, b) => {\n if (a.isDir && !b.isDir) return -1;\n if (!a.isDir && b.isDir) return 1;\n // localeCompare for unicode alphabets\n return a.name.localeCompare(b.name);\n })\n .map((it, id) => ({ id, ...it }));\n\n data.lastSelected = undefined;\n })\n .catch((err) => (data.error = String(err)))\n .finally(() => {\n data.currentLoadingPath = undefined;\n });\n};\n\nconst load = () => {\n resetData();\n const { storageHandle, dirPath, modelValue } = lookup.value;\n if (storageHandle && modelValue) {\n query(storageHandle, dirPath);\n }\n};\n\nconst breadcrumbs = computed(() => getFilePathBreadcrumbs(data.dirPath));\n\nconst selectedFiles = computed(() =>\n data.items.filter((f) => f.canBeSelected && f.selected && !f.isDir),\n);\n\nconst isReady = computed(() => selectedFiles.value.length > 0 && data.storageEntry?.handle);\n\nconst getFilesToImport = () => ({\n storageHandle: notEmpty(data.storageEntry?.handle),\n files: selectedFiles.value.map((f) => f.handle!),\n});\n\nconst setDirPath = (dirPath: string) => {\n data.dirPath = dirPath;\n};\n\nconst selectFile = (ev: MouseEvent, file: FileDialogItem) => {\n const { shiftKey } = ev;\n\n const ctrlOrMetaKey = isCtrlOrMeta(ev);\n\n const { lastSelected } = data;\n\n ev.preventDefault();\n\n const items = visibleItems.value;\n\n if (file.canBeSelected) {\n if (!props.multi) {\n items.forEach((f) => (f.selected = false));\n }\n\n file.selected = !file.selected;\n\n if (!props.multi) {\n return;\n }\n\n if (!ctrlOrMetaKey && !shiftKey) {\n items.forEach((f) => {\n if (f.id !== file.id) {\n f.selected = false;\n }\n });\n }\n\n if (shiftKey && lastSelected !== undefined) {\n items.forEach((f) => {\n if (between(f.id, lastSelected, file.id)) {\n f.selected = true;\n }\n });\n }\n\n if (file.selected) {\n data.lastSelected = file.id;\n }\n }\n};\n\nconst changeAll = (selected: boolean) => {\n if (selected && !props.multi) {\n return;\n }\n\n visibleItems.value\n .filter((f) => f.canBeSelected)\n .forEach((file) => {\n file.selected = selected;\n });\n};\n\nconst selectAll = () => changeAll(true);\n\nconst deselectAll = () => changeAll(false);\n\nconst loadAvailableStorages = () => {\n resetData();\n deselectAll();\n if (!getRawPlatformaInstance()) {\n console.warn(\"platforma API is not found\");\n return;\n }\n getRawPlatformaInstance()\n .lsDriver.getStorageList()\n .then((storageEntries) => {\n // local storage is always returned by the ML, so we need to remove it from remote dialog manually\n storageEntries = storageEntries.filter(\n (it) => it.id !== \"local\" && !it.id.startsWith(\"local_disk_\"),\n );\n\n data.storageOptions = storageEntries.map((it) => ({\n text: it.name,\n value: it,\n }));\n\n if (props.autoSelectStorage) {\n tapIf(storageEntries[0], (entry) => {\n data.storageEntry = entry;\n });\n }\n })\n .catch((err) => (data.error = String(err)));\n};\n\nwatch(\n toRef(data, \"storageEntry\"),\n (entry) => {\n resetData();\n data.dirPath = entry?.initialFullPath ?? \"\";\n },\n { immediate: true },\n);\n\nwatch([() => data.dirPath, () => data.storageEntry], () => {\n load();\n});\n\nwatch(\n () => props.modelValue,\n (isOpen) => {\n if (isOpen) {\n loadAvailableStorages();\n } else {\n Object.assign(data, defaultData());\n }\n },\n { immediate: true },\n);\n\nuseEventListener(document, \"keydown\", (ev: KeyboardEvent) => {\n if (!props.modelValue) {\n return;\n }\n\n if (ev.target !== document.body) {\n return;\n }\n\n const ctrlOrMetaKey = isCtrlOrMeta(ev);\n\n if (ctrlOrMetaKey && ev.code === \"KeyA\") {\n ev.preventDefault();\n selectAll();\n }\n\n if (ctrlOrMetaKey && ev.shiftKey && ev.code === \"Period\") {\n ev.preventDefault();\n data.showHiddenItems = !data.showHiddenItems;\n }\n\n if (ev.code === \"Enter\") {\n props.submit();\n }\n});\n\ndefineExpose({\n isReady,\n getFilesToImport,\n});\n\nonMounted(loadAvailableStorages);\n\nconst lsContainerRef = ref<HTMLElement | undefined>();\n</script>\n\n<template>\n <div :class=\"style.remote\" @click.stop=\"deselectAll\">\n <div :class=\"style.search\">\n <div>\n <PlDropdown\n v-model=\"data.storageEntry\"\n label=\"Select storage\"\n :options=\"data.storageOptions\"\n />\n </div>\n <div>\n <PlSearchField v-model=\"data.search\" label=\"Search in folder\" clearable />\n </div>\n </div>\n <div :class=\"style['ls-container']\" ref=\"lsContainerRef\">\n <div :class=\"style['ls-head']\">\n <div :class=\"style['breadcrumbs']\">\n <template v-for=\"(s, i) in breadcrumbs\" :key=\"i\">\n <div :title=\"s.path\" @click=\"setDirPath(s.path)\">{{ s.name }}</div>\n <PlIcon16 v-if=\"s.index !== breadcrumbs.length - 1\" name=\"chevron-right\" />\n </template>\n </div>\n <div :class=\"style.selected\">\n <span>Selected: {{ selectedFiles.length }}</span>\n <Shortcuts :container=\"lsContainerRef\" />\n </div>\n </div>\n <div v-if=\"data.currentLoadingPath !== undefined\" class=\"ls-loader\">\n <i class=\"mask-24 mask-loading loader-icon\" />\n </div>\n <div v-else-if=\"!data.storageEntry\" :class=\"style['ls-empty']\">\n <div :class=\"style.cat\" />\n <div :class=\"style.message\">Select storage to preview</div>\n </div>\n <div v-else-if=\"data.error\" :class=\"style['ls-error']\">\n <div :class=\"style.cat\" />\n <div :class=\"style.message\">{{ data.error }}</div>\n </div>\n <div v-else :class=\"style['ls-body']\">\n <template v-for=\"file in visibleItems\" :key=\"file.id\">\n <div v-if=\"file.isDir\" :class=\"style.isDir\" @click=\"setDirPath(file.path)\">\n <PlIcon16 name=\"chevron-right\" />\n <span v-text-overflown :title=\"file.name\">{{ file.name }}</span>\n </div>\n <div\n v-else\n :class=\"{ [style.canBeSelected]: file.canBeSelected, [style.selected]: file.selected }\"\n @click.stop=\"(ev) => selectFile(ev, file)\"\n >\n <PlMaskIcon16 name=\"box\" :class=\"style.isFile\" />\n <span v-text-overflown :title=\"file.name\">{{ file.name }}</span>\n </div>\n </template>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/uikit",
3
- "version": "2.13.4",
3
+ "version": "2.14.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -32,7 +32,7 @@
32
32
  "sortablejs": "^1.15.6",
33
33
  "vue": "^3.5.24",
34
34
  "@milaboratories/helpers": "1.14.1",
35
- "@platforma-sdk/model": "1.73.0"
35
+ "@platforma-sdk/model": "1.74.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@vitest/coverage-istanbul": "^4.1.3",
@@ -40,8 +40,8 @@
40
40
  "svgo": "^3.3.2",
41
41
  "typescript": "~5.9.3",
42
42
  "vitest": "^4.1.3",
43
- "@milaboratories/ts-builder": "1.3.2",
44
43
  "@milaboratories/ts-configs": "1.2.3",
44
+ "@milaboratories/ts-builder": "1.4.0",
45
45
  "@milaboratories/build-configs": "2.0.0"
46
46
  },
47
47
  "scripts": {
@@ -199,7 +199,7 @@ const loadAvailableStorages = () => {
199
199
  .then((storageEntries) => {
200
200
  // local storage is always returned by the ML, so we need to remove it from remote dialog manually
201
201
  storageEntries = storageEntries.filter(
202
- (it) => it.name !== "local" && !it.name.startsWith("local_disk_"),
202
+ (it) => it.id !== "local" && !it.id.startsWith("local_disk_"),
203
203
  );
204
204
 
205
205
  data.storageOptions = storageEntries.map((it) => ({