@platforma-sdk/ui-vue 1.84.10 → 1.84.14
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 +68 -68
- package/.turbo/turbo-formatter$colon$check.log +2 -2
- package/.turbo/turbo-linter$colon$check.log +2 -2
- package/.turbo/turbo-types$colon$check.log +1 -1
- package/CHANGELOG.md +8 -0
- package/dist/components/BlockLayout.js.map +1 -1
- package/dist/components/BlockLayout.style.js.map +1 -1
- package/dist/components/BlockLayout.vue.d.ts.map +1 -1
- package/dist/components/BlockLayout.vue2.js +5 -1
- package/dist/components/BlockLayout.vue2.js.map +1 -1
- package/dist/components/BlockLoader.js.map +1 -1
- package/dist/components/BlockLoader.vue.d.ts.map +1 -1
- package/dist/components/BlockLoader.vue2.js +2 -0
- package/dist/components/BlockLoader.vue2.js.map +1 -1
- package/dist/components/LoaderPage.js +4 -1
- package/dist/components/LoaderPage.js.map +1 -1
- package/dist/components/LoaderPage.vue.d.ts.map +1 -1
- package/dist/components/NotFound.js.map +1 -1
- package/dist/components/NotFound.vue.d.ts.map +1 -1
- package/dist/components/NotFound.vue2.js +11 -5
- package/dist/components/NotFound.vue2.js.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.js.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.style.js.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.vue.d.ts.map +1 -1
- package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js +26 -2
- package/dist/components/PlAdvancedFilter/FilterEditor.vue2.js.map +1 -1
- package/dist/components/PlAdvancedFilter/OperandButton.js.map +1 -1
- package/dist/components/PlAdvancedFilter/OperandButton.style.js.map +1 -1
- package/dist/components/PlAdvancedFilter/OperandButton.vue.d.ts.map +1 -1
- package/dist/components/PlAdvancedFilter/OperandButton.vue2.js +2 -1
- package/dist/components/PlAdvancedFilter/OperandButton.vue2.js.map +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.js.map +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.style.js.map +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts.map +1 -1
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js +70 -61
- package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js.map +1 -1
- package/dist/components/PlAgCellFile/PlAgCellFile.js.map +1 -1
- package/dist/components/PlAgCellFile/PlAgCellFile.vue.d.ts.map +1 -1
- package/dist/components/PlAgCellFile/PlAgCellFile.vue2.js +5 -1
- package/dist/components/PlAgCellFile/PlAgCellFile.vue2.js.map +1 -1
- package/dist/components/PlAgCellProgress/PlAgCellProgress.js.map +1 -1
- package/dist/components/PlAgCellProgress/PlAgCellProgress.vue.d.ts.map +1 -1
- package/dist/components/PlAgCellProgress/PlAgCellProgress.vue2.js +6 -6
- package/dist/components/PlAgCellProgress/PlAgCellProgress.vue2.js.map +1 -1
- package/dist/components/PlAgCellStatusTag/PlAgCellStatusTag.js.map +1 -1
- package/dist/components/PlAgCellStatusTag/PlAgCellStatusTag.vue.d.ts.map +1 -1
- package/dist/components/PlAgCellStatusTag/PlAgCellStatusTag.vue2.js +8 -2
- package/dist/components/PlAgCellStatusTag/PlAgCellStatusTag.vue2.js.map +1 -1
- package/dist/components/PlAgChartHistogramCell/PlAgChartHistogramCell.js.map +1 -1
- package/dist/components/PlAgChartHistogramCell/PlAgChartHistogramCell.vue.d.ts.map +1 -1
- package/dist/components/PlAgChartHistogramCell/PlAgChartHistogramCell.vue2.js +4 -1
- package/dist/components/PlAgChartHistogramCell/PlAgChartHistogramCell.vue2.js.map +1 -1
- package/dist/components/PlAgChartStackedBarCell/PlAgChartStackedBarCell.js.map +1 -1
- package/dist/components/PlAgChartStackedBarCell/PlAgChartStackedBarCell.vue.d.ts.map +1 -1
- package/dist/components/PlAgChartStackedBarCell/PlAgChartStackedBarCell.vue2.js +7 -2
- package/dist/components/PlAgChartStackedBarCell/PlAgChartStackedBarCell.vue2.js.map +1 -1
- package/dist/components/PlAgColumnHeader/PlAgColumnHeader.js.map +1 -1
- package/dist/components/PlAgColumnHeader/PlAgColumnHeader.vue.d.ts.map +1 -1
- package/dist/components/PlAgColumnHeader/PlAgColumnHeader.vue2.js +28 -20
- package/dist/components/PlAgColumnHeader/PlAgColumnHeader.vue2.js.map +1 -1
- package/dist/components/PlAgCsvExporter/PlAgCsvExporter.js.map +1 -1
- package/dist/components/PlAgCsvExporter/PlAgCsvExporter.vue.d.ts.map +1 -1
- package/dist/components/PlAgCsvExporter/PlAgCsvExporter.vue2.js +1 -0
- package/dist/components/PlAgCsvExporter/PlAgCsvExporter.vue2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableSheets.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableSheets.style.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableSheets.vue.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableSheets.vue2.js +2 -0
- package/dist/components/PlAgDataTable/PlAgDataTableSheets.vue2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.style.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +5 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgOverlayLoading.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgOverlayLoading.vue.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgOverlayLoading.vue2.js +12 -2
- package/dist/components/PlAgDataTable/PlAgOverlayLoading.vue2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgOverlayNoRows.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgOverlayNoRows.vue.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgOverlayNoRows.vue2.js +7 -1
- package/dist/components/PlAgDataTable/PlAgOverlayNoRows.vue2.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.style.js.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue.d.ts.map +1 -1
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js +35 -27
- package/dist/components/PlAgGridColumnManager/PlAgGridColumnManager.vue2.js.map +1 -1
- package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.js.map +1 -1
- package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.d.ts.map +1 -1
- package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue2.js +12 -7
- package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue2.js.map +1 -1
- package/dist/components/PlAgRowNumHeader.js.map +1 -1
- package/dist/components/PlAgRowNumHeader.vue.d.ts.map +1 -1
- package/dist/components/PlAgRowNumHeader.vue2.js +14 -7
- package/dist/components/PlAgRowNumHeader.vue2.js.map +1 -1
- package/dist/components/PlAgTextAndButtonCell/PlAgTextAndButtonCell.js.map +1 -1
- package/dist/components/PlAgTextAndButtonCell/PlAgTextAndButtonCell.vue.d.ts.map +1 -1
- package/dist/components/PlAgTextAndButtonCell/PlAgTextAndButtonCell.vue2.js +8 -1
- package/dist/components/PlAgTextAndButtonCell/PlAgTextAndButtonCell.vue2.js.map +1 -1
- package/dist/components/PlAnnotations/components/AnnotationsSidebar.js.map +1 -1
- package/dist/components/PlAnnotations/components/AnnotationsSidebar.style.js.map +1 -1
- package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue.d.ts.map +1 -1
- package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js +14 -3
- package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js.map +1 -1
- package/dist/components/PlAnnotations/components/FilterSidebar.js.map +1 -1
- package/dist/components/PlAnnotations/components/FilterSidebar.style.js.map +1 -1
- package/dist/components/PlAnnotations/components/FilterSidebar.vue.d.ts.map +1 -1
- package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +11 -2
- package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotations.js.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotations.style.js.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotations.vue.d.ts.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotationsModal.js.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotationsModal.style.js.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue.d.ts.map +1 -1
- package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js +1 -0
- package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js.map +1 -1
- package/dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.js.map +1 -1
- package/dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue.d.ts.map +1 -1
- package/dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue2.js +16 -2
- package/dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue2.js.map +1 -1
- package/dist/components/PlBtnExportArchive/Item.js.map +1 -1
- package/dist/components/PlBtnExportArchive/Item.style.js.map +1 -1
- package/dist/components/PlBtnExportArchive/Item.vue.d.ts.map +1 -1
- package/dist/components/PlBtnExportArchive/Item.vue2.js +12 -2
- package/dist/components/PlBtnExportArchive/Item.vue2.js.map +1 -1
- package/dist/components/PlBtnExportArchive/PlBtnExportArchive.js.map +1 -1
- package/dist/components/PlBtnExportArchive/PlBtnExportArchive.style.js.map +1 -1
- package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue.d.ts.map +1 -1
- package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue2.js +7 -1
- package/dist/components/PlBtnExportArchive/PlBtnExportArchive.vue2.js.map +1 -1
- package/dist/components/PlBtnExportArchive/Summary.js.map +1 -1
- package/dist/components/PlBtnExportArchive/Summary.style.js.map +1 -1
- package/dist/components/PlBtnExportArchive/Summary.vue.d.ts.map +1 -1
- package/dist/components/PlBtnExportArchive/Summary.vue2.js +11 -2
- package/dist/components/PlBtnExportArchive/Summary.vue2.js.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.js.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js +1 -0
- package/dist/components/PlDatasetSelector/PlDatasetSelector.vue2.js.map +1 -1
- package/dist/components/PlTableFastSearch/PlTableFastSearch.js.map +1 -1
- package/dist/components/PlTableFastSearch/PlTableFastSearch.vue.d.ts.map +1 -1
- package/dist/components/PlTableFastSearch/PlTableFastSearch.vue2.js +1 -0
- package/dist/components/PlTableFastSearch/PlTableFastSearch.vue2.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.style.js.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue.d.ts.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js +12 -2
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js.map +1 -1
- package/package.json +5 -5
- package/src/components/BlockLayout.vue +4 -2
- package/src/components/BlockLoader.vue +2 -1
- package/src/components/LoaderPage.vue +1 -1
- package/src/components/NotFound.vue +7 -3
- package/src/components/PlAdvancedFilter/FilterEditor.vue +36 -6
- package/src/components/PlAdvancedFilter/OperandButton.vue +2 -1
- package/src/components/PlAdvancedFilter/PlAdvancedFilter.vue +20 -4
- package/src/components/PlAgCellFile/PlAgCellFile.vue +2 -1
- package/src/components/PlAgCellProgress/PlAgCellProgress.vue +1 -1
- package/src/components/PlAgCellStatusTag/PlAgCellStatusTag.vue +2 -2
- package/src/components/PlAgChartHistogramCell/PlAgChartHistogramCell.vue +13 -3
- package/src/components/PlAgChartStackedBarCell/PlAgChartStackedBarCell.vue +13 -3
- package/src/components/PlAgColumnHeader/PlAgColumnHeader.vue +24 -6
- package/src/components/PlAgCsvExporter/PlAgCsvExporter.vue +6 -1
- package/src/components/PlAgDataTable/PlAgDataTableSheets.vue +6 -1
- package/src/components/PlAgDataTable/PlAgDataTableV2.vue +2 -1
- package/src/components/PlAgDataTable/PlAgOverlayLoading.vue +10 -3
- package/src/components/PlAgDataTable/PlAgOverlayNoRows.vue +4 -2
- package/src/components/PlAgGridColumnManager/PlAgGridColumnManager.vue +18 -5
- package/src/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue +5 -1
- package/src/components/PlAgRowNumHeader.vue +3 -1
- package/src/components/PlAgTextAndButtonCell/PlAgTextAndButtonCell.vue +3 -2
- package/src/components/PlAnnotations/components/AnnotationsSidebar.vue +13 -4
- package/src/components/PlAnnotations/components/FilterSidebar.vue +11 -3
- package/src/components/PlAnnotations/components/PlAnnotations.vue +1 -1
- package/src/components/PlAnnotations/components/PlAnnotationsModal.vue +1 -0
- package/src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue +34 -7
- package/src/components/PlBtnExportArchive/Item.vue +22 -6
- package/src/components/PlBtnExportArchive/PlBtnExportArchive.vue +18 -3
- package/src/components/PlBtnExportArchive/Summary.vue +15 -5
- package/src/components/PlDatasetSelector/PlDatasetSelector.vue +1 -0
- package/src/components/PlTableFastSearch/PlTableFastSearch.vue +6 -1
- package/src/components/PlTableFilters/PlTableFiltersV2.vue +14 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterSidebar.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/FilterSidebar.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type Props = {\n columns: PlAdvancedFilterItem[];\n\n getSuggestOptions: (params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchStr: string;\n searchType: \"value\" | \"label\";\n }) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;\n\n hasSelectedColumns?: boolean;\n getValuesForSelectedColumns?: () => Promise<\n undefined | { columnId: PObjectId; values: string[] }\n >;\n};\n</script>\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { produce } from \"immer\";\nimport { randomInt } from \"@milaboratories/helpers\";\nimport { PlBtnSecondary, PlEditableTitle, PlSidebarItem } from \"@milaboratories/uikit\";\nimport type { ListOptionBase, PObjectId, SUniversalPColumnId } from \"@platforma-sdk/model\";\n\nimport { PlAdvancedFilterComponent } from \"../../PlAdvancedFilter\";\nimport type {\n PlAdvancedFilterItem,\n PlAdvancedFilterColumnId,\n PlAdvancedFilterSupportedFilters,\n PlAdvancedFilter,\n} from \"../../PlAdvancedFilter\";\nimport type { Filter } from \"../types\";\nimport { validateTitle } from \"../utils\";\n\nimport $commonStyle from \"./style.module.css\";\n\nconst props = defineProps<\n Props & {\n step: Filter;\n onUpdateStep: (step: Filter) => void;\n }\n>();\n\nconst withSelection = computed(() => {\n return props.hasSelectedColumns !== undefined && props.getValuesForSelectedColumns !== undefined;\n});\n\nfunction produceStepUpdate(updater: (draft: Filter) => void) {\n props.onUpdateStep(produce(props.step, updater));\n}\n\nfunction updateLabel(label: string | undefined) {\n produceStepUpdate((draft) => {\n draft.label = label ?? \"\";\n });\n}\n\nfunction updateFilter(filter: PlAdvancedFilter) {\n produceStepUpdate((draft) => {\n draft.filter = filter as typeof draft.filter;\n });\n}\n\nfunction addFilterPlaceholder() {\n if (props.columns.length === 0) return;\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n isExpanded: true,\n type: \"or\",\n filters: [\n {\n id: randomInt(),\n type: \"isNA\",\n column: props.columns[0].id as SUniversalPColumnId,\n },\n ],\n });\n });\n}\n\nasync function addFilterFromSelected() {\n if (props.hasSelectedColumns === undefined || props.getValuesForSelectedColumns === undefined)\n return;\n\n const data = await props.getValuesForSelectedColumns();\n if (!data || data.values.length === 0) return;\n\n const { columnId, values } = data;\n const shortReminder =\n values.slice(0, 3).join(\", \") + (values.length > 3 ? ` and ${values.length - 3} more` : \"\");\n\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n name: `Selected list (${shortReminder})`,\n isExpanded: false,\n type: \"or\",\n filters: values.map((value, i) => ({\n id: i,\n type: \"patternEquals\",\n column: columnId as SUniversalPColumnId,\n value,\n })),\n });\n });\n}\n\nconst supportedFilters = [\n \"isNA\",\n \"isNotNA\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"patternEquals\",\n \"patternNotEquals\",\n \"patternContainSubsequence\",\n \"patternNotContainSubsequence\",\n \"equal\",\n \"notEqual\",\n \"topN\",\n \"bottomN\",\n] as (typeof PlAdvancedFilterSupportedFilters)[number][];\n</script>\n\n<template>\n <PlSidebarItem v-if=\"props.step\">\n <template #header-content>\n <PlEditableTitle\n :key=\"props.step.id\"\n :model-value=\"props.step.label\"\n :class=\"{ [$commonStyle.flashing]: props.step.label.length === 0 }\"\n :max-length=\"40\"\n max-width=\"600px\"\n placeholder=\"Label\"\n :autofocus=\"props.step.label.length === 0\"\n :validate=\"validateTitle\"\n @update:model-value=\"updateLabel\"\n />\n </template>\n <template #body-content>\n <PlAdvancedFilterComponent\n :class=\"[$style.root, { [$commonStyle.disabled]: props.step.label.length === 0 }]\"\n :options=\"props.columns\"\n :filters=\"props.step.filter as PlAdvancedFilter\"\n :on-update-filters=\"updateFilter\"\n :supported-filters=\"supportedFilters\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :enable-dnd=\"false\"\n :enable-add-group-button=\"true\"\n >\n <template #add-group-buttons>\n <div :class=\"$style.actions\">\n <PlBtnSecondary
|
|
1
|
+
{"version":3,"file":"FilterSidebar.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/FilterSidebar.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type Props = {\n columns: PlAdvancedFilterItem[];\n\n getSuggestOptions: (params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchStr: string;\n searchType: \"value\" | \"label\";\n }) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;\n\n hasSelectedColumns?: boolean;\n getValuesForSelectedColumns?: () => Promise<\n undefined | { columnId: PObjectId; values: string[] }\n >;\n};\n</script>\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { produce } from \"immer\";\nimport { randomInt } from \"@milaboratories/helpers\";\nimport { PlBtnSecondary, PlEditableTitle, PlSidebarItem } from \"@milaboratories/uikit\";\nimport type { ListOptionBase, PObjectId, SUniversalPColumnId } from \"@platforma-sdk/model\";\n\nimport { PlAdvancedFilterComponent } from \"../../PlAdvancedFilter\";\nimport type {\n PlAdvancedFilterItem,\n PlAdvancedFilterColumnId,\n PlAdvancedFilterSupportedFilters,\n PlAdvancedFilter,\n} from \"../../PlAdvancedFilter\";\nimport type { Filter } from \"../types\";\nimport { validateTitle } from \"../utils\";\n\nimport $commonStyle from \"./style.module.css\";\n\nconst props = defineProps<\n Props & {\n step: Filter;\n onUpdateStep: (step: Filter) => void;\n }\n>();\n\nconst withSelection = computed(() => {\n return props.hasSelectedColumns !== undefined && props.getValuesForSelectedColumns !== undefined;\n});\n\nfunction produceStepUpdate(updater: (draft: Filter) => void) {\n props.onUpdateStep(produce(props.step, updater));\n}\n\nfunction updateLabel(label: string | undefined) {\n produceStepUpdate((draft) => {\n draft.label = label ?? \"\";\n });\n}\n\nfunction updateFilter(filter: PlAdvancedFilter) {\n produceStepUpdate((draft) => {\n draft.filter = filter as typeof draft.filter;\n });\n}\n\nfunction addFilterPlaceholder() {\n if (props.columns.length === 0) return;\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n isExpanded: true,\n type: \"or\",\n filters: [\n {\n id: randomInt(),\n type: \"isNA\",\n column: props.columns[0].id as SUniversalPColumnId,\n },\n ],\n });\n });\n}\n\nasync function addFilterFromSelected() {\n if (props.hasSelectedColumns === undefined || props.getValuesForSelectedColumns === undefined)\n return;\n\n const data = await props.getValuesForSelectedColumns();\n if (!data || data.values.length === 0) return;\n\n const { columnId, values } = data;\n const shortReminder =\n values.slice(0, 3).join(\", \") + (values.length > 3 ? ` and ${values.length - 3} more` : \"\");\n\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n name: `Selected list (${shortReminder})`,\n isExpanded: false,\n type: \"or\",\n filters: values.map((value, i) => ({\n id: i,\n type: \"patternEquals\",\n column: columnId as SUniversalPColumnId,\n value,\n })),\n });\n });\n}\n\nconst supportedFilters = [\n \"isNA\",\n \"isNotNA\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"patternEquals\",\n \"patternNotEquals\",\n \"patternContainSubsequence\",\n \"patternNotContainSubsequence\",\n \"equal\",\n \"notEqual\",\n \"topN\",\n \"bottomN\",\n] as (typeof PlAdvancedFilterSupportedFilters)[number][];\n</script>\n\n<template>\n <PlSidebarItem v-if=\"props.step\" data-testid=\"pl-annotations-step\">\n <template #header-content>\n <PlEditableTitle\n :key=\"props.step.id\"\n data-testid=\"pl-annotations-step-label\"\n :model-value=\"props.step.label\"\n :class=\"{ [$commonStyle.flashing]: props.step.label.length === 0 }\"\n :max-length=\"40\"\n max-width=\"600px\"\n placeholder=\"Label\"\n :autofocus=\"props.step.label.length === 0\"\n :validate=\"validateTitle\"\n @update:model-value=\"updateLabel\"\n />\n </template>\n <template #body-content>\n <PlAdvancedFilterComponent\n :class=\"[$style.root, { [$commonStyle.disabled]: props.step.label.length === 0 }]\"\n :options=\"props.columns\"\n :filters=\"props.step.filter as PlAdvancedFilter\"\n :on-update-filters=\"updateFilter\"\n :supported-filters=\"supportedFilters\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :enable-dnd=\"false\"\n :enable-add-group-button=\"true\"\n >\n <template #add-group-buttons>\n <div data-testid=\"pl-annotations-filter-actions\" :class=\"$style.actions\">\n <PlBtnSecondary\n data-testid=\"pl-annotations-add-filter\"\n icon=\"add\"\n @click=\"addFilterPlaceholder\"\n >\n Add Filter\n </PlBtnSecondary>\n <PlBtnSecondary\n v-if=\"withSelection\"\n data-testid=\"pl-annotations-add-from-selection\"\n icon=\"add\"\n :disabled=\"props.hasSelectedColumns !== true\"\n @click=\"addFilterFromSelected\"\n >\n From selection\n </PlBtnSecondary>\n </div>\n </template>\n </PlAdvancedFilterComponent>\n </template>\n </PlSidebarItem>\n</template>\n\n<style module>\n.root {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.actions {\n display: flex;\n flex-direction: row;\n gap: 12px;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterSidebar.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/FilterSidebar.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type Props = {\n columns: PlAdvancedFilterItem[];\n\n getSuggestOptions: (params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchStr: string;\n searchType: \"value\" | \"label\";\n }) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;\n\n hasSelectedColumns?: boolean;\n getValuesForSelectedColumns?: () => Promise<\n undefined | { columnId: PObjectId; values: string[] }\n >;\n};\n</script>\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { produce } from \"immer\";\nimport { randomInt } from \"@milaboratories/helpers\";\nimport { PlBtnSecondary, PlEditableTitle, PlSidebarItem } from \"@milaboratories/uikit\";\nimport type { ListOptionBase, PObjectId, SUniversalPColumnId } from \"@platforma-sdk/model\";\n\nimport { PlAdvancedFilterComponent } from \"../../PlAdvancedFilter\";\nimport type {\n PlAdvancedFilterItem,\n PlAdvancedFilterColumnId,\n PlAdvancedFilterSupportedFilters,\n PlAdvancedFilter,\n} from \"../../PlAdvancedFilter\";\nimport type { Filter } from \"../types\";\nimport { validateTitle } from \"../utils\";\n\nimport $commonStyle from \"./style.module.css\";\n\nconst props = defineProps<\n Props & {\n step: Filter;\n onUpdateStep: (step: Filter) => void;\n }\n>();\n\nconst withSelection = computed(() => {\n return props.hasSelectedColumns !== undefined && props.getValuesForSelectedColumns !== undefined;\n});\n\nfunction produceStepUpdate(updater: (draft: Filter) => void) {\n props.onUpdateStep(produce(props.step, updater));\n}\n\nfunction updateLabel(label: string | undefined) {\n produceStepUpdate((draft) => {\n draft.label = label ?? \"\";\n });\n}\n\nfunction updateFilter(filter: PlAdvancedFilter) {\n produceStepUpdate((draft) => {\n draft.filter = filter as typeof draft.filter;\n });\n}\n\nfunction addFilterPlaceholder() {\n if (props.columns.length === 0) return;\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n isExpanded: true,\n type: \"or\",\n filters: [\n {\n id: randomInt(),\n type: \"isNA\",\n column: props.columns[0].id as SUniversalPColumnId,\n },\n ],\n });\n });\n}\n\nasync function addFilterFromSelected() {\n if (props.hasSelectedColumns === undefined || props.getValuesForSelectedColumns === undefined)\n return;\n\n const data = await props.getValuesForSelectedColumns();\n if (!data || data.values.length === 0) return;\n\n const { columnId, values } = data;\n const shortReminder =\n values.slice(0, 3).join(\", \") + (values.length > 3 ? ` and ${values.length - 3} more` : \"\");\n\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n name: `Selected list (${shortReminder})`,\n isExpanded: false,\n type: \"or\",\n filters: values.map((value, i) => ({\n id: i,\n type: \"patternEquals\",\n column: columnId as SUniversalPColumnId,\n value,\n })),\n });\n });\n}\n\nconst supportedFilters = [\n \"isNA\",\n \"isNotNA\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"patternEquals\",\n \"patternNotEquals\",\n \"patternContainSubsequence\",\n \"patternNotContainSubsequence\",\n \"equal\",\n \"notEqual\",\n \"topN\",\n \"bottomN\",\n] as (typeof PlAdvancedFilterSupportedFilters)[number][];\n</script>\n\n<template>\n <PlSidebarItem v-if=\"props.step\">\n <template #header-content>\n <PlEditableTitle\n :key=\"props.step.id\"\n :model-value=\"props.step.label\"\n :class=\"{ [$commonStyle.flashing]: props.step.label.length === 0 }\"\n :max-length=\"40\"\n max-width=\"600px\"\n placeholder=\"Label\"\n :autofocus=\"props.step.label.length === 0\"\n :validate=\"validateTitle\"\n @update:model-value=\"updateLabel\"\n />\n </template>\n <template #body-content>\n <PlAdvancedFilterComponent\n :class=\"[$style.root, { [$commonStyle.disabled]: props.step.label.length === 0 }]\"\n :options=\"props.columns\"\n :filters=\"props.step.filter as PlAdvancedFilter\"\n :on-update-filters=\"updateFilter\"\n :supported-filters=\"supportedFilters\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :enable-dnd=\"false\"\n :enable-add-group-button=\"true\"\n >\n <template #add-group-buttons>\n <div :class=\"$style.actions\">\n <PlBtnSecondary
|
|
1
|
+
{"version":3,"file":"FilterSidebar.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/FilterSidebar.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type Props = {\n columns: PlAdvancedFilterItem[];\n\n getSuggestOptions: (params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchStr: string;\n searchType: \"value\" | \"label\";\n }) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;\n\n hasSelectedColumns?: boolean;\n getValuesForSelectedColumns?: () => Promise<\n undefined | { columnId: PObjectId; values: string[] }\n >;\n};\n</script>\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { produce } from \"immer\";\nimport { randomInt } from \"@milaboratories/helpers\";\nimport { PlBtnSecondary, PlEditableTitle, PlSidebarItem } from \"@milaboratories/uikit\";\nimport type { ListOptionBase, PObjectId, SUniversalPColumnId } from \"@platforma-sdk/model\";\n\nimport { PlAdvancedFilterComponent } from \"../../PlAdvancedFilter\";\nimport type {\n PlAdvancedFilterItem,\n PlAdvancedFilterColumnId,\n PlAdvancedFilterSupportedFilters,\n PlAdvancedFilter,\n} from \"../../PlAdvancedFilter\";\nimport type { Filter } from \"../types\";\nimport { validateTitle } from \"../utils\";\n\nimport $commonStyle from \"./style.module.css\";\n\nconst props = defineProps<\n Props & {\n step: Filter;\n onUpdateStep: (step: Filter) => void;\n }\n>();\n\nconst withSelection = computed(() => {\n return props.hasSelectedColumns !== undefined && props.getValuesForSelectedColumns !== undefined;\n});\n\nfunction produceStepUpdate(updater: (draft: Filter) => void) {\n props.onUpdateStep(produce(props.step, updater));\n}\n\nfunction updateLabel(label: string | undefined) {\n produceStepUpdate((draft) => {\n draft.label = label ?? \"\";\n });\n}\n\nfunction updateFilter(filter: PlAdvancedFilter) {\n produceStepUpdate((draft) => {\n draft.filter = filter as typeof draft.filter;\n });\n}\n\nfunction addFilterPlaceholder() {\n if (props.columns.length === 0) return;\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n isExpanded: true,\n type: \"or\",\n filters: [\n {\n id: randomInt(),\n type: \"isNA\",\n column: props.columns[0].id as SUniversalPColumnId,\n },\n ],\n });\n });\n}\n\nasync function addFilterFromSelected() {\n if (props.hasSelectedColumns === undefined || props.getValuesForSelectedColumns === undefined)\n return;\n\n const data = await props.getValuesForSelectedColumns();\n if (!data || data.values.length === 0) return;\n\n const { columnId, values } = data;\n const shortReminder =\n values.slice(0, 3).join(\", \") + (values.length > 3 ? ` and ${values.length - 3} more` : \"\");\n\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n name: `Selected list (${shortReminder})`,\n isExpanded: false,\n type: \"or\",\n filters: values.map((value, i) => ({\n id: i,\n type: \"patternEquals\",\n column: columnId as SUniversalPColumnId,\n value,\n })),\n });\n });\n}\n\nconst supportedFilters = [\n \"isNA\",\n \"isNotNA\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"patternEquals\",\n \"patternNotEquals\",\n \"patternContainSubsequence\",\n \"patternNotContainSubsequence\",\n \"equal\",\n \"notEqual\",\n \"topN\",\n \"bottomN\",\n] as (typeof PlAdvancedFilterSupportedFilters)[number][];\n</script>\n\n<template>\n <PlSidebarItem v-if=\"props.step\" data-testid=\"pl-annotations-step\">\n <template #header-content>\n <PlEditableTitle\n :key=\"props.step.id\"\n data-testid=\"pl-annotations-step-label\"\n :model-value=\"props.step.label\"\n :class=\"{ [$commonStyle.flashing]: props.step.label.length === 0 }\"\n :max-length=\"40\"\n max-width=\"600px\"\n placeholder=\"Label\"\n :autofocus=\"props.step.label.length === 0\"\n :validate=\"validateTitle\"\n @update:model-value=\"updateLabel\"\n />\n </template>\n <template #body-content>\n <PlAdvancedFilterComponent\n :class=\"[$style.root, { [$commonStyle.disabled]: props.step.label.length === 0 }]\"\n :options=\"props.columns\"\n :filters=\"props.step.filter as PlAdvancedFilter\"\n :on-update-filters=\"updateFilter\"\n :supported-filters=\"supportedFilters\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :enable-dnd=\"false\"\n :enable-add-group-button=\"true\"\n >\n <template #add-group-buttons>\n <div data-testid=\"pl-annotations-filter-actions\" :class=\"$style.actions\">\n <PlBtnSecondary\n data-testid=\"pl-annotations-add-filter\"\n icon=\"add\"\n @click=\"addFilterPlaceholder\"\n >\n Add Filter\n </PlBtnSecondary>\n <PlBtnSecondary\n v-if=\"withSelection\"\n data-testid=\"pl-annotations-add-from-selection\"\n icon=\"add\"\n :disabled=\"props.hasSelectedColumns !== true\"\n @click=\"addFilterFromSelected\"\n >\n From selection\n </PlBtnSecondary>\n </div>\n </template>\n </PlAdvancedFilterComponent>\n </template>\n </PlSidebarItem>\n</template>\n\n<style module>\n.root {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.actions {\n display: flex;\n flex-direction: row;\n gap: 12px;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterSidebar.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAnnotations/components/FilterSidebar.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FilterSidebar.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAnnotations/components/FilterSidebar.vue"],"names":[],"mappings":"AAsMA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAuB,MAAM,sBAAsB,CAAC;AAG3F,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EAGzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,MAAM,KAAK,GAAG;IAClB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAEhC,iBAAiB,EAAE,CAAC,MAAM,EAAE;QAC1B,QAAQ,EAAE,wBAAwB,CAAC;QACnC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC;KAC/B,KAAK,cAAc,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAErF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,OAAO,CACzC,SAAS,GAAG;QAAE,QAAQ,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CACtD,CAAC;CACH,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;UAER,MAAM;kBACE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;;UAD9B,MAAM;kBACE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;iGAwRpC,CAAC"}
|
|
@@ -83,9 +83,13 @@ var y = /* @__PURE__ */ d({
|
|
|
83
83
|
"topN",
|
|
84
84
|
"bottomN"
|
|
85
85
|
];
|
|
86
|
-
return (e, i) => y.step ? (p(), o(m(v), {
|
|
86
|
+
return (e, i) => y.step ? (p(), o(m(v), {
|
|
87
|
+
key: 0,
|
|
88
|
+
"data-testid": "pl-annotations-step"
|
|
89
|
+
}, {
|
|
87
90
|
"header-content": h(() => [(p(), o(m(_), {
|
|
88
91
|
key: y.step.id,
|
|
92
|
+
"data-testid": "pl-annotations-step-label",
|
|
89
93
|
"model-value": y.step.label,
|
|
90
94
|
class: f({ [m(n).flashing]: y.step.label.length === 0 }),
|
|
91
95
|
"max-length": 40,
|
|
@@ -110,7 +114,11 @@ var y = /* @__PURE__ */ d({
|
|
|
110
114
|
"enable-dnd": !1,
|
|
111
115
|
"enable-add-group-button": !0
|
|
112
116
|
}, {
|
|
113
|
-
"add-group-buttons": h(() => [c("div", {
|
|
117
|
+
"add-group-buttons": h(() => [c("div", {
|
|
118
|
+
"data-testid": "pl-annotations-filter-actions",
|
|
119
|
+
class: f(e.$style.actions)
|
|
120
|
+
}, [u(m(g), {
|
|
121
|
+
"data-testid": "pl-annotations-add-filter",
|
|
114
122
|
icon: "add",
|
|
115
123
|
onClick: w
|
|
116
124
|
}, {
|
|
@@ -118,6 +126,7 @@ var y = /* @__PURE__ */ d({
|
|
|
118
126
|
_: 1
|
|
119
127
|
}), b.value ? (p(), o(m(g), {
|
|
120
128
|
key: 0,
|
|
129
|
+
"data-testid": "pl-annotations-add-from-selection",
|
|
121
130
|
icon: "add",
|
|
122
131
|
disabled: y.hasSelectedColumns !== !0,
|
|
123
132
|
onClick: T
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterSidebar.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../../src/components/PlAnnotations/components/FilterSidebar.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type Props = {\n columns: PlAdvancedFilterItem[];\n\n getSuggestOptions: (params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchStr: string;\n searchType: \"value\" | \"label\";\n }) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;\n\n hasSelectedColumns?: boolean;\n getValuesForSelectedColumns?: () => Promise<\n undefined | { columnId: PObjectId; values: string[] }\n >;\n};\n</script>\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { produce } from \"immer\";\nimport { randomInt } from \"@milaboratories/helpers\";\nimport { PlBtnSecondary, PlEditableTitle, PlSidebarItem } from \"@milaboratories/uikit\";\nimport type { ListOptionBase, PObjectId, SUniversalPColumnId } from \"@platforma-sdk/model\";\n\nimport { PlAdvancedFilterComponent } from \"../../PlAdvancedFilter\";\nimport type {\n PlAdvancedFilterItem,\n PlAdvancedFilterColumnId,\n PlAdvancedFilterSupportedFilters,\n PlAdvancedFilter,\n} from \"../../PlAdvancedFilter\";\nimport type { Filter } from \"../types\";\nimport { validateTitle } from \"../utils\";\n\nimport $commonStyle from \"./style.module.css\";\n\nconst props = defineProps<\n Props & {\n step: Filter;\n onUpdateStep: (step: Filter) => void;\n }\n>();\n\nconst withSelection = computed(() => {\n return props.hasSelectedColumns !== undefined && props.getValuesForSelectedColumns !== undefined;\n});\n\nfunction produceStepUpdate(updater: (draft: Filter) => void) {\n props.onUpdateStep(produce(props.step, updater));\n}\n\nfunction updateLabel(label: string | undefined) {\n produceStepUpdate((draft) => {\n draft.label = label ?? \"\";\n });\n}\n\nfunction updateFilter(filter: PlAdvancedFilter) {\n produceStepUpdate((draft) => {\n draft.filter = filter as typeof draft.filter;\n });\n}\n\nfunction addFilterPlaceholder() {\n if (props.columns.length === 0) return;\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n isExpanded: true,\n type: \"or\",\n filters: [\n {\n id: randomInt(),\n type: \"isNA\",\n column: props.columns[0].id as SUniversalPColumnId,\n },\n ],\n });\n });\n}\n\nasync function addFilterFromSelected() {\n if (props.hasSelectedColumns === undefined || props.getValuesForSelectedColumns === undefined)\n return;\n\n const data = await props.getValuesForSelectedColumns();\n if (!data || data.values.length === 0) return;\n\n const { columnId, values } = data;\n const shortReminder =\n values.slice(0, 3).join(\", \") + (values.length > 3 ? ` and ${values.length - 3} more` : \"\");\n\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n name: `Selected list (${shortReminder})`,\n isExpanded: false,\n type: \"or\",\n filters: values.map((value, i) => ({\n id: i,\n type: \"patternEquals\",\n column: columnId as SUniversalPColumnId,\n value,\n })),\n });\n });\n}\n\nconst supportedFilters = [\n \"isNA\",\n \"isNotNA\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"patternEquals\",\n \"patternNotEquals\",\n \"patternContainSubsequence\",\n \"patternNotContainSubsequence\",\n \"equal\",\n \"notEqual\",\n \"topN\",\n \"bottomN\",\n] as (typeof PlAdvancedFilterSupportedFilters)[number][];\n</script>\n\n<template>\n <PlSidebarItem v-if=\"props.step\">\n <template #header-content>\n <PlEditableTitle\n :key=\"props.step.id\"\n :model-value=\"props.step.label\"\n :class=\"{ [$commonStyle.flashing]: props.step.label.length === 0 }\"\n :max-length=\"40\"\n max-width=\"600px\"\n placeholder=\"Label\"\n :autofocus=\"props.step.label.length === 0\"\n :validate=\"validateTitle\"\n @update:model-value=\"updateLabel\"\n />\n </template>\n <template #body-content>\n <PlAdvancedFilterComponent\n :class=\"[$style.root, { [$commonStyle.disabled]: props.step.label.length === 0 }]\"\n :options=\"props.columns\"\n :filters=\"props.step.filter as PlAdvancedFilter\"\n :on-update-filters=\"updateFilter\"\n :supported-filters=\"supportedFilters\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :enable-dnd=\"false\"\n :enable-add-group-button=\"true\"\n >\n <template #add-group-buttons>\n <div :class=\"$style.actions\">\n <PlBtnSecondary
|
|
1
|
+
{"version":3,"file":"FilterSidebar.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../../src/components/PlAnnotations/components/FilterSidebar.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type Props = {\n columns: PlAdvancedFilterItem[];\n\n getSuggestOptions: (params: {\n columnId: PlAdvancedFilterColumnId;\n axisIdx?: number;\n searchStr: string;\n searchType: \"value\" | \"label\";\n }) => ListOptionBase<string | number>[] | Promise<ListOptionBase<string | number>[]>;\n\n hasSelectedColumns?: boolean;\n getValuesForSelectedColumns?: () => Promise<\n undefined | { columnId: PObjectId; values: string[] }\n >;\n};\n</script>\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { produce } from \"immer\";\nimport { randomInt } from \"@milaboratories/helpers\";\nimport { PlBtnSecondary, PlEditableTitle, PlSidebarItem } from \"@milaboratories/uikit\";\nimport type { ListOptionBase, PObjectId, SUniversalPColumnId } from \"@platforma-sdk/model\";\n\nimport { PlAdvancedFilterComponent } from \"../../PlAdvancedFilter\";\nimport type {\n PlAdvancedFilterItem,\n PlAdvancedFilterColumnId,\n PlAdvancedFilterSupportedFilters,\n PlAdvancedFilter,\n} from \"../../PlAdvancedFilter\";\nimport type { Filter } from \"../types\";\nimport { validateTitle } from \"../utils\";\n\nimport $commonStyle from \"./style.module.css\";\n\nconst props = defineProps<\n Props & {\n step: Filter;\n onUpdateStep: (step: Filter) => void;\n }\n>();\n\nconst withSelection = computed(() => {\n return props.hasSelectedColumns !== undefined && props.getValuesForSelectedColumns !== undefined;\n});\n\nfunction produceStepUpdate(updater: (draft: Filter) => void) {\n props.onUpdateStep(produce(props.step, updater));\n}\n\nfunction updateLabel(label: string | undefined) {\n produceStepUpdate((draft) => {\n draft.label = label ?? \"\";\n });\n}\n\nfunction updateFilter(filter: PlAdvancedFilter) {\n produceStepUpdate((draft) => {\n draft.filter = filter as typeof draft.filter;\n });\n}\n\nfunction addFilterPlaceholder() {\n if (props.columns.length === 0) return;\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n isExpanded: true,\n type: \"or\",\n filters: [\n {\n id: randomInt(),\n type: \"isNA\",\n column: props.columns[0].id as SUniversalPColumnId,\n },\n ],\n });\n });\n}\n\nasync function addFilterFromSelected() {\n if (props.hasSelectedColumns === undefined || props.getValuesForSelectedColumns === undefined)\n return;\n\n const data = await props.getValuesForSelectedColumns();\n if (!data || data.values.length === 0) return;\n\n const { columnId, values } = data;\n const shortReminder =\n values.slice(0, 3).join(\", \") + (values.length > 3 ? ` and ${values.length - 3} more` : \"\");\n\n produceStepUpdate((draft) => {\n draft.filter.filters.push({\n id: randomInt(),\n name: `Selected list (${shortReminder})`,\n isExpanded: false,\n type: \"or\",\n filters: values.map((value, i) => ({\n id: i,\n type: \"patternEquals\",\n column: columnId as SUniversalPColumnId,\n value,\n })),\n });\n });\n}\n\nconst supportedFilters = [\n \"isNA\",\n \"isNotNA\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"patternEquals\",\n \"patternNotEquals\",\n \"patternContainSubsequence\",\n \"patternNotContainSubsequence\",\n \"equal\",\n \"notEqual\",\n \"topN\",\n \"bottomN\",\n] as (typeof PlAdvancedFilterSupportedFilters)[number][];\n</script>\n\n<template>\n <PlSidebarItem v-if=\"props.step\" data-testid=\"pl-annotations-step\">\n <template #header-content>\n <PlEditableTitle\n :key=\"props.step.id\"\n data-testid=\"pl-annotations-step-label\"\n :model-value=\"props.step.label\"\n :class=\"{ [$commonStyle.flashing]: props.step.label.length === 0 }\"\n :max-length=\"40\"\n max-width=\"600px\"\n placeholder=\"Label\"\n :autofocus=\"props.step.label.length === 0\"\n :validate=\"validateTitle\"\n @update:model-value=\"updateLabel\"\n />\n </template>\n <template #body-content>\n <PlAdvancedFilterComponent\n :class=\"[$style.root, { [$commonStyle.disabled]: props.step.label.length === 0 }]\"\n :options=\"props.columns\"\n :filters=\"props.step.filter as PlAdvancedFilter\"\n :on-update-filters=\"updateFilter\"\n :supported-filters=\"supportedFilters\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :enable-dnd=\"false\"\n :enable-add-group-button=\"true\"\n >\n <template #add-group-buttons>\n <div data-testid=\"pl-annotations-filter-actions\" :class=\"$style.actions\">\n <PlBtnSecondary\n data-testid=\"pl-annotations-add-filter\"\n icon=\"add\"\n @click=\"addFilterPlaceholder\"\n >\n Add Filter\n </PlBtnSecondary>\n <PlBtnSecondary\n v-if=\"withSelection\"\n data-testid=\"pl-annotations-add-from-selection\"\n icon=\"add\"\n :disabled=\"props.hasSelectedColumns !== true\"\n @click=\"addFilterFromSelected\"\n >\n From selection\n </PlBtnSecondary>\n </div>\n </template>\n </PlAdvancedFilterComponent>\n </template>\n </PlSidebarItem>\n</template>\n\n<style module>\n.root {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.actions {\n display: flex;\n flex-direction: row;\n gap: 12px;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAoCA,IAAM,IAAQ,GAOR,IAAgB,QACb,EAAM,uBAAuB,KAAA,KAAa,EAAM,gCAAgC,KAAA,EACvF;EAEF,SAAS,EAAkB,GAAkC;AAC3D,KAAM,aAAa,EAAQ,EAAM,MAAM,EAAQ,CAAC;;EAGlD,SAAS,EAAY,GAA2B;AAC9C,MAAmB,MAAU;AAC3B,MAAM,QAAQ,KAAS;KACvB;;EAGJ,SAAS,EAAa,GAA0B;AAC9C,MAAmB,MAAU;AAC3B,MAAM,SAAS;KACf;;EAGJ,SAAS,IAAuB;AAC1B,KAAM,QAAQ,WAAW,KAC7B,GAAmB,MAAU;AAC3B,MAAM,OAAO,QAAQ,KAAK;KACxB,IAAI,GAAW;KACf,YAAY;KACZ,MAAM;KACN,SAAS,CACP;MACE,IAAI,GAAW;MACf,MAAM;MACN,QAAQ,EAAM,QAAQ,GAAG;MAC1B,CACF;KACF,CAAC;KACF;;EAGJ,eAAe,IAAwB;AACrC,OAAI,EAAM,uBAAuB,KAAA,KAAa,EAAM,gCAAgC,KAAA,EAClF;GAEF,IAAM,IAAO,MAAM,EAAM,6BAA6B;AACtD,OAAI,CAAC,KAAQ,EAAK,OAAO,WAAW,EAAG;GAEvC,IAAM,EAAE,aAAU,cAAW,GACvB,IACJ,EAAO,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,IAAI,EAAO,SAAS,IAAI,QAAQ,EAAO,SAAS,EAAE,SAAS;AAE1F,MAAmB,MAAU;AAC3B,MAAM,OAAO,QAAQ,KAAK;KACxB,IAAI,GAAW;KACf,MAAM,kBAAkB,EAAc;KACtC,YAAY;KACZ,MAAM;KACN,SAAS,EAAO,KAAK,GAAO,OAAO;MACjC,IAAI;MACJ,MAAM;MACN,QAAQ;MACR;MACD,EAAE;KACJ,CAAC;KACF;;EAGJ,IAAM,IAAmB;GACvB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;mBAIsB,EAAM,QAAA,GAAA,EAA3B,EAgDgB,EAAA,EAAA,EAAA;;GAhDiB,eAAY;;GAChC,kBAAc,QAYrB,EAAA,GAAA,EAXF,EAWE,EAAA,EAAA,EAAA;IAVC,KAAK,EAAM,KAAK;IACjB,eAAY;IACX,eAAa,EAAM,KAAK;IACxB,OAAK,EAAA,GAAK,EAAA,EAAY,CAAC,WAAW,EAAM,KAAK,MAAM,WAAM,GAAA,CAAA;IACzD,cAAY;IACb,aAAU;IACV,aAAY;IACX,WAAW,EAAM,KAAK,MAAM,WAAM;IAClC,UAAU,EAAA,EAAa;IACvB,uBAAoB;;;;;;;GAGd,gBAAY,QA+BO,CA9B5B,EA8B4B,EAAA,EAAA,EAAA;IA7BzB,OAAK,EAAA,CAAGA,EAAAA,OAAO,MAAI,GAAK,EAAA,EAAY,CAAC,WAAW,EAAM,KAAK,MAAM,WAAM,GAAA,CAAA,CAAA;IACvE,SAAS,EAAM;IACf,SAAS,EAAM,KAAK;IACpB,qBAAmB;IACnB,qBAAmB;IACnB,uBAAqB,EAAM;IAC3B,cAAY;IACZ,2BAAyB;;IAEf,qBAAiB,QAkBpB,CAjBN,EAiBM,OAAA;KAjBD,eAAY;KAAiC,OAAK,EAAEA,EAAAA,OAAO,QAAO;QACrE,EAMiB,EAAA,EAAA,EAAA;KALf,eAAY;KACZ,MAAK;KACJ,SAAO;;sBAGV,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAFC,gBAED,GAAA,CAAA,CAAA,CAAA;;QAEQ,EAAA,SAAA,GAAA,EADR,EAQiB,EAAA,EAAA,EAAA;;KANf,eAAY;KACZ,MAAK;KACJ,UAAU,EAAM,uBAAkB;KAClC,SAAO;;sBAGV,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAFC,oBAED,GAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotations.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Props as BaseProps } from \"./FilterSidebar.vue\";\nexport type Props = Omit<BaseProps, \"step\" | \"onUpdateStep\"> & {\n annotation: Annotation;\n onUpdateAnnotation: (annotation: Annotation) => void;\n onDeleteSchema?: () => void;\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, effect, shallowRef } from \"vue\";\n\nimport { isNil } from \"@milaboratories/helpers\";\nimport { produce } from \"immer\";\nimport { PlSidebarGroup, useConfirm } from \"@milaboratories/uikit\";\n\nimport type { Annotation, Filter } from \"../types\";\nimport AnnotationsSidebar from \"./AnnotationsSidebar.vue\";\nimport FilterSidebar from \"./FilterSidebar.vue\";\n\nconst props = defineProps<Props>();\n\nconst selectedStepId = shallowRef<undefined | number>(undefined);\n\nconst selectedStep = computed(() => {\n return isNil(selectedStepId.value) || isNil(props.annotation)\n ? undefined\n : props.annotation.steps.find((step) => step.id === selectedStepId.value);\n});\n\neffect(function setDefaultStepId() {\n if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {\n selectedStepId.value = props.annotation.steps[0].id;\n }\n});\n\nconst confirmResetSchema = useConfirm({\n title: \"Reset Schema\",\n message: \"Are you sure you want to reset the schema? This action cannot be undone.\",\n confirmLabel: \"Yes, reset\",\n cancelLabel: \"No, cancel\",\n});\n\nasync function handleDeleteSchema() {\n if (await confirmResetSchema()) {\n selectedStepId.value = undefined;\n props.onDeleteSchema?.();\n }\n}\n\nfunction updateSelectedStepId(id: undefined | number) {\n selectedStepId.value = id;\n}\n\nfunction updateSelectedStep(step: Filter) {\n props.onUpdateAnnotation(\n produce(props.annotation, (draft) => {\n const idx = draft.steps.findIndex((s) => s.id === step.id);\n if (idx !== -1) {\n draft.steps[idx] = step;\n }\n }),\n );\n}\n</script>\n\n<template>\n <PlSidebarGroup>\n <template #item-0>\n <AnnotationsSidebar\n :annotation=\"props.annotation\"\n :selected-step-id=\"selectedStepId\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-update-selected-step-id=\"updateSelectedStepId\"\n :class=\"$style.sidebarItem\"\n @delete-schema=\"handleDeleteSchema\"\n />\n </template>\n <template #item-1>\n <FilterSidebar\n v-if=\"selectedStep\"\n :step=\"selectedStep\"\n :on-update-step=\"updateSelectedStep\"\n :class=\"$style.sidebarItem\"\n :columns=\"props.columns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :hasSelectedColumns=\"props.hasSelectedColumns\"\n :getValuesForSelectedColumns=\"props.getValuesForSelectedColumns\"\n />\n </template>\n </PlSidebarGroup>\n</template>\n\n<style module>\n.sidebarItem {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"PlAnnotations.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Props as BaseProps } from \"./FilterSidebar.vue\";\nexport type Props = Omit<BaseProps, \"step\" | \"onUpdateStep\"> & {\n annotation: Annotation;\n onUpdateAnnotation: (annotation: Annotation) => void;\n onDeleteSchema?: () => void;\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, effect, shallowRef } from \"vue\";\n\nimport { isNil } from \"@milaboratories/helpers\";\nimport { produce } from \"immer\";\nimport { PlSidebarGroup, useConfirm } from \"@milaboratories/uikit\";\n\nimport type { Annotation, Filter } from \"../types\";\nimport AnnotationsSidebar from \"./AnnotationsSidebar.vue\";\nimport FilterSidebar from \"./FilterSidebar.vue\";\n\nconst props = defineProps<Props>();\n\nconst selectedStepId = shallowRef<undefined | number>(undefined);\n\nconst selectedStep = computed(() => {\n return isNil(selectedStepId.value) || isNil(props.annotation)\n ? undefined\n : props.annotation.steps.find((step) => step.id === selectedStepId.value);\n});\n\neffect(function setDefaultStepId() {\n if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {\n selectedStepId.value = props.annotation.steps[0].id;\n }\n});\n\nconst confirmResetSchema = useConfirm({\n title: \"Reset Schema\",\n message: \"Are you sure you want to reset the schema? This action cannot be undone.\",\n confirmLabel: \"Yes, reset\",\n cancelLabel: \"No, cancel\",\n});\n\nasync function handleDeleteSchema() {\n if (await confirmResetSchema()) {\n selectedStepId.value = undefined;\n props.onDeleteSchema?.();\n }\n}\n\nfunction updateSelectedStepId(id: undefined | number) {\n selectedStepId.value = id;\n}\n\nfunction updateSelectedStep(step: Filter) {\n props.onUpdateAnnotation(\n produce(props.annotation, (draft) => {\n const idx = draft.steps.findIndex((s) => s.id === step.id);\n if (idx !== -1) {\n draft.steps[idx] = step;\n }\n }),\n );\n}\n</script>\n\n<template>\n <PlSidebarGroup data-testid=\"pl-annotations\">\n <template #item-0>\n <AnnotationsSidebar\n :annotation=\"props.annotation\"\n :selected-step-id=\"selectedStepId\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-update-selected-step-id=\"updateSelectedStepId\"\n :class=\"$style.sidebarItem\"\n @delete-schema=\"handleDeleteSchema\"\n />\n </template>\n <template #item-1>\n <FilterSidebar\n v-if=\"selectedStep\"\n :step=\"selectedStep\"\n :on-update-step=\"updateSelectedStep\"\n :class=\"$style.sidebarItem\"\n :columns=\"props.columns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :hasSelectedColumns=\"props.hasSelectedColumns\"\n :getValuesForSelectedColumns=\"props.getValuesForSelectedColumns\"\n />\n </template>\n </PlSidebarGroup>\n</template>\n\n<style module>\n.sidebarItem {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotations.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Props as BaseProps } from \"./FilterSidebar.vue\";\nexport type Props = Omit<BaseProps, \"step\" | \"onUpdateStep\"> & {\n annotation: Annotation;\n onUpdateAnnotation: (annotation: Annotation) => void;\n onDeleteSchema?: () => void;\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, effect, shallowRef } from \"vue\";\n\nimport { isNil } from \"@milaboratories/helpers\";\nimport { produce } from \"immer\";\nimport { PlSidebarGroup, useConfirm } from \"@milaboratories/uikit\";\n\nimport type { Annotation, Filter } from \"../types\";\nimport AnnotationsSidebar from \"./AnnotationsSidebar.vue\";\nimport FilterSidebar from \"./FilterSidebar.vue\";\n\nconst props = defineProps<Props>();\n\nconst selectedStepId = shallowRef<undefined | number>(undefined);\n\nconst selectedStep = computed(() => {\n return isNil(selectedStepId.value) || isNil(props.annotation)\n ? undefined\n : props.annotation.steps.find((step) => step.id === selectedStepId.value);\n});\n\neffect(function setDefaultStepId() {\n if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {\n selectedStepId.value = props.annotation.steps[0].id;\n }\n});\n\nconst confirmResetSchema = useConfirm({\n title: \"Reset Schema\",\n message: \"Are you sure you want to reset the schema? This action cannot be undone.\",\n confirmLabel: \"Yes, reset\",\n cancelLabel: \"No, cancel\",\n});\n\nasync function handleDeleteSchema() {\n if (await confirmResetSchema()) {\n selectedStepId.value = undefined;\n props.onDeleteSchema?.();\n }\n}\n\nfunction updateSelectedStepId(id: undefined | number) {\n selectedStepId.value = id;\n}\n\nfunction updateSelectedStep(step: Filter) {\n props.onUpdateAnnotation(\n produce(props.annotation, (draft) => {\n const idx = draft.steps.findIndex((s) => s.id === step.id);\n if (idx !== -1) {\n draft.steps[idx] = step;\n }\n }),\n );\n}\n</script>\n\n<template>\n <PlSidebarGroup>\n <template #item-0>\n <AnnotationsSidebar\n :annotation=\"props.annotation\"\n :selected-step-id=\"selectedStepId\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-update-selected-step-id=\"updateSelectedStepId\"\n :class=\"$style.sidebarItem\"\n @delete-schema=\"handleDeleteSchema\"\n />\n </template>\n <template #item-1>\n <FilterSidebar\n v-if=\"selectedStep\"\n :step=\"selectedStep\"\n :on-update-step=\"updateSelectedStep\"\n :class=\"$style.sidebarItem\"\n :columns=\"props.columns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :hasSelectedColumns=\"props.hasSelectedColumns\"\n :getValuesForSelectedColumns=\"props.getValuesForSelectedColumns\"\n />\n </template>\n </PlSidebarGroup>\n</template>\n\n<style module>\n.sidebarItem {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"PlAnnotations.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Props as BaseProps } from \"./FilterSidebar.vue\";\nexport type Props = Omit<BaseProps, \"step\" | \"onUpdateStep\"> & {\n annotation: Annotation;\n onUpdateAnnotation: (annotation: Annotation) => void;\n onDeleteSchema?: () => void;\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, effect, shallowRef } from \"vue\";\n\nimport { isNil } from \"@milaboratories/helpers\";\nimport { produce } from \"immer\";\nimport { PlSidebarGroup, useConfirm } from \"@milaboratories/uikit\";\n\nimport type { Annotation, Filter } from \"../types\";\nimport AnnotationsSidebar from \"./AnnotationsSidebar.vue\";\nimport FilterSidebar from \"./FilterSidebar.vue\";\n\nconst props = defineProps<Props>();\n\nconst selectedStepId = shallowRef<undefined | number>(undefined);\n\nconst selectedStep = computed(() => {\n return isNil(selectedStepId.value) || isNil(props.annotation)\n ? undefined\n : props.annotation.steps.find((step) => step.id === selectedStepId.value);\n});\n\neffect(function setDefaultStepId() {\n if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {\n selectedStepId.value = props.annotation.steps[0].id;\n }\n});\n\nconst confirmResetSchema = useConfirm({\n title: \"Reset Schema\",\n message: \"Are you sure you want to reset the schema? This action cannot be undone.\",\n confirmLabel: \"Yes, reset\",\n cancelLabel: \"No, cancel\",\n});\n\nasync function handleDeleteSchema() {\n if (await confirmResetSchema()) {\n selectedStepId.value = undefined;\n props.onDeleteSchema?.();\n }\n}\n\nfunction updateSelectedStepId(id: undefined | number) {\n selectedStepId.value = id;\n}\n\nfunction updateSelectedStep(step: Filter) {\n props.onUpdateAnnotation(\n produce(props.annotation, (draft) => {\n const idx = draft.steps.findIndex((s) => s.id === step.id);\n if (idx !== -1) {\n draft.steps[idx] = step;\n }\n }),\n );\n}\n</script>\n\n<template>\n <PlSidebarGroup data-testid=\"pl-annotations\">\n <template #item-0>\n <AnnotationsSidebar\n :annotation=\"props.annotation\"\n :selected-step-id=\"selectedStepId\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-update-selected-step-id=\"updateSelectedStepId\"\n :class=\"$style.sidebarItem\"\n @delete-schema=\"handleDeleteSchema\"\n />\n </template>\n <template #item-1>\n <FilterSidebar\n v-if=\"selectedStep\"\n :step=\"selectedStep\"\n :on-update-step=\"updateSelectedStep\"\n :class=\"$style.sidebarItem\"\n :columns=\"props.columns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :hasSelectedColumns=\"props.hasSelectedColumns\"\n :getValuesForSelectedColumns=\"props.getValuesForSelectedColumns\"\n />\n </template>\n </PlSidebarGroup>\n</template>\n\n<style module>\n.sidebarItem {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotations.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"names":[],"mappings":"AA4GA,OAAO,KAAK,EAAE,UAAU,EAAU,MAAM,UAAU,CAAC;AAKnD,OAAO,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC9D,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAAC,GAAG;IAC7D,UAAU,EAAE,UAAU,CAAC;IACvB,kBAAkB,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IACrD,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"PlAnnotations.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"names":[],"mappings":"AA4GA,OAAO,KAAK,EAAE,UAAU,EAAU,MAAM,UAAU,CAAC;AAKnD,OAAO,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC9D,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAAC,GAAG;IAC7D,UAAU,EAAE,UAAU,CAAC;IACvB,kBAAkB,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IACrD,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY,sRAyJd,CAAC"}
|
|
@@ -40,7 +40,7 @@ var _ = /* @__PURE__ */ c({
|
|
|
40
40
|
n !== -1 && (t.steps[n] = e);
|
|
41
41
|
}));
|
|
42
42
|
}
|
|
43
|
-
return (e, r) => (d(), a(p(h),
|
|
43
|
+
return (e, r) => (d(), a(p(h), { "data-testid": "pl-annotations" }, {
|
|
44
44
|
"item-0": m(() => [s(t, {
|
|
45
45
|
annotation: _.annotation,
|
|
46
46
|
"selected-step-id": v.value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotations.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Props as BaseProps } from \"./FilterSidebar.vue\";\nexport type Props = Omit<BaseProps, \"step\" | \"onUpdateStep\"> & {\n annotation: Annotation;\n onUpdateAnnotation: (annotation: Annotation) => void;\n onDeleteSchema?: () => void;\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, effect, shallowRef } from \"vue\";\n\nimport { isNil } from \"@milaboratories/helpers\";\nimport { produce } from \"immer\";\nimport { PlSidebarGroup, useConfirm } from \"@milaboratories/uikit\";\n\nimport type { Annotation, Filter } from \"../types\";\nimport AnnotationsSidebar from \"./AnnotationsSidebar.vue\";\nimport FilterSidebar from \"./FilterSidebar.vue\";\n\nconst props = defineProps<Props>();\n\nconst selectedStepId = shallowRef<undefined | number>(undefined);\n\nconst selectedStep = computed(() => {\n return isNil(selectedStepId.value) || isNil(props.annotation)\n ? undefined\n : props.annotation.steps.find((step) => step.id === selectedStepId.value);\n});\n\neffect(function setDefaultStepId() {\n if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {\n selectedStepId.value = props.annotation.steps[0].id;\n }\n});\n\nconst confirmResetSchema = useConfirm({\n title: \"Reset Schema\",\n message: \"Are you sure you want to reset the schema? This action cannot be undone.\",\n confirmLabel: \"Yes, reset\",\n cancelLabel: \"No, cancel\",\n});\n\nasync function handleDeleteSchema() {\n if (await confirmResetSchema()) {\n selectedStepId.value = undefined;\n props.onDeleteSchema?.();\n }\n}\n\nfunction updateSelectedStepId(id: undefined | number) {\n selectedStepId.value = id;\n}\n\nfunction updateSelectedStep(step: Filter) {\n props.onUpdateAnnotation(\n produce(props.annotation, (draft) => {\n const idx = draft.steps.findIndex((s) => s.id === step.id);\n if (idx !== -1) {\n draft.steps[idx] = step;\n }\n }),\n );\n}\n</script>\n\n<template>\n <PlSidebarGroup>\n <template #item-0>\n <AnnotationsSidebar\n :annotation=\"props.annotation\"\n :selected-step-id=\"selectedStepId\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-update-selected-step-id=\"updateSelectedStepId\"\n :class=\"$style.sidebarItem\"\n @delete-schema=\"handleDeleteSchema\"\n />\n </template>\n <template #item-1>\n <FilterSidebar\n v-if=\"selectedStep\"\n :step=\"selectedStep\"\n :on-update-step=\"updateSelectedStep\"\n :class=\"$style.sidebarItem\"\n :columns=\"props.columns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :hasSelectedColumns=\"props.hasSelectedColumns\"\n :getValuesForSelectedColumns=\"props.getValuesForSelectedColumns\"\n />\n </template>\n </PlSidebarGroup>\n</template>\n\n<style module>\n.sidebarItem {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAoBA,IAAM,IAAQ,GAER,IAAiB,EAA+B,KAAA,EAAU,EAE1D,IAAe,QACZ,EAAM,EAAe,MAAM,IAAI,EAAM,EAAM,WAAU,GACxD,KAAA,IACA,EAAM,WAAW,MAAM,MAAM,MAAS,EAAK,OAAO,EAAe,MAAM,CAC3E;AAEF,IAAO,WAA4B;AACjC,GAAI,EAAe,UAAU,KAAA,KAAa,EAAM,WAAW,MAAM,SAAS,MACxE,EAAe,QAAQ,EAAM,WAAW,MAAM,GAAG;IAEnD;EAEF,IAAM,IAAqB,EAAW;GACpC,OAAO;GACP,SAAS;GACT,cAAc;GACd,aAAa;GACd,CAAC;EAEF,eAAe,IAAqB;AAClC,GAAI,MAAM,GAAoB,KAC5B,EAAe,QAAQ,KAAA,GACvB,EAAM,kBAAkB;;EAI5B,SAAS,EAAqB,GAAwB;AACpD,KAAe,QAAQ;;EAGzB,SAAS,EAAmB,GAAc;AACxC,KAAM,mBACJ,EAAQ,EAAM,aAAa,MAAU;IACnC,IAAM,IAAM,EAAM,MAAM,WAAW,MAAM,EAAE,OAAO,EAAK,GAAG;AAC1D,IAAI,MAAQ,OACV,EAAM,MAAM,KAAO;KAErB,CACH;;yBAKD,EAuBiB,EAAA,EAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"PlAnnotations.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotations.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Props as BaseProps } from \"./FilterSidebar.vue\";\nexport type Props = Omit<BaseProps, \"step\" | \"onUpdateStep\"> & {\n annotation: Annotation;\n onUpdateAnnotation: (annotation: Annotation) => void;\n onDeleteSchema?: () => void;\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, effect, shallowRef } from \"vue\";\n\nimport { isNil } from \"@milaboratories/helpers\";\nimport { produce } from \"immer\";\nimport { PlSidebarGroup, useConfirm } from \"@milaboratories/uikit\";\n\nimport type { Annotation, Filter } from \"../types\";\nimport AnnotationsSidebar from \"./AnnotationsSidebar.vue\";\nimport FilterSidebar from \"./FilterSidebar.vue\";\n\nconst props = defineProps<Props>();\n\nconst selectedStepId = shallowRef<undefined | number>(undefined);\n\nconst selectedStep = computed(() => {\n return isNil(selectedStepId.value) || isNil(props.annotation)\n ? undefined\n : props.annotation.steps.find((step) => step.id === selectedStepId.value);\n});\n\neffect(function setDefaultStepId() {\n if (selectedStepId.value === undefined && props.annotation.steps.length > 0) {\n selectedStepId.value = props.annotation.steps[0].id;\n }\n});\n\nconst confirmResetSchema = useConfirm({\n title: \"Reset Schema\",\n message: \"Are you sure you want to reset the schema? This action cannot be undone.\",\n confirmLabel: \"Yes, reset\",\n cancelLabel: \"No, cancel\",\n});\n\nasync function handleDeleteSchema() {\n if (await confirmResetSchema()) {\n selectedStepId.value = undefined;\n props.onDeleteSchema?.();\n }\n}\n\nfunction updateSelectedStepId(id: undefined | number) {\n selectedStepId.value = id;\n}\n\nfunction updateSelectedStep(step: Filter) {\n props.onUpdateAnnotation(\n produce(props.annotation, (draft) => {\n const idx = draft.steps.findIndex((s) => s.id === step.id);\n if (idx !== -1) {\n draft.steps[idx] = step;\n }\n }),\n );\n}\n</script>\n\n<template>\n <PlSidebarGroup data-testid=\"pl-annotations\">\n <template #item-0>\n <AnnotationsSidebar\n :annotation=\"props.annotation\"\n :selected-step-id=\"selectedStepId\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-update-selected-step-id=\"updateSelectedStepId\"\n :class=\"$style.sidebarItem\"\n @delete-schema=\"handleDeleteSchema\"\n />\n </template>\n <template #item-1>\n <FilterSidebar\n v-if=\"selectedStep\"\n :step=\"selectedStep\"\n :on-update-step=\"updateSelectedStep\"\n :class=\"$style.sidebarItem\"\n :columns=\"props.columns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :hasSelectedColumns=\"props.hasSelectedColumns\"\n :getValuesForSelectedColumns=\"props.getValuesForSelectedColumns\"\n />\n </template>\n </PlSidebarGroup>\n</template>\n\n<style module>\n.sidebarItem {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAoBA,IAAM,IAAQ,GAER,IAAiB,EAA+B,KAAA,EAAU,EAE1D,IAAe,QACZ,EAAM,EAAe,MAAM,IAAI,EAAM,EAAM,WAAU,GACxD,KAAA,IACA,EAAM,WAAW,MAAM,MAAM,MAAS,EAAK,OAAO,EAAe,MAAM,CAC3E;AAEF,IAAO,WAA4B;AACjC,GAAI,EAAe,UAAU,KAAA,KAAa,EAAM,WAAW,MAAM,SAAS,MACxE,EAAe,QAAQ,EAAM,WAAW,MAAM,GAAG;IAEnD;EAEF,IAAM,IAAqB,EAAW;GACpC,OAAO;GACP,SAAS;GACT,cAAc;GACd,aAAa;GACd,CAAC;EAEF,eAAe,IAAqB;AAClC,GAAI,MAAM,GAAoB,KAC5B,EAAe,QAAQ,KAAA,GACvB,EAAM,kBAAkB;;EAI5B,SAAS,EAAqB,GAAwB;AACpD,KAAe,QAAQ;;EAGzB,SAAS,EAAmB,GAAc;AACxC,KAAM,mBACJ,EAAQ,EAAM,aAAa,MAAU;IACnC,IAAM,IAAM,EAAM,MAAM,WAAW,MAAM,EAAE,OAAO,EAAK,GAAG;AAC1D,IAAI,MAAQ,OACV,EAAM,MAAM,KAAO;KAErB,CACH;;yBAKD,EAuBiB,EAAA,EAAA,EAAA,EAvBD,eAAY,kBAAgB,EAAA;GAC/B,UAAM,QAQb,CAPF,EAOE,GAAA;IANC,YAAY,EAAM;IAClB,oBAAkB,EAAA;IAClB,wBAAsB,EAAM;IAC5B,8BAA4B;IAC5B,OAAK,EAAEA,EAAAA,OAAO,YAAW;IACzB,gBAAe;;;;;;;GAGT,UAAM,QAUb,CARM,EAAA,SAAA,GAAA,EADR,EASE,GAAA;;IAPC,MAAM,EAAA;IACN,kBAAgB;IAChB,OAAK,EAAEA,EAAAA,OAAO,YAAW;IACzB,SAAS,EAAM;IACf,uBAAqB,EAAM;IAC3B,oBAAoB,EAAM;IAC1B,6BAA6B,EAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotationsModal.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotationsModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlPureSlideModal } from \"@milaboratories/uikit\";\n\nimport type { Props } from \"./PlAnnotations.vue\";\nimport PlAnnotations from \"./PlAnnotations.vue\";\n\nconst props = defineProps<\n Props & {\n opened: boolean;\n onUpdateOpened: (opened: boolean) => void;\n }\n>();\n\nasync function handleDeleteSchema() {\n props.onUpdateOpened(false);\n props.onDeleteSchema?.();\n}\n</script>\n\n<template>\n <PlPureSlideModal\n :model-value=\"props.opened\"\n :class=\"$style.modal\"\n width=\"768px\"\n @update:model-value=\"props.onUpdateOpened\"\n >\n <PlAnnotations\n :class=\"$style.content\"\n :columns=\"props.columns\"\n :annotation=\"props.annotation\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-delete-schema=\"handleDeleteSchema\"\n :has-selected-columns=\"props.hasSelectedColumns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :get-values-for-selected-columns=\"props.getValuesForSelectedColumns\"\n />\n </PlPureSlideModal>\n</template>\n\n<style module>\n.modal {\n display: flex;\n}\n\n.content {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"PlAnnotationsModal.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotationsModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlPureSlideModal } from \"@milaboratories/uikit\";\n\nimport type { Props } from \"./PlAnnotations.vue\";\nimport PlAnnotations from \"./PlAnnotations.vue\";\n\nconst props = defineProps<\n Props & {\n opened: boolean;\n onUpdateOpened: (opened: boolean) => void;\n }\n>();\n\nasync function handleDeleteSchema() {\n props.onUpdateOpened(false);\n props.onDeleteSchema?.();\n}\n</script>\n\n<template>\n <PlPureSlideModal\n data-testid=\"pl-annotations-modal\"\n :model-value=\"props.opened\"\n :class=\"$style.modal\"\n width=\"768px\"\n @update:model-value=\"props.onUpdateOpened\"\n >\n <PlAnnotations\n :class=\"$style.content\"\n :columns=\"props.columns\"\n :annotation=\"props.annotation\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-delete-schema=\"handleDeleteSchema\"\n :has-selected-columns=\"props.hasSelectedColumns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :get-values-for-selected-columns=\"props.getValuesForSelectedColumns\"\n />\n </PlPureSlideModal>\n</template>\n\n<style module>\n.modal {\n display: flex;\n}\n\n.content {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotationsModal.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotationsModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlPureSlideModal } from \"@milaboratories/uikit\";\n\nimport type { Props } from \"./PlAnnotations.vue\";\nimport PlAnnotations from \"./PlAnnotations.vue\";\n\nconst props = defineProps<\n Props & {\n opened: boolean;\n onUpdateOpened: (opened: boolean) => void;\n }\n>();\n\nasync function handleDeleteSchema() {\n props.onUpdateOpened(false);\n props.onDeleteSchema?.();\n}\n</script>\n\n<template>\n <PlPureSlideModal\n :model-value=\"props.opened\"\n :class=\"$style.modal\"\n width=\"768px\"\n @update:model-value=\"props.onUpdateOpened\"\n >\n <PlAnnotations\n :class=\"$style.content\"\n :columns=\"props.columns\"\n :annotation=\"props.annotation\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-delete-schema=\"handleDeleteSchema\"\n :has-selected-columns=\"props.hasSelectedColumns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :get-values-for-selected-columns=\"props.getValuesForSelectedColumns\"\n />\n </PlPureSlideModal>\n</template>\n\n<style module>\n.modal {\n display: flex;\n}\n\n.content {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"PlAnnotationsModal.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotationsModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlPureSlideModal } from \"@milaboratories/uikit\";\n\nimport type { Props } from \"./PlAnnotations.vue\";\nimport PlAnnotations from \"./PlAnnotations.vue\";\n\nconst props = defineProps<\n Props & {\n opened: boolean;\n onUpdateOpened: (opened: boolean) => void;\n }\n>();\n\nasync function handleDeleteSchema() {\n props.onUpdateOpened(false);\n props.onDeleteSchema?.();\n}\n</script>\n\n<template>\n <PlPureSlideModal\n data-testid=\"pl-annotations-modal\"\n :model-value=\"props.opened\"\n :class=\"$style.modal\"\n width=\"768px\"\n @update:model-value=\"props.onUpdateOpened\"\n >\n <PlAnnotations\n :class=\"$style.content\"\n :columns=\"props.columns\"\n :annotation=\"props.annotation\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-delete-schema=\"handleDeleteSchema\"\n :has-selected-columns=\"props.hasSelectedColumns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :get-values-for-selected-columns=\"props.getValuesForSelectedColumns\"\n />\n </PlPureSlideModal>\n</template>\n\n<style module>\n.modal {\n display: flex;\n}\n\n.content {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotationsModal.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAnnotations/components/PlAnnotationsModal.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PlAnnotationsModal.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/PlAnnotations/components/PlAnnotationsModal.vue"],"names":[],"mappings":"AAuDA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAGjD,KAAK,WAAW,GAAG,KAAK,GAAG;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAC3C,CAAC;AAyFJ,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAnnotationsModal.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotationsModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlPureSlideModal } from \"@milaboratories/uikit\";\n\nimport type { Props } from \"./PlAnnotations.vue\";\nimport PlAnnotations from \"./PlAnnotations.vue\";\n\nconst props = defineProps<\n Props & {\n opened: boolean;\n onUpdateOpened: (opened: boolean) => void;\n }\n>();\n\nasync function handleDeleteSchema() {\n props.onUpdateOpened(false);\n props.onDeleteSchema?.();\n}\n</script>\n\n<template>\n <PlPureSlideModal\n :model-value=\"props.opened\"\n :class=\"$style.modal\"\n width=\"768px\"\n @update:model-value=\"props.onUpdateOpened\"\n >\n <PlAnnotations\n :class=\"$style.content\"\n :columns=\"props.columns\"\n :annotation=\"props.annotation\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-delete-schema=\"handleDeleteSchema\"\n :has-selected-columns=\"props.hasSelectedColumns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :get-values-for-selected-columns=\"props.getValuesForSelectedColumns\"\n />\n </PlPureSlideModal>\n</template>\n\n<style module>\n.modal {\n display: flex;\n}\n\n.content {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAMA,IAAM,IAAQ;EAOd,eAAe,IAAqB;AAElC,GADA,EAAM,eAAe,GAAM,EAC3B,EAAM,kBAAkB;;yBAKxB,
|
|
1
|
+
{"version":3,"file":"PlAnnotationsModal.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../../src/components/PlAnnotations/components/PlAnnotationsModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlPureSlideModal } from \"@milaboratories/uikit\";\n\nimport type { Props } from \"./PlAnnotations.vue\";\nimport PlAnnotations from \"./PlAnnotations.vue\";\n\nconst props = defineProps<\n Props & {\n opened: boolean;\n onUpdateOpened: (opened: boolean) => void;\n }\n>();\n\nasync function handleDeleteSchema() {\n props.onUpdateOpened(false);\n props.onDeleteSchema?.();\n}\n</script>\n\n<template>\n <PlPureSlideModal\n data-testid=\"pl-annotations-modal\"\n :model-value=\"props.opened\"\n :class=\"$style.modal\"\n width=\"768px\"\n @update:model-value=\"props.onUpdateOpened\"\n >\n <PlAnnotations\n :class=\"$style.content\"\n :columns=\"props.columns\"\n :annotation=\"props.annotation\"\n :on-update-annotation=\"props.onUpdateAnnotation\"\n :on-delete-schema=\"handleDeleteSchema\"\n :has-selected-columns=\"props.hasSelectedColumns\"\n :get-suggest-options=\"props.getSuggestOptions\"\n :get-values-for-selected-columns=\"props.getValuesForSelectedColumns\"\n />\n </PlPureSlideModal>\n</template>\n\n<style module>\n.modal {\n display: flex;\n}\n\n.content {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAMA,IAAM,IAAQ;EAOd,eAAe,IAAqB;AAElC,GADA,EAAM,eAAe,GAAM,EAC3B,EAAM,kBAAkB;;yBAKxB,EAiBmB,EAAA,EAAA,EAAA;GAhBjB,eAAY;GACX,eAAa,EAAM;GACnB,OAAK,EAAEA,EAAAA,OAAO,MAAK;GACpB,OAAM;GACL,uBAAoB,EAAM;;oBAWzB,CATF,EASE,GAAA;IARC,OAAK,EAAEA,EAAAA,OAAO,QAAO;IACrB,SAAS,EAAM;IACf,YAAY,EAAM;IAClB,wBAAsB,EAAM;IAC5B,oBAAkB;IAClB,wBAAsB,EAAM;IAC5B,uBAAqB,EAAM;IAC3B,mCAAiC,EAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAppErrorNotificationAlert.js","names":[],"sources":["../../../src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { BlockOutputsBase } from \"@platforma-sdk/model\";\nimport type { OutputErrors } from \"../../types\";\n// @TODO module\nimport \"./pl-app-error-notification-alert.scss\";\nimport {\n PlBtnPrimary,\n PlDialogModal,\n PlNotificationAlert,\n PlSpacer,\n PlLogView,\n} from \"@milaboratories/uikit\";\nimport { computed, ref, watch } from \"vue\";\n\nexport type FullMessage = { fullMessage: string };\n\nconst props = defineProps<{ errors: OutputErrors<BlockOutputsBase> }>();\n\nconst isModalOpen = ref(false);\n\nconst isAlertOpen = ref(true);\n\nconst existingErrors = computed(() => Object.entries(props.errors).filter((item) => !!item[1]));\n\nfunction showErrors() {\n isModalOpen.value = true;\n}\n\n// @TODO (temp)\nwatch(\n () => props.errors,\n (errors) => {\n isAlertOpen.value = Object.values(errors).some((v) => !!v);\n },\n { immediate: true, deep: true },\n);\n</script>\n<template>\n <div class=\"pl-app-notification-alert\">\n <PlDialogModal
|
|
1
|
+
{"version":3,"file":"PlAppErrorNotificationAlert.js","names":[],"sources":["../../../src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { BlockOutputsBase } from \"@platforma-sdk/model\";\nimport type { OutputErrors } from \"../../types\";\n// @TODO module\nimport \"./pl-app-error-notification-alert.scss\";\nimport {\n PlBtnPrimary,\n PlDialogModal,\n PlNotificationAlert,\n PlSpacer,\n PlLogView,\n} from \"@milaboratories/uikit\";\nimport { computed, ref, watch } from \"vue\";\n\nexport type FullMessage = { fullMessage: string };\n\nconst props = defineProps<{ errors: OutputErrors<BlockOutputsBase> }>();\n\nconst isModalOpen = ref(false);\n\nconst isAlertOpen = ref(true);\n\nconst existingErrors = computed(() => Object.entries(props.errors).filter((item) => !!item[1]));\n\nfunction showErrors() {\n isModalOpen.value = true;\n}\n\n// @TODO (temp)\nwatch(\n () => props.errors,\n (errors) => {\n isAlertOpen.value = Object.values(errors).some((v) => !!v);\n },\n { immediate: true, deep: true },\n);\n</script>\n<template>\n <div data-testid=\"pl-app-error-notification-alert\" class=\"pl-app-notification-alert\">\n <PlDialogModal\n v-model=\"isModalOpen\"\n data-testid=\"pl-app-error-notification-alert-modal\"\n width=\"720px\"\n style=\"max-height: 100vh\"\n >\n <template #title> Errors </template>\n <div\n data-testid=\"pl-app-error-notification-alert-content\"\n class=\"pl-app-notification-alert__content\"\n >\n <template v-for=\"item in existingErrors\" :key=\"item[0]\">\n <div\n data-testid=\"pl-app-error-notification-alert-item\"\n class=\"pl-app-notification-alert__item\"\n >\n <div\n data-testid=\"pl-app-error-notification-alert-item-title\"\n class=\"pl-app-notification-alert__title\"\n >\n Block output: {{ item[0] }}\n </div>\n <PlLogView\n data-testid=\"pl-app-error-notification-alert-log\"\n :value=\"item[1]?.message\"\n :valueToCopy=\"\n 'fullMessage' in (item[1] ?? {})\n ? (item[1] as unknown as FullMessage).fullMessage\n : item[1]?.message\n \"\n :download-filename=\"`output-${item[0]}-error.txt`\"\n />\n </div>\n </template>\n </div>\n </PlDialogModal>\n\n <PlNotificationAlert\n v-model=\"isAlertOpen\"\n data-testid=\"pl-app-error-notification-alert-message\"\n type=\"error\"\n closable\n >\n Some outputs have errors.\n <template #actions>\n <PlBtnPrimary\n data-testid=\"pl-app-error-notification-alert-show-errors\"\n icon=\"arrow-right\"\n @click=\"showErrors\"\n >See errors</PlBtnPrimary\n >\n <PlSpacer />\n </template>\n </PlNotificationAlert>\n </div>\n</template>\n"],"mappings":""}
|
package/dist/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAppErrorNotificationAlert.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PlAppErrorNotificationAlert.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue"],"names":[],"mappings":"AAkGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,wCAAwC,CAAC;AAUhD,MAAM,MAAM,WAAW,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAA;CAAE,CAAC;AAyL9D,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -2,7 +2,16 @@ import './pl-app-error-notification-alert.css';/* empty css
|
|
|
2
2
|
import { Fragment as e, computed as t, createElementBlock as n, createElementVNode as r, createTextVNode as i, createVNode as a, defineComponent as o, openBlock as s, ref as c, renderList as l, toDisplayString as u, unref as d, watch as f, withCtx as p } from "vue";
|
|
3
3
|
import { PlBtnPrimary as m, PlDialogModal as h, PlLogView as g, PlNotificationAlert as _, PlSpacer as v } from "@milaboratories/uikit";
|
|
4
4
|
//#region src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var y = {
|
|
5
|
+
var y = {
|
|
6
|
+
"data-testid": "pl-app-error-notification-alert",
|
|
7
|
+
class: "pl-app-notification-alert"
|
|
8
|
+
}, b = {
|
|
9
|
+
"data-testid": "pl-app-error-notification-alert-content",
|
|
10
|
+
class: "pl-app-notification-alert__content"
|
|
11
|
+
}, x = {
|
|
12
|
+
"data-testid": "pl-app-error-notification-alert-item-title",
|
|
13
|
+
class: "pl-app-notification-alert__title"
|
|
14
|
+
}, S = /* @__PURE__ */ o({
|
|
6
15
|
__name: "PlAppErrorNotificationAlert",
|
|
7
16
|
props: { errors: {} },
|
|
8
17
|
setup(o) {
|
|
@@ -18,14 +27,17 @@ var y = { class: "pl-app-notification-alert" }, b = { class: "pl-app-notificatio
|
|
|
18
27
|
}), (t, o) => (s(), n("div", y, [a(d(h), {
|
|
19
28
|
modelValue: C.value,
|
|
20
29
|
"onUpdate:modelValue": o[0] ||= (e) => C.value = e,
|
|
30
|
+
"data-testid": "pl-app-error-notification-alert-modal",
|
|
21
31
|
width: "720px",
|
|
22
32
|
style: { "max-height": "100vh" }
|
|
23
33
|
}, {
|
|
24
34
|
title: p(() => [...o[2] ||= [i(" Errors ", -1)]]),
|
|
25
35
|
default: p(() => [r("div", b, [(s(!0), n(e, null, l(T.value, (e) => (s(), n("div", {
|
|
26
36
|
key: e[0],
|
|
37
|
+
"data-testid": "pl-app-error-notification-alert-item",
|
|
27
38
|
class: "pl-app-notification-alert__item"
|
|
28
|
-
}, [r("div", x, "Block output: " + u(e[0]), 1), a(d(g), {
|
|
39
|
+
}, [r("div", x, " Block output: " + u(e[0]), 1), a(d(g), {
|
|
40
|
+
"data-testid": "pl-app-error-notification-alert-log",
|
|
29
41
|
value: e[1]?.message,
|
|
30
42
|
valueToCopy: "fullMessage" in (e[1] ?? {}) ? e[1].fullMessage : e[1]?.message,
|
|
31
43
|
"download-filename": `output-${e[0]}-error.txt`
|
|
@@ -38,10 +50,12 @@ var y = { class: "pl-app-notification-alert" }, b = { class: "pl-app-notificatio
|
|
|
38
50
|
}, 8, ["modelValue"]), a(d(_), {
|
|
39
51
|
modelValue: w.value,
|
|
40
52
|
"onUpdate:modelValue": o[1] ||= (e) => w.value = e,
|
|
53
|
+
"data-testid": "pl-app-error-notification-alert-message",
|
|
41
54
|
type: "error",
|
|
42
55
|
closable: ""
|
|
43
56
|
}, {
|
|
44
57
|
actions: p(() => [a(d(m), {
|
|
58
|
+
"data-testid": "pl-app-error-notification-alert-show-errors",
|
|
45
59
|
icon: "arrow-right",
|
|
46
60
|
onClick: E
|
|
47
61
|
}, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAppErrorNotificationAlert.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { BlockOutputsBase } from \"@platforma-sdk/model\";\nimport type { OutputErrors } from \"../../types\";\n// @TODO module\nimport \"./pl-app-error-notification-alert.scss\";\nimport {\n PlBtnPrimary,\n PlDialogModal,\n PlNotificationAlert,\n PlSpacer,\n PlLogView,\n} from \"@milaboratories/uikit\";\nimport { computed, ref, watch } from \"vue\";\n\nexport type FullMessage = { fullMessage: string };\n\nconst props = defineProps<{ errors: OutputErrors<BlockOutputsBase> }>();\n\nconst isModalOpen = ref(false);\n\nconst isAlertOpen = ref(true);\n\nconst existingErrors = computed(() => Object.entries(props.errors).filter((item) => !!item[1]));\n\nfunction showErrors() {\n isModalOpen.value = true;\n}\n\n// @TODO (temp)\nwatch(\n () => props.errors,\n (errors) => {\n isAlertOpen.value = Object.values(errors).some((v) => !!v);\n },\n { immediate: true, deep: true },\n);\n</script>\n<template>\n <div class=\"pl-app-notification-alert\">\n <PlDialogModal
|
|
1
|
+
{"version":3,"file":"PlAppErrorNotificationAlert.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/PlAppErrorNotificationAlert/PlAppErrorNotificationAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { BlockOutputsBase } from \"@platforma-sdk/model\";\nimport type { OutputErrors } from \"../../types\";\n// @TODO module\nimport \"./pl-app-error-notification-alert.scss\";\nimport {\n PlBtnPrimary,\n PlDialogModal,\n PlNotificationAlert,\n PlSpacer,\n PlLogView,\n} from \"@milaboratories/uikit\";\nimport { computed, ref, watch } from \"vue\";\n\nexport type FullMessage = { fullMessage: string };\n\nconst props = defineProps<{ errors: OutputErrors<BlockOutputsBase> }>();\n\nconst isModalOpen = ref(false);\n\nconst isAlertOpen = ref(true);\n\nconst existingErrors = computed(() => Object.entries(props.errors).filter((item) => !!item[1]));\n\nfunction showErrors() {\n isModalOpen.value = true;\n}\n\n// @TODO (temp)\nwatch(\n () => props.errors,\n (errors) => {\n isAlertOpen.value = Object.values(errors).some((v) => !!v);\n },\n { immediate: true, deep: true },\n);\n</script>\n<template>\n <div data-testid=\"pl-app-error-notification-alert\" class=\"pl-app-notification-alert\">\n <PlDialogModal\n v-model=\"isModalOpen\"\n data-testid=\"pl-app-error-notification-alert-modal\"\n width=\"720px\"\n style=\"max-height: 100vh\"\n >\n <template #title> Errors </template>\n <div\n data-testid=\"pl-app-error-notification-alert-content\"\n class=\"pl-app-notification-alert__content\"\n >\n <template v-for=\"item in existingErrors\" :key=\"item[0]\">\n <div\n data-testid=\"pl-app-error-notification-alert-item\"\n class=\"pl-app-notification-alert__item\"\n >\n <div\n data-testid=\"pl-app-error-notification-alert-item-title\"\n class=\"pl-app-notification-alert__title\"\n >\n Block output: {{ item[0] }}\n </div>\n <PlLogView\n data-testid=\"pl-app-error-notification-alert-log\"\n :value=\"item[1]?.message\"\n :valueToCopy=\"\n 'fullMessage' in (item[1] ?? {})\n ? (item[1] as unknown as FullMessage).fullMessage\n : item[1]?.message\n \"\n :download-filename=\"`output-${item[0]}-error.txt`\"\n />\n </div>\n </template>\n </div>\n </PlDialogModal>\n\n <PlNotificationAlert\n v-model=\"isAlertOpen\"\n data-testid=\"pl-app-error-notification-alert-message\"\n type=\"error\"\n closable\n >\n Some outputs have errors.\n <template #actions>\n <PlBtnPrimary\n data-testid=\"pl-app-error-notification-alert-show-errors\"\n icon=\"arrow-right\"\n @click=\"showErrors\"\n >See errors</PlBtnPrimary\n >\n <PlSpacer />\n </template>\n </PlNotificationAlert>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;EAgBA,IAAM,IAAQ,GAER,IAAc,EAAI,GAAM,EAExB,IAAc,EAAI,GAAK,EAEvB,IAAiB,QAAe,OAAO,QAAQ,EAAM,OAAO,CAAC,QAAQ,MAAS,CAAC,CAAC,EAAK,GAAG,CAAC;EAE/F,SAAS,IAAa;AACpB,KAAY,QAAQ;;SAItB,QACQ,EAAM,SACX,MAAW;AACV,KAAY,QAAQ,OAAO,OAAO,EAAO,CAAC,MAAM,MAAM,CAAC,CAAC,EAAE;KAE5D;GAAE,WAAW;GAAM,MAAM;GAAM,CAChC,kBAGC,EAuDM,OAvDN,GAuDM,CAtDJ,EAmCgB,EAAA,EAAA,EAAA;eAlCL,EAAA;4CAAW,QAAA;GACpB,eAAY;GACZ,OAAM;GACN,OAAA,EAAA,cAAA,SAAyB;;GAEd,OAAK,QAAS,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAAR,YAAQ,GAAA,CAAA,CAAA,CAAA;oBA4BnB,CA3BN,EA2BM,OA3BN,GA2BM,EAAA,EAAA,GAAA,EAvBJ,EAsBW,GAAA,MAAA,EAtBc,EAAA,QAAR,YACf,EAoBM,OAAA;SArBuC,EAAI;IAE/C,eAAY;IACZ,OAAM;OAEN,EAKM,OALN,GAGC,oBACe,EAAG,EAAI,GAAA,EAAA,EAAA,EAEvB,EASE,EAAA,EAAA,EAAA;IARA,eAAY;IACX,OAAO,EAAI,IAAK;IAChB,aAAA,kBAAgD,EAAI,MAAA,EAAA,IAAgC,EAAI,GAA+B,cAAgC,EAAI,IAAK;IAKhK,qBAAiB,UAAY,EAAI,GAAA;;;;;;;yBAO5C,EAgBsB,EAAA,EAAA,EAAA;eAfX,EAAA;4CAAW,QAAA;GACpB,eAAY;GACZ,MAAK;GACL,UAAA;;GAGW,SAAO,QAMf,CALD,EAKC,EAAA,EAAA,EAAA;IAJC,eAAY;IACZ,MAAK;IACJ,SAAO;;qBACG,CAAA,GAAA,AAAA,EAAA,OAAA,CAAA,EAAV,cAAU,GAAA,CAAA,CAAA,CAAA;;OAEb,EAAY,EAAA,EAAA,CAAA,CAAA,CAAA;oBAPd,CAAA,AAAA,EAAA,OAAA,EAFD,+BAEC,GAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Item.js","names":[],"sources":["../../../src/components/PlBtnExportArchive/Item.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ExportItem } from \"./types\";\nimport { prettyBytes } from \"@milaboratories/helpers\";\n\ndefineProps<{\n item: ExportItem;\n}>();\n</script>\n\n<template>\n <div :class=\"$style.item\">\n <div :class=\"$style.name\"
|
|
1
|
+
{"version":3,"file":"Item.js","names":[],"sources":["../../../src/components/PlBtnExportArchive/Item.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ExportItem } from \"./types\";\nimport { prettyBytes } from \"@milaboratories/helpers\";\n\ndefineProps<{\n item: ExportItem;\n}>();\n</script>\n\n<template>\n <div data-testid=\"pl-btn-export-archive-item\" :class=\"$style.item\">\n <div data-testid=\"pl-btn-export-archive-item-name\" :class=\"$style.name\">\n {{ item.fileName }}\n </div>\n <div\n v-if=\"item.status === 'in-progress'\"\n data-testid=\"pl-btn-export-archive-item-status\"\n :class=\"$style.details\"\n >\n <span>{{ prettyBytes(item.current, {}) }}</span>\n <span>/</span>\n <span>{{ prettyBytes(item.size, {}) }}</span>\n </div>\n <div\n v-else-if=\"item.status === 'completed'\"\n data-testid=\"pl-btn-export-archive-item-status\"\n :class=\"$style.details\"\n >\n Done <span>{{ prettyBytes(item.size, {}) }}</span>\n </div>\n <div\n v-else-if=\"item.status === 'error'\"\n data-testid=\"pl-btn-export-archive-item-error\"\n :class=\"$style.error\"\n >\n <span>{{ item.error }}</span>\n </div>\n <div v-else data-testid=\"pl-btn-export-archive-item-status\" :class=\"$style.details\">\n Pending\n </div>\n </div>\n</template>\n\n<style module>\n.item {\n display: flex;\n flex-direction: column;\n margin-bottom: 8px;\n overflow: hidden;\n --name-font-size: 12px;\n --details-font-size: 10px;\n}\n.name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: var(--name-font-size);\n font-weight: 600;\n}\n\n.details {\n font-size: var(--details-font-size);\n font-weight: 400;\n color: rgba(255, 255, 255, 0.6);\n}\n\n.error {\n font-size: var(--details-font-size);\n font-weight: 400;\n color: var(--txt-error);\n span {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Item.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../src/components/PlBtnExportArchive/Item.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ExportItem } from \"./types\";\nimport { prettyBytes } from \"@milaboratories/helpers\";\n\ndefineProps<{\n item: ExportItem;\n}>();\n</script>\n\n<template>\n <div :class=\"$style.item\">\n <div :class=\"$style.name\"
|
|
1
|
+
{"version":3,"file":"Item.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../src/components/PlBtnExportArchive/Item.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ExportItem } from \"./types\";\nimport { prettyBytes } from \"@milaboratories/helpers\";\n\ndefineProps<{\n item: ExportItem;\n}>();\n</script>\n\n<template>\n <div data-testid=\"pl-btn-export-archive-item\" :class=\"$style.item\">\n <div data-testid=\"pl-btn-export-archive-item-name\" :class=\"$style.name\">\n {{ item.fileName }}\n </div>\n <div\n v-if=\"item.status === 'in-progress'\"\n data-testid=\"pl-btn-export-archive-item-status\"\n :class=\"$style.details\"\n >\n <span>{{ prettyBytes(item.current, {}) }}</span>\n <span>/</span>\n <span>{{ prettyBytes(item.size, {}) }}</span>\n </div>\n <div\n v-else-if=\"item.status === 'completed'\"\n data-testid=\"pl-btn-export-archive-item-status\"\n :class=\"$style.details\"\n >\n Done <span>{{ prettyBytes(item.size, {}) }}</span>\n </div>\n <div\n v-else-if=\"item.status === 'error'\"\n data-testid=\"pl-btn-export-archive-item-error\"\n :class=\"$style.error\"\n >\n <span>{{ item.error }}</span>\n </div>\n <div v-else data-testid=\"pl-btn-export-archive-item-status\" :class=\"$style.details\">\n Pending\n </div>\n </div>\n</template>\n\n<style module>\n.item {\n display: flex;\n flex-direction: column;\n margin-bottom: 8px;\n overflow: hidden;\n --name-font-size: 12px;\n --details-font-size: 10px;\n}\n.name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: var(--name-font-size);\n font-weight: 600;\n}\n\n.details {\n font-size: var(--details-font-size);\n font-weight: 400;\n color: rgba(255, 255, 255, 0.6);\n}\n\n.error {\n font-size: var(--details-font-size);\n font-weight: 400;\n color: var(--txt-error);\n span {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Item.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlBtnExportArchive/Item.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Item.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlBtnExportArchive/Item.vue"],"names":[],"mappings":"AAiFA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AA+EF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -6,8 +6,15 @@ var l = /* @__PURE__ */ i({
|
|
|
6
6
|
__name: "Item",
|
|
7
7
|
props: { item: {} },
|
|
8
8
|
setup(i) {
|
|
9
|
-
return (l, u) => (o(), t("div", {
|
|
9
|
+
return (l, u) => (o(), t("div", {
|
|
10
|
+
"data-testid": "pl-btn-export-archive-item",
|
|
11
|
+
class: a(l.$style.item)
|
|
12
|
+
}, [n("div", {
|
|
13
|
+
"data-testid": "pl-btn-export-archive-item-name",
|
|
14
|
+
class: a(l.$style.name)
|
|
15
|
+
}, s(i.item.fileName), 3), i.item.status === "in-progress" ? (o(), t("div", {
|
|
10
16
|
key: 0,
|
|
17
|
+
"data-testid": "pl-btn-export-archive-item-status",
|
|
11
18
|
class: a(l.$style.details)
|
|
12
19
|
}, [
|
|
13
20
|
n("span", null, s(c(e)(i.item.current, {})), 1),
|
|
@@ -15,14 +22,17 @@ var l = /* @__PURE__ */ i({
|
|
|
15
22
|
n("span", null, s(c(e)(i.item.size, {})), 1)
|
|
16
23
|
], 2)) : i.item.status === "completed" ? (o(), t("div", {
|
|
17
24
|
key: 1,
|
|
25
|
+
"data-testid": "pl-btn-export-archive-item-status",
|
|
18
26
|
class: a(l.$style.details)
|
|
19
27
|
}, [u[1] ||= r(" Done ", -1), n("span", null, s(c(e)(i.item.size, {})), 1)], 2)) : i.item.status === "error" ? (o(), t("div", {
|
|
20
28
|
key: 2,
|
|
29
|
+
"data-testid": "pl-btn-export-archive-item-error",
|
|
21
30
|
class: a(l.$style.error)
|
|
22
31
|
}, [n("span", null, s(i.item.error), 1)], 2)) : (o(), t("div", {
|
|
23
32
|
key: 3,
|
|
33
|
+
"data-testid": "pl-btn-export-archive-item-status",
|
|
24
34
|
class: a(l.$style.details)
|
|
25
|
-
}, "Pending", 2))], 2));
|
|
35
|
+
}, " Pending ", 2))], 2));
|
|
26
36
|
}
|
|
27
37
|
});
|
|
28
38
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Item.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../src/components/PlBtnExportArchive/Item.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ExportItem } from \"./types\";\nimport { prettyBytes } from \"@milaboratories/helpers\";\n\ndefineProps<{\n item: ExportItem;\n}>();\n</script>\n\n<template>\n <div :class=\"$style.item\">\n <div :class=\"$style.name\"
|
|
1
|
+
{"version":3,"file":"Item.vue_vue_type_script_setup_true_lang.js","names":["$style"],"sources":["../../../src/components/PlBtnExportArchive/Item.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ExportItem } from \"./types\";\nimport { prettyBytes } from \"@milaboratories/helpers\";\n\ndefineProps<{\n item: ExportItem;\n}>();\n</script>\n\n<template>\n <div data-testid=\"pl-btn-export-archive-item\" :class=\"$style.item\">\n <div data-testid=\"pl-btn-export-archive-item-name\" :class=\"$style.name\">\n {{ item.fileName }}\n </div>\n <div\n v-if=\"item.status === 'in-progress'\"\n data-testid=\"pl-btn-export-archive-item-status\"\n :class=\"$style.details\"\n >\n <span>{{ prettyBytes(item.current, {}) }}</span>\n <span>/</span>\n <span>{{ prettyBytes(item.size, {}) }}</span>\n </div>\n <div\n v-else-if=\"item.status === 'completed'\"\n data-testid=\"pl-btn-export-archive-item-status\"\n :class=\"$style.details\"\n >\n Done <span>{{ prettyBytes(item.size, {}) }}</span>\n </div>\n <div\n v-else-if=\"item.status === 'error'\"\n data-testid=\"pl-btn-export-archive-item-error\"\n :class=\"$style.error\"\n >\n <span>{{ item.error }}</span>\n </div>\n <div v-else data-testid=\"pl-btn-export-archive-item-status\" :class=\"$style.details\">\n Pending\n </div>\n </div>\n</template>\n\n<style module>\n.item {\n display: flex;\n flex-direction: column;\n margin-bottom: 8px;\n overflow: hidden;\n --name-font-size: 12px;\n --details-font-size: 10px;\n}\n.name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: var(--name-font-size);\n font-weight: 600;\n}\n\n.details {\n font-size: var(--details-font-size);\n font-weight: 400;\n color: rgba(255, 255, 255, 0.6);\n}\n\n.error {\n font-size: var(--details-font-size);\n font-weight: 400;\n color: var(--txt-error);\n span {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n }\n}\n</style>\n"],"mappings":";;;;;;;;yBAUE,EA8BM,OAAA;GA9BD,eAAY;GAA8B,OAAK,EAAEA,EAAAA,OAAO,KAAI;MAC/D,EAEM,OAAA;GAFD,eAAY;GAAmC,OAAK,EAAEA,EAAAA,OAAO,KAAI;OACjE,EAAA,KAAK,SAAQ,EAAA,EAAA,EAGV,EAAA,KAAK,WAAM,iBAAA,GAAA,EADnB,EAQM,OAAA;;GANJ,eAAY;GACX,OAAK,EAAEA,EAAAA,OAAO,QAAO;;GAEtB,EAAgD,QAAA,MAAA,EAAvC,EAAA,EAAW,CAAC,EAAA,KAAK,SAAO,EAAA,CAAA,CAAA,EAAA,EAAA;YACjC,EAAc,QAAA,MAAR,KAAC,GAAA;GACP,EAA6C,QAAA,MAAA,EAApC,EAAA,EAAW,CAAC,EAAA,KAAK,MAAI,EAAA,CAAA,CAAA,EAAA,EAAA;WAGnB,EAAA,KAAK,WAAM,eAAA,GAAA,EADxB,EAMM,OAAA;;GAJJ,eAAY;GACX,OAAK,EAAEA,EAAAA,OAAO,QAAO;iBACvB,UACM,GAAA,EAAA,EAA6C,QAAA,MAAA,EAApC,EAAA,EAAW,CAAC,EAAA,KAAK,MAAI,EAAA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,EAAA,IAGxB,EAAA,KAAK,WAAM,WAAA,GAAA,EADxB,EAMM,OAAA;;GAJJ,eAAY;GACX,OAAK,EAAEA,EAAAA,OAAO,MAAK;MAEpB,EAA6B,QAAA,MAAA,EAApB,EAAA,KAAK,MAAK,EAAA,EAAA,CAAA,EAAA,EAAA,KAAA,GAAA,EAErB,EAEM,OAAA;;GAFM,eAAY;GAAqC,OAAK,EAAEA,EAAAA,OAAO,QAAO;KAAE,aAEpF,EAAA,EAAA,EAAA,EAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlBtnExportArchive.js","names":[],"sources":["../../../src/components/PlBtnExportArchive/PlBtnExportArchive.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlBtnGhost, PlIcon16, PlIcon24, useClickOutside } from \"@milaboratories/uikit\";\nimport { ZipWriter } from \"@zip.js/zip.js\";\nimport { reactive, computed, ref } from \"vue\";\nimport type { ExportItem, ExportsMap, FileExportEntry } from \"./types\";\nimport Item from \"./Item.vue\";\nimport { getFileNameFromHandle, ChunkedStreamReader } from \"@platforma-sdk/model\";\nimport { getRawPlatformaInstance } from \"@platforma-sdk/model\";\nimport { uniqueId } from \"@milaboratories/helpers\";\nimport Summary from \"./Summary.vue\";\n\ntype FilePickerAcceptType = {\n description?: string;\n accept?: Record<string, string[]>;\n};\n\nconst props = defineProps<{\n fileExports?: FileExportEntry[];\n suggestedFileName?: string;\n disabled?: boolean;\n filePickerTypes?: FilePickerAcceptType[];\n strategy?: \"parallel\"; // default is sequential\n debugFn?: (fileName: string) => Promise<void>;\n}>();\n\nconst defaultData = () => ({\n loading: false,\n name: \"\",\n exports: undefined as ExportsMap | undefined,\n showExports: false,\n});\n\nconst data = reactive(defaultData());\n\nconst updateExportsItem = (id: string, partial: Partial<ExportItem>) => {\n const it = data.exports?.get(id);\n if (it) {\n data.exports?.set(id, { ...it, ...partial });\n }\n};\n\nconst isReadyToExport = computed(() => {\n return props.fileExports !== undefined && !props.disabled;\n});\n\nconst items = computed(() => {\n return Array.from(data.exports?.values() ?? []);\n});\n\nconst archive = computed<ExportItem>(() => {\n return {\n fileName: data.name,\n current: items.value.reduce((acc, item) => acc + item.current, 0),\n size: items.value.reduce((acc, item) => acc + item.size, 0),\n status: items.value.some((item) => item.status === \"in-progress\")\n ? \"in-progress\"\n : items.value.every((item) => item.status === \"completed\")\n ? \"completed\"\n : \"pending\",\n hasErrors: items.value.some((item) => item.status === \"error\"),\n };\n});\n\ntype ZipRequest = {\n id: string;\n fileName: string;\n size: number;\n stream: ReadableStream<Uint8Array>;\n};\n\nconst exportRawTsvs = async () => {\n if (data.loading) {\n data.showExports = true;\n return;\n }\n\n if (!isReadyToExport.value || !props.fileExports) {\n return;\n }\n\n const defaultFileName = `${new Date().toISOString().split(\"T\")[0]}_Export.zip`;\n const defaultTypes = [\n {\n description: \"ZIP files\",\n accept: {\n \"application/zip\": [\".zip\"],\n },\n },\n ];\n\n // @ts-expect-error - type definition issue TODO: fix this\n const newHandle = await window.showSaveFilePicker({\n types: props.filePickerTypes || defaultTypes,\n suggestedName: props.suggestedFileName || defaultFileName,\n });\n\n data.loading = true;\n data.name = newHandle.name;\n data.showExports = true;\n data.exports = new Map();\n\n try {\n const writableStream = await newHandle.createWritable();\n const zip = new ZipWriter(writableStream, {\n keepOrder: true,\n zip64: true,\n bufferedWrite: false,\n });\n try {\n const requests = [] as ZipRequest[];\n\n for (const entry of props.fileExports) {\n const { importHandle, blobHandle, fileName: customFileName } = entry;\n const fileName = customFileName ?? getFileNameFromHandle(importHandle);\n const { handle, size } = blobHandle;\n\n const id = uniqueId();\n\n data.exports?.set(id, { fileName, current: 0, size, status: \"pending\" });\n\n const stream = ChunkedStreamReader.create({\n fetchChunk: async ({ from, to }) => {\n if (props.debugFn) {\n await props.debugFn(fileName);\n }\n\n return await getRawPlatformaInstance().blobDriver.getContent(handle, { from, to });\n },\n totalSize: size,\n onError: async (error) => {\n updateExportsItem(id, { status: \"error\", error });\n await new Promise((resolve) => setTimeout(resolve, 1000)); // primitive for now\n return \"continue\";\n },\n });\n\n // Create a chunked stream reader for efficient streaming\n requests.push({ id, fileName, size, stream });\n }\n\n const processRequest = async (request: ZipRequest) => {\n const { id, fileName, size, stream } = request;\n const update = (partial: Partial<ExportItem>) => {\n const it = data.exports?.get(id);\n if (it) {\n data.exports?.set(id, { ...it, ...partial });\n }\n };\n await zip.add(fileName, stream, {\n bufferedWrite: true,\n onstart: () => {\n update({ status: \"in-progress\" });\n return undefined;\n },\n onprogress: (current: number) => {\n update({ current, status: \"in-progress\" });\n return undefined;\n },\n onend() {\n update({ current: size, status: \"completed\" });\n return undefined;\n },\n });\n };\n\n if (props.strategy === \"parallel\") {\n await Promise.all(requests.map(processRequest));\n } else {\n for (const request of requests) {\n await processRequest(request);\n }\n }\n } finally {\n await zip.close().catch((error) => {\n console.error(\"Error closing zip\", error);\n });\n }\n } finally {\n data.loading = false;\n }\n};\n\nconst progressesRef = ref();\n\nuseClickOutside([progressesRef], () => {\n data.showExports = false;\n});\n</script>\n\n<template>\n <PlBtnGhost\n :disabled=\"!isReadyToExport\"\n :loading=\"data.loading\"\n :class=\"{ [$style['has-exports']]: data.exports }\"\n @click.stop=\"exportRawTsvs\"\n >\n <slot />\n <template #append>\n <PlIcon24 :class=\"$style.icon\" name=\"download\" />\n </template>\n </PlBtnGhost>\n <Teleport to=\"body\">\n <div
|
|
1
|
+
{"version":3,"file":"PlBtnExportArchive.js","names":[],"sources":["../../../src/components/PlBtnExportArchive/PlBtnExportArchive.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlBtnGhost, PlIcon16, PlIcon24, useClickOutside } from \"@milaboratories/uikit\";\nimport { ZipWriter } from \"@zip.js/zip.js\";\nimport { reactive, computed, ref } from \"vue\";\nimport type { ExportItem, ExportsMap, FileExportEntry } from \"./types\";\nimport Item from \"./Item.vue\";\nimport { getFileNameFromHandle, ChunkedStreamReader } from \"@platforma-sdk/model\";\nimport { getRawPlatformaInstance } from \"@platforma-sdk/model\";\nimport { uniqueId } from \"@milaboratories/helpers\";\nimport Summary from \"./Summary.vue\";\n\ntype FilePickerAcceptType = {\n description?: string;\n accept?: Record<string, string[]>;\n};\n\nconst props = defineProps<{\n fileExports?: FileExportEntry[];\n suggestedFileName?: string;\n disabled?: boolean;\n filePickerTypes?: FilePickerAcceptType[];\n strategy?: \"parallel\"; // default is sequential\n debugFn?: (fileName: string) => Promise<void>;\n}>();\n\nconst defaultData = () => ({\n loading: false,\n name: \"\",\n exports: undefined as ExportsMap | undefined,\n showExports: false,\n});\n\nconst data = reactive(defaultData());\n\nconst updateExportsItem = (id: string, partial: Partial<ExportItem>) => {\n const it = data.exports?.get(id);\n if (it) {\n data.exports?.set(id, { ...it, ...partial });\n }\n};\n\nconst isReadyToExport = computed(() => {\n return props.fileExports !== undefined && !props.disabled;\n});\n\nconst items = computed(() => {\n return Array.from(data.exports?.values() ?? []);\n});\n\nconst archive = computed<ExportItem>(() => {\n return {\n fileName: data.name,\n current: items.value.reduce((acc, item) => acc + item.current, 0),\n size: items.value.reduce((acc, item) => acc + item.size, 0),\n status: items.value.some((item) => item.status === \"in-progress\")\n ? \"in-progress\"\n : items.value.every((item) => item.status === \"completed\")\n ? \"completed\"\n : \"pending\",\n hasErrors: items.value.some((item) => item.status === \"error\"),\n };\n});\n\ntype ZipRequest = {\n id: string;\n fileName: string;\n size: number;\n stream: ReadableStream<Uint8Array>;\n};\n\nconst exportRawTsvs = async () => {\n if (data.loading) {\n data.showExports = true;\n return;\n }\n\n if (!isReadyToExport.value || !props.fileExports) {\n return;\n }\n\n const defaultFileName = `${new Date().toISOString().split(\"T\")[0]}_Export.zip`;\n const defaultTypes = [\n {\n description: \"ZIP files\",\n accept: {\n \"application/zip\": [\".zip\"],\n },\n },\n ];\n\n // @ts-expect-error - type definition issue TODO: fix this\n const newHandle = await window.showSaveFilePicker({\n types: props.filePickerTypes || defaultTypes,\n suggestedName: props.suggestedFileName || defaultFileName,\n });\n\n data.loading = true;\n data.name = newHandle.name;\n data.showExports = true;\n data.exports = new Map();\n\n try {\n const writableStream = await newHandle.createWritable();\n const zip = new ZipWriter(writableStream, {\n keepOrder: true,\n zip64: true,\n bufferedWrite: false,\n });\n try {\n const requests = [] as ZipRequest[];\n\n for (const entry of props.fileExports) {\n const { importHandle, blobHandle, fileName: customFileName } = entry;\n const fileName = customFileName ?? getFileNameFromHandle(importHandle);\n const { handle, size } = blobHandle;\n\n const id = uniqueId();\n\n data.exports?.set(id, { fileName, current: 0, size, status: \"pending\" });\n\n const stream = ChunkedStreamReader.create({\n fetchChunk: async ({ from, to }) => {\n if (props.debugFn) {\n await props.debugFn(fileName);\n }\n\n return await getRawPlatformaInstance().blobDriver.getContent(handle, { from, to });\n },\n totalSize: size,\n onError: async (error) => {\n updateExportsItem(id, { status: \"error\", error });\n await new Promise((resolve) => setTimeout(resolve, 1000)); // primitive for now\n return \"continue\";\n },\n });\n\n // Create a chunked stream reader for efficient streaming\n requests.push({ id, fileName, size, stream });\n }\n\n const processRequest = async (request: ZipRequest) => {\n const { id, fileName, size, stream } = request;\n const update = (partial: Partial<ExportItem>) => {\n const it = data.exports?.get(id);\n if (it) {\n data.exports?.set(id, { ...it, ...partial });\n }\n };\n await zip.add(fileName, stream, {\n bufferedWrite: true,\n onstart: () => {\n update({ status: \"in-progress\" });\n return undefined;\n },\n onprogress: (current: number) => {\n update({ current, status: \"in-progress\" });\n return undefined;\n },\n onend() {\n update({ current: size, status: \"completed\" });\n return undefined;\n },\n });\n };\n\n if (props.strategy === \"parallel\") {\n await Promise.all(requests.map(processRequest));\n } else {\n for (const request of requests) {\n await processRequest(request);\n }\n }\n } finally {\n await zip.close().catch((error) => {\n console.error(\"Error closing zip\", error);\n });\n }\n } finally {\n data.loading = false;\n }\n};\n\nconst progressesRef = ref();\n\nuseClickOutside([progressesRef], () => {\n data.showExports = false;\n});\n</script>\n\n<template>\n <PlBtnGhost\n data-testid=\"pl-btn-export-archive\"\n :disabled=\"!isReadyToExport\"\n :loading=\"data.loading\"\n :class=\"{ [$style['has-exports']]: data.exports }\"\n @click.stop=\"exportRawTsvs\"\n >\n <slot />\n <template #append>\n <PlIcon24 :class=\"$style.icon\" name=\"download\" />\n </template>\n </PlBtnGhost>\n <Teleport to=\"body\">\n <div\n v-if=\"data.exports && data.showExports\"\n ref=\"progressesRef\"\n data-testid=\"pl-btn-export-archive-progress\"\n :class=\"$style.progresses\"\n >\n <PlIcon16\n data-testid=\"pl-btn-export-archive-progress-close\"\n :class=\"$style.close\"\n name=\"close\"\n @click.stop=\"data.showExports = false\"\n />\n <Summary :item=\"archive\" />\n <div\n data-testid=\"pl-btn-export-archive-items\"\n :class=\"$style.itemsContainer\"\n class=\"pl-scrollable-y\"\n >\n <Item v-for=\"item in data.exports?.values()\" :key=\"item.fileName\" :item=\"item\" />\n </div>\n </div>\n </Teleport>\n</template>\n\n<style module>\n.progresses {\n position: fixed;\n top: 8px;\n right: 8px;\n width: 350px;\n height: auto;\n max-height: 400px;\n overflow: auto;\n background: rgba(0, 0, 0, 0.85);\n border-radius: 8px;\n padding: 20px 8px 8px 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n z-index: 1000;\n\n .itemsContainer {\n max-height: 300px;\n }\n\n .close {\n position: absolute;\n top: 8px;\n right: 8px;\n cursor: pointer;\n --icon-color: white;\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlBtnExportArchive.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../src/components/PlBtnExportArchive/PlBtnExportArchive.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlBtnGhost, PlIcon16, PlIcon24, useClickOutside } from \"@milaboratories/uikit\";\nimport { ZipWriter } from \"@zip.js/zip.js\";\nimport { reactive, computed, ref } from \"vue\";\nimport type { ExportItem, ExportsMap, FileExportEntry } from \"./types\";\nimport Item from \"./Item.vue\";\nimport { getFileNameFromHandle, ChunkedStreamReader } from \"@platforma-sdk/model\";\nimport { getRawPlatformaInstance } from \"@platforma-sdk/model\";\nimport { uniqueId } from \"@milaboratories/helpers\";\nimport Summary from \"./Summary.vue\";\n\ntype FilePickerAcceptType = {\n description?: string;\n accept?: Record<string, string[]>;\n};\n\nconst props = defineProps<{\n fileExports?: FileExportEntry[];\n suggestedFileName?: string;\n disabled?: boolean;\n filePickerTypes?: FilePickerAcceptType[];\n strategy?: \"parallel\"; // default is sequential\n debugFn?: (fileName: string) => Promise<void>;\n}>();\n\nconst defaultData = () => ({\n loading: false,\n name: \"\",\n exports: undefined as ExportsMap | undefined,\n showExports: false,\n});\n\nconst data = reactive(defaultData());\n\nconst updateExportsItem = (id: string, partial: Partial<ExportItem>) => {\n const it = data.exports?.get(id);\n if (it) {\n data.exports?.set(id, { ...it, ...partial });\n }\n};\n\nconst isReadyToExport = computed(() => {\n return props.fileExports !== undefined && !props.disabled;\n});\n\nconst items = computed(() => {\n return Array.from(data.exports?.values() ?? []);\n});\n\nconst archive = computed<ExportItem>(() => {\n return {\n fileName: data.name,\n current: items.value.reduce((acc, item) => acc + item.current, 0),\n size: items.value.reduce((acc, item) => acc + item.size, 0),\n status: items.value.some((item) => item.status === \"in-progress\")\n ? \"in-progress\"\n : items.value.every((item) => item.status === \"completed\")\n ? \"completed\"\n : \"pending\",\n hasErrors: items.value.some((item) => item.status === \"error\"),\n };\n});\n\ntype ZipRequest = {\n id: string;\n fileName: string;\n size: number;\n stream: ReadableStream<Uint8Array>;\n};\n\nconst exportRawTsvs = async () => {\n if (data.loading) {\n data.showExports = true;\n return;\n }\n\n if (!isReadyToExport.value || !props.fileExports) {\n return;\n }\n\n const defaultFileName = `${new Date().toISOString().split(\"T\")[0]}_Export.zip`;\n const defaultTypes = [\n {\n description: \"ZIP files\",\n accept: {\n \"application/zip\": [\".zip\"],\n },\n },\n ];\n\n // @ts-expect-error - type definition issue TODO: fix this\n const newHandle = await window.showSaveFilePicker({\n types: props.filePickerTypes || defaultTypes,\n suggestedName: props.suggestedFileName || defaultFileName,\n });\n\n data.loading = true;\n data.name = newHandle.name;\n data.showExports = true;\n data.exports = new Map();\n\n try {\n const writableStream = await newHandle.createWritable();\n const zip = new ZipWriter(writableStream, {\n keepOrder: true,\n zip64: true,\n bufferedWrite: false,\n });\n try {\n const requests = [] as ZipRequest[];\n\n for (const entry of props.fileExports) {\n const { importHandle, blobHandle, fileName: customFileName } = entry;\n const fileName = customFileName ?? getFileNameFromHandle(importHandle);\n const { handle, size } = blobHandle;\n\n const id = uniqueId();\n\n data.exports?.set(id, { fileName, current: 0, size, status: \"pending\" });\n\n const stream = ChunkedStreamReader.create({\n fetchChunk: async ({ from, to }) => {\n if (props.debugFn) {\n await props.debugFn(fileName);\n }\n\n return await getRawPlatformaInstance().blobDriver.getContent(handle, { from, to });\n },\n totalSize: size,\n onError: async (error) => {\n updateExportsItem(id, { status: \"error\", error });\n await new Promise((resolve) => setTimeout(resolve, 1000)); // primitive for now\n return \"continue\";\n },\n });\n\n // Create a chunked stream reader for efficient streaming\n requests.push({ id, fileName, size, stream });\n }\n\n const processRequest = async (request: ZipRequest) => {\n const { id, fileName, size, stream } = request;\n const update = (partial: Partial<ExportItem>) => {\n const it = data.exports?.get(id);\n if (it) {\n data.exports?.set(id, { ...it, ...partial });\n }\n };\n await zip.add(fileName, stream, {\n bufferedWrite: true,\n onstart: () => {\n update({ status: \"in-progress\" });\n return undefined;\n },\n onprogress: (current: number) => {\n update({ current, status: \"in-progress\" });\n return undefined;\n },\n onend() {\n update({ current: size, status: \"completed\" });\n return undefined;\n },\n });\n };\n\n if (props.strategy === \"parallel\") {\n await Promise.all(requests.map(processRequest));\n } else {\n for (const request of requests) {\n await processRequest(request);\n }\n }\n } finally {\n await zip.close().catch((error) => {\n console.error(\"Error closing zip\", error);\n });\n }\n } finally {\n data.loading = false;\n }\n};\n\nconst progressesRef = ref();\n\nuseClickOutside([progressesRef], () => {\n data.showExports = false;\n});\n</script>\n\n<template>\n <PlBtnGhost\n :disabled=\"!isReadyToExport\"\n :loading=\"data.loading\"\n :class=\"{ [$style['has-exports']]: data.exports }\"\n @click.stop=\"exportRawTsvs\"\n >\n <slot />\n <template #append>\n <PlIcon24 :class=\"$style.icon\" name=\"download\" />\n </template>\n </PlBtnGhost>\n <Teleport to=\"body\">\n <div
|
|
1
|
+
{"version":3,"file":"PlBtnExportArchive.vue_vue_type_style_index_0_lang.module.js","names":[],"sources":["../../../src/components/PlBtnExportArchive/PlBtnExportArchive.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PlBtnGhost, PlIcon16, PlIcon24, useClickOutside } from \"@milaboratories/uikit\";\nimport { ZipWriter } from \"@zip.js/zip.js\";\nimport { reactive, computed, ref } from \"vue\";\nimport type { ExportItem, ExportsMap, FileExportEntry } from \"./types\";\nimport Item from \"./Item.vue\";\nimport { getFileNameFromHandle, ChunkedStreamReader } from \"@platforma-sdk/model\";\nimport { getRawPlatformaInstance } from \"@platforma-sdk/model\";\nimport { uniqueId } from \"@milaboratories/helpers\";\nimport Summary from \"./Summary.vue\";\n\ntype FilePickerAcceptType = {\n description?: string;\n accept?: Record<string, string[]>;\n};\n\nconst props = defineProps<{\n fileExports?: FileExportEntry[];\n suggestedFileName?: string;\n disabled?: boolean;\n filePickerTypes?: FilePickerAcceptType[];\n strategy?: \"parallel\"; // default is sequential\n debugFn?: (fileName: string) => Promise<void>;\n}>();\n\nconst defaultData = () => ({\n loading: false,\n name: \"\",\n exports: undefined as ExportsMap | undefined,\n showExports: false,\n});\n\nconst data = reactive(defaultData());\n\nconst updateExportsItem = (id: string, partial: Partial<ExportItem>) => {\n const it = data.exports?.get(id);\n if (it) {\n data.exports?.set(id, { ...it, ...partial });\n }\n};\n\nconst isReadyToExport = computed(() => {\n return props.fileExports !== undefined && !props.disabled;\n});\n\nconst items = computed(() => {\n return Array.from(data.exports?.values() ?? []);\n});\n\nconst archive = computed<ExportItem>(() => {\n return {\n fileName: data.name,\n current: items.value.reduce((acc, item) => acc + item.current, 0),\n size: items.value.reduce((acc, item) => acc + item.size, 0),\n status: items.value.some((item) => item.status === \"in-progress\")\n ? \"in-progress\"\n : items.value.every((item) => item.status === \"completed\")\n ? \"completed\"\n : \"pending\",\n hasErrors: items.value.some((item) => item.status === \"error\"),\n };\n});\n\ntype ZipRequest = {\n id: string;\n fileName: string;\n size: number;\n stream: ReadableStream<Uint8Array>;\n};\n\nconst exportRawTsvs = async () => {\n if (data.loading) {\n data.showExports = true;\n return;\n }\n\n if (!isReadyToExport.value || !props.fileExports) {\n return;\n }\n\n const defaultFileName = `${new Date().toISOString().split(\"T\")[0]}_Export.zip`;\n const defaultTypes = [\n {\n description: \"ZIP files\",\n accept: {\n \"application/zip\": [\".zip\"],\n },\n },\n ];\n\n // @ts-expect-error - type definition issue TODO: fix this\n const newHandle = await window.showSaveFilePicker({\n types: props.filePickerTypes || defaultTypes,\n suggestedName: props.suggestedFileName || defaultFileName,\n });\n\n data.loading = true;\n data.name = newHandle.name;\n data.showExports = true;\n data.exports = new Map();\n\n try {\n const writableStream = await newHandle.createWritable();\n const zip = new ZipWriter(writableStream, {\n keepOrder: true,\n zip64: true,\n bufferedWrite: false,\n });\n try {\n const requests = [] as ZipRequest[];\n\n for (const entry of props.fileExports) {\n const { importHandle, blobHandle, fileName: customFileName } = entry;\n const fileName = customFileName ?? getFileNameFromHandle(importHandle);\n const { handle, size } = blobHandle;\n\n const id = uniqueId();\n\n data.exports?.set(id, { fileName, current: 0, size, status: \"pending\" });\n\n const stream = ChunkedStreamReader.create({\n fetchChunk: async ({ from, to }) => {\n if (props.debugFn) {\n await props.debugFn(fileName);\n }\n\n return await getRawPlatformaInstance().blobDriver.getContent(handle, { from, to });\n },\n totalSize: size,\n onError: async (error) => {\n updateExportsItem(id, { status: \"error\", error });\n await new Promise((resolve) => setTimeout(resolve, 1000)); // primitive for now\n return \"continue\";\n },\n });\n\n // Create a chunked stream reader for efficient streaming\n requests.push({ id, fileName, size, stream });\n }\n\n const processRequest = async (request: ZipRequest) => {\n const { id, fileName, size, stream } = request;\n const update = (partial: Partial<ExportItem>) => {\n const it = data.exports?.get(id);\n if (it) {\n data.exports?.set(id, { ...it, ...partial });\n }\n };\n await zip.add(fileName, stream, {\n bufferedWrite: true,\n onstart: () => {\n update({ status: \"in-progress\" });\n return undefined;\n },\n onprogress: (current: number) => {\n update({ current, status: \"in-progress\" });\n return undefined;\n },\n onend() {\n update({ current: size, status: \"completed\" });\n return undefined;\n },\n });\n };\n\n if (props.strategy === \"parallel\") {\n await Promise.all(requests.map(processRequest));\n } else {\n for (const request of requests) {\n await processRequest(request);\n }\n }\n } finally {\n await zip.close().catch((error) => {\n console.error(\"Error closing zip\", error);\n });\n }\n } finally {\n data.loading = false;\n }\n};\n\nconst progressesRef = ref();\n\nuseClickOutside([progressesRef], () => {\n data.showExports = false;\n});\n</script>\n\n<template>\n <PlBtnGhost\n data-testid=\"pl-btn-export-archive\"\n :disabled=\"!isReadyToExport\"\n :loading=\"data.loading\"\n :class=\"{ [$style['has-exports']]: data.exports }\"\n @click.stop=\"exportRawTsvs\"\n >\n <slot />\n <template #append>\n <PlIcon24 :class=\"$style.icon\" name=\"download\" />\n </template>\n </PlBtnGhost>\n <Teleport to=\"body\">\n <div\n v-if=\"data.exports && data.showExports\"\n ref=\"progressesRef\"\n data-testid=\"pl-btn-export-archive-progress\"\n :class=\"$style.progresses\"\n >\n <PlIcon16\n data-testid=\"pl-btn-export-archive-progress-close\"\n :class=\"$style.close\"\n name=\"close\"\n @click.stop=\"data.showExports = false\"\n />\n <Summary :item=\"archive\" />\n <div\n data-testid=\"pl-btn-export-archive-items\"\n :class=\"$style.itemsContainer\"\n class=\"pl-scrollable-y\"\n >\n <Item v-for=\"item in data.exports?.values()\" :key=\"item.fileName\" :item=\"item\" />\n </div>\n </div>\n </Teleport>\n</template>\n\n<style module>\n.progresses {\n position: fixed;\n top: 8px;\n right: 8px;\n width: 350px;\n height: auto;\n max-height: 400px;\n overflow: auto;\n background: rgba(0, 0, 0, 0.85);\n border-radius: 8px;\n padding: 20px 8px 8px 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n z-index: 1000;\n\n .itemsContainer {\n max-height: 300px;\n }\n\n .close {\n position: absolute;\n top: 8px;\n right: 8px;\n cursor: pointer;\n --icon-color: white;\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlBtnExportArchive.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlBtnExportArchive/PlBtnExportArchive.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PlBtnExportArchive.vue.d.ts","sourceRoot":"","sources":["../../../src/components/PlBtnExportArchive/PlBtnExportArchive.vue"],"names":[],"mappings":"AAuQA,OAAO,KAAK,EAA0B,eAAe,EAAE,MAAM,SAAS,CAAC;AAOvE,KAAK,oBAAoB,GAAG;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACnC,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C,CAAC;AAiUF,QAAA,IAAI,OAAO,IAAW,CAAE;AACxB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAK/C,QAAA,MAAM,UAAU,kSAEd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|