@platforma-sdk/ui-vue 1.42.42 → 1.42.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/.turbo/turbo-build.log +34 -33
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +14 -0
  4. package/dist/AgGridVue/createAgGridColDef.js +3 -2
  5. package/dist/AgGridVue/createAgGridColDef.js.map +1 -1
  6. package/dist/AgGridVue/useAgGridOptions.js +3 -2
  7. package/dist/AgGridVue/useAgGridOptions.js.map +1 -1
  8. package/dist/components/PlAgDataTable/PlAgDataTableSheets.vue2.js +3 -2
  9. package/dist/components/PlAgDataTable/PlAgDataTableSheets.vue2.js.map +1 -1
  10. package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +3 -2
  11. package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js.map +1 -1
  12. package/dist/components/PlAgDataTable/PlAgRowCount.vue.js +3 -2
  13. package/dist/components/PlAgDataTable/PlAgRowCount.vue.js.map +1 -1
  14. package/dist/components/PlAgDataTable/sources/focus-row.js +21 -20
  15. package/dist/components/PlAgDataTable/sources/focus-row.js.map +1 -1
  16. package/dist/components/PlAgDataTable/sources/table-source-v2.js +3 -2
  17. package/dist/components/PlAgDataTable/sources/table-source-v2.js.map +1 -1
  18. package/dist/components/PlAgDataTable/sources/table-state-v2.js +3 -2
  19. package/dist/components/PlAgDataTable/sources/table-state-v2.js.map +1 -1
  20. package/dist/components/PlAgDataTable/types.js +10 -9
  21. package/dist/components/PlAgDataTable/types.js.map +1 -1
  22. package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js +12 -11
  23. package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js.map +1 -1
  24. package/dist/components/PlAgRowNumHeader.vue.js +9 -8
  25. package/dist/components/PlAgRowNumHeader.vue.js.map +1 -1
  26. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js +3 -2
  27. package/dist/components/PlAnnotations/components/AnnotationsSidebar.vue2.js.map +1 -1
  28. package/dist/components/PlAnnotations/components/DynamicForm.vue2.js +3 -2
  29. package/dist/components/PlAnnotations/components/DynamicForm.vue2.js.map +1 -1
  30. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +3 -2
  31. package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js.map +1 -1
  32. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js +10 -9
  33. package/dist/components/PlAnnotations/components/PlAnnotationsModal.vue2.js.map +1 -1
  34. package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue2.js +3 -2
  35. package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue2.js.map +1 -1
  36. package/dist/components/PlMultiSequenceAlignment/Toolbar.vue2.js +3 -2
  37. package/dist/components/PlMultiSequenceAlignment/Toolbar.vue2.js.map +1 -1
  38. package/dist/components/PlMultiSequenceAlignment/data.js +9 -8
  39. package/dist/components/PlMultiSequenceAlignment/data.js.map +1 -1
  40. package/dist/components/PlTableFilters/PlTableAddFilterV2.vue.js +3 -2
  41. package/dist/components/PlTableFilters/PlTableAddFilterV2.vue.js.map +1 -1
  42. package/dist/components/PlTableFilters/PlTableFilterEntryV2.vue.js +3 -2
  43. package/dist/components/PlTableFilters/PlTableFilterEntryV2.vue.js.map +1 -1
  44. package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js +3 -2
  45. package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js.map +1 -1
  46. package/dist/components/PlTableFilters/filters-state.js +10 -9
  47. package/dist/components/PlTableFilters/filters-state.js.map +1 -1
  48. package/dist/createModel.js +3 -2
  49. package/dist/createModel.js.map +1 -1
  50. package/dist/defineApp.js +9 -8
  51. package/dist/defineApp.js.map +1 -1
  52. package/dist/internal/UpdateSerializer.js +11 -10
  53. package/dist/internal/UpdateSerializer.js.map +1 -1
  54. package/dist/internal/createAppModel.js +12 -11
  55. package/dist/internal/createAppModel.js.map +1 -1
  56. package/dist/internal/createAppV1.js +3 -2
  57. package/dist/internal/createAppV1.js.map +1 -1
  58. package/dist/internal/createAppV2.js +14 -13
  59. package/dist/internal/createAppV2.js.map +1 -1
  60. package/dist/lib/util/helpers/dist/test_timeouts.js +28 -0
  61. package/dist/lib/util/helpers/dist/test_timeouts.js.map +1 -0
  62. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.vue2.js","sources":["../../../src/components/PlMultiSequenceAlignment/Toolbar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { isJsonEqual } from '@milaboratories/helpers';\nimport {\n type ListOptionNormalized,\n PlBtnGhost,\n PlBtnPrimary,\n PlBtnSecondary,\n PlCheckbox,\n PlDropdown,\n PlDropdownMulti,\n PlNumberField,\n PlSlideModal,\n} from '@milaboratories/uikit';\nimport type {\n PlMultiSequenceAlignmentColorSchemeOption as ColorSchemeOption,\n PlMultiSequenceAlignmentSettings as Settings,\n PObjectId,\n PTableColumnId,\n} from '@platforma-sdk/model';\nimport { computed, ref, watchEffect } from 'vue';\nimport { defaultAlignmentParams } from './multi-sequence-alignment';\n\nconst { settings } = defineProps<{\n settings: Settings;\n sequenceColumnOptions: ListOptionNormalized<PObjectId>[] | undefined;\n labelColumnOptions: ListOptionNormalized<PTableColumnId>[] | undefined;\n colorSchemeOptions: ListOptionNormalized<ColorSchemeOption>[];\n}>();\n\nconst emit = defineEmits<{\n updateSettings: [Partial<Settings>];\n export: [];\n}>();\n\nconst settingsOpen = ref(false);\n\nfunction updateSetting<K extends keyof Settings>(\n key: K,\n value: Settings[K] | undefined,\n) {\n emit('updateSettings', { [key]: value });\n}\n\nfunction toggleWidget(\n widget: 'seqLogo' | 'consensus' | 'legend',\n checked: boolean,\n) {\n updateSetting(\n 'widgets',\n checked\n ? [...settings.widgets, widget]\n : settings.widgets.filter((w) => widget !== w),\n );\n}\n\nconst alignmentParams = ref({ ...settings.alignmentParams });\nwatchEffect(() => {\n alignmentParams.value = { ...settings.alignmentParams };\n});\n\nconst alignmentParamsChangesPending = computed(() =>\n !isJsonEqual(settings.alignmentParams, alignmentParams.value),\n);\n\nconst canResetAlignmentParams = computed(() =>\n !isJsonEqual(settings.alignmentParams, defaultAlignmentParams),\n);\n</script>\n\n<template>\n <div :class=\"$style.container\">\n <div :class=\"$style.line\">\n <div :class=\"$style.section\">\n <PlDropdownMulti\n label=\"Sequence Columns\"\n :model-value=\"settings.sequenceColumnIds ?? []\"\n :options=\"sequenceColumnOptions\"\n clearable\n @update:model-value=\"updateSetting('sequenceColumnIds', $event)\"\n />\n <PlDropdownMulti\n :model-value=\"settings.labelColumnIds ?? []\"\n label=\"Label Columns\"\n :options=\"labelColumnOptions\"\n clearable\n @update:model-value=\"updateSetting('labelColumnIds', $event)\"\n />\n <PlDropdown\n :model-value=\"settings.colorScheme\"\n label=\"Color Scheme\"\n :options=\"colorSchemeOptions\"\n @update:model-value=\"updateSetting('colorScheme', $event)\"\n />\n </div>\n <div :class=\"$style.buttons\">\n <PlBtnGhost icon=\"settings\" @click.stop=\"settingsOpen = true\">\n Settings\n </PlBtnGhost>\n <PlBtnGhost icon=\"export\" @click.stop=\"$emit('export')\">\n Export\n </PlBtnGhost>\n </div>\n </div>\n <div :class=\"$style.line\">\n <div :class=\"$style.section\">\n <PlCheckbox\n :model-value=\"settings.widgets.includes('seqLogo')\"\n @update:model-value=\"toggleWidget('seqLogo', $event)\"\n >\n Seq logo\n </PlCheckbox>\n <PlCheckbox\n :model-value=\"settings.widgets.includes('consensus')\"\n @update:model-value=\"toggleWidget('consensus', $event)\"\n >\n Consensus\n </PlCheckbox>\n <PlCheckbox :model-value=\"false\" disabled>Navigator</PlCheckbox>\n <PlCheckbox :model-value=\"false\" disabled>Tree</PlCheckbox>\n <PlCheckbox\n :model-value=\"settings.widgets.includes('legend')\"\n :disabled=\"settings.colorScheme.type === 'no-color'\"\n @update:model-value=\"toggleWidget('legend', $event)\"\n >\n Legend\n </PlCheckbox>\n </div>\n </div>\n </div>\n <PlSlideModal v-model=\"settingsOpen\">\n <template #title>Settings</template>\n <PlNumberField\n v-model=\"alignmentParams.gpo\"\n label=\"Gap open penalty\"\n :step=\"0.1\"\n @keyup.enter=\"updateSetting('alignmentParams', alignmentParams)\"\n >\n <template #tooltip>\n Penalty score assigned to the introduction of a gap in the alignment\n </template>\n </PlNumberField>\n <PlNumberField\n v-model=\"alignmentParams.gpe\"\n label=\"Gap extension penalty\"\n :step=\"0.1\"\n @keyup.enter=\"updateSetting('alignmentParams', alignmentParams)\"\n >\n <template #tooltip>\n Penalty score assigned to each additional residue added to an existing\n gap\n </template>\n </PlNumberField>\n <PlNumberField\n v-model=\"alignmentParams.tgpe\"\n label=\"Terminal gap extension penalty\"\n :step=\"0.1\"\n @keyup.enter=\"updateSetting('alignmentParams', alignmentParams)\"\n >\n <template #tooltip>\n Penalty score assigned to extending gaps at the ends of sequences\n </template>\n </PlNumberField>\n <div\n v-if=\"alignmentParamsChangesPending\"\n :class=\"$style['pending-changes']\"\n >\n <PlBtnPrimary @click=\"updateSetting('alignmentParams', alignmentParams)\">\n Apply\n </PlBtnPrimary>\n <PlBtnGhost @click=\"alignmentParams = settings.alignmentParams\">\n Cancel\n </PlBtnGhost>\n </div>\n <PlBtnSecondary\n v-if=\"canResetAlignmentParams\"\n :class=\"$style['reset-button']\"\n icon=\"reverse\"\n @click=\"updateSetting('alignmentParams', undefined)\"\n >\n Reset to Default\n </PlBtnSecondary>\n </PlSlideModal>\n</template>\n\n<style module>\n.container {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.line {\n display: flex;\n justify-content: space-between;\n}\n\n.section {\n display: flex;\n flex-wrap: wrap;\n gap: 24px;\n}\n\n.buttons {\n display: flex;\n}\n\n.pending-changes {\n display: flex;\n button {\n min-width: 160px;\n }\n}\n\n.reset-button {\n margin-block-start: auto;\n span {\n text-transform: none;\n }\n}\n</style>\n"],"names":["emit","__emit","settingsOpen","ref","updateSetting","key","value","toggleWidget","widget","checked","__props","w","alignmentParams","watchEffect","alignmentParamsChangesPending","computed","isJsonEqual","canResetAlignmentParams","defaultAlignmentParams"],"mappings":";;;;;;;;;;;;;;AA6BA,UAAMA,IAAOC,GAKPC,IAAeC,EAAI,EAAK;AAE9B,aAASC,EACPC,GACAC,GACA;AACA,MAAAN,EAAK,kBAAkB,EAAE,CAACK,CAAG,GAAGC,GAAO;AAAA,IACzC;AAEA,aAASC,EACPC,GACAC,GACA;AACA,MAAAL;AAAA,QACE;AAAA,QACAK,IACI,CAAC,GAAGC,EAAA,SAAS,SAASF,CAAM,IAC5BE,EAAA,SAAS,QAAQ,OAAO,CAACC,MAAMH,MAAWG,CAAC;AAAA,MAAA;AAAA,IAEnD;AAEA,UAAMC,IAAkBT,EAAI,EAAE,GAAGO,WAAS,iBAAiB;AAC3D,IAAAG,EAAY,MAAM;AAChB,MAAAD,EAAgB,QAAQ,EAAE,GAAGF,WAAS,gBAAA;AAAA,IACxC,CAAC;AAED,UAAMI,IAAgCC;AAAA,MAAS,MAC7C,CAACC,EAAYN,EAAA,SAAS,iBAAiBE,EAAgB,KAAK;AAAA,IAAA,GAGxDK,IAA0BF;AAAA,MAAS,MACvC,CAACC,EAAYN,EAAA,SAAS,iBAAiBQ,CAAsB;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Toolbar.vue2.js","sources":["../../../src/components/PlMultiSequenceAlignment/Toolbar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { isJsonEqual } from '@milaboratories/helpers';\nimport {\n type ListOptionNormalized,\n PlBtnGhost,\n PlBtnPrimary,\n PlBtnSecondary,\n PlCheckbox,\n PlDropdown,\n PlDropdownMulti,\n PlNumberField,\n PlSlideModal,\n} from '@milaboratories/uikit';\nimport type {\n PlMultiSequenceAlignmentColorSchemeOption as ColorSchemeOption,\n PlMultiSequenceAlignmentSettings as Settings,\n PObjectId,\n PTableColumnId,\n} from '@platforma-sdk/model';\nimport { computed, ref, watchEffect } from 'vue';\nimport { defaultAlignmentParams } from './multi-sequence-alignment';\n\nconst { settings } = defineProps<{\n settings: Settings;\n sequenceColumnOptions: ListOptionNormalized<PObjectId>[] | undefined;\n labelColumnOptions: ListOptionNormalized<PTableColumnId>[] | undefined;\n colorSchemeOptions: ListOptionNormalized<ColorSchemeOption>[];\n}>();\n\nconst emit = defineEmits<{\n updateSettings: [Partial<Settings>];\n export: [];\n}>();\n\nconst settingsOpen = ref(false);\n\nfunction updateSetting<K extends keyof Settings>(\n key: K,\n value: Settings[K] | undefined,\n) {\n emit('updateSettings', { [key]: value });\n}\n\nfunction toggleWidget(\n widget: 'seqLogo' | 'consensus' | 'legend',\n checked: boolean,\n) {\n updateSetting(\n 'widgets',\n checked\n ? [...settings.widgets, widget]\n : settings.widgets.filter((w) => widget !== w),\n );\n}\n\nconst alignmentParams = ref({ ...settings.alignmentParams });\nwatchEffect(() => {\n alignmentParams.value = { ...settings.alignmentParams };\n});\n\nconst alignmentParamsChangesPending = computed(() =>\n !isJsonEqual(settings.alignmentParams, alignmentParams.value),\n);\n\nconst canResetAlignmentParams = computed(() =>\n !isJsonEqual(settings.alignmentParams, defaultAlignmentParams),\n);\n</script>\n\n<template>\n <div :class=\"$style.container\">\n <div :class=\"$style.line\">\n <div :class=\"$style.section\">\n <PlDropdownMulti\n label=\"Sequence Columns\"\n :model-value=\"settings.sequenceColumnIds ?? []\"\n :options=\"sequenceColumnOptions\"\n clearable\n @update:model-value=\"updateSetting('sequenceColumnIds', $event)\"\n />\n <PlDropdownMulti\n :model-value=\"settings.labelColumnIds ?? []\"\n label=\"Label Columns\"\n :options=\"labelColumnOptions\"\n clearable\n @update:model-value=\"updateSetting('labelColumnIds', $event)\"\n />\n <PlDropdown\n :model-value=\"settings.colorScheme\"\n label=\"Color Scheme\"\n :options=\"colorSchemeOptions\"\n @update:model-value=\"updateSetting('colorScheme', $event)\"\n />\n </div>\n <div :class=\"$style.buttons\">\n <PlBtnGhost icon=\"settings\" @click.stop=\"settingsOpen = true\">\n Settings\n </PlBtnGhost>\n <PlBtnGhost icon=\"export\" @click.stop=\"$emit('export')\">\n Export\n </PlBtnGhost>\n </div>\n </div>\n <div :class=\"$style.line\">\n <div :class=\"$style.section\">\n <PlCheckbox\n :model-value=\"settings.widgets.includes('seqLogo')\"\n @update:model-value=\"toggleWidget('seqLogo', $event)\"\n >\n Seq logo\n </PlCheckbox>\n <PlCheckbox\n :model-value=\"settings.widgets.includes('consensus')\"\n @update:model-value=\"toggleWidget('consensus', $event)\"\n >\n Consensus\n </PlCheckbox>\n <PlCheckbox :model-value=\"false\" disabled>Navigator</PlCheckbox>\n <PlCheckbox :model-value=\"false\" disabled>Tree</PlCheckbox>\n <PlCheckbox\n :model-value=\"settings.widgets.includes('legend')\"\n :disabled=\"settings.colorScheme.type === 'no-color'\"\n @update:model-value=\"toggleWidget('legend', $event)\"\n >\n Legend\n </PlCheckbox>\n </div>\n </div>\n </div>\n <PlSlideModal v-model=\"settingsOpen\">\n <template #title>Settings</template>\n <PlNumberField\n v-model=\"alignmentParams.gpo\"\n label=\"Gap open penalty\"\n :step=\"0.1\"\n @keyup.enter=\"updateSetting('alignmentParams', alignmentParams)\"\n >\n <template #tooltip>\n Penalty score assigned to the introduction of a gap in the alignment\n </template>\n </PlNumberField>\n <PlNumberField\n v-model=\"alignmentParams.gpe\"\n label=\"Gap extension penalty\"\n :step=\"0.1\"\n @keyup.enter=\"updateSetting('alignmentParams', alignmentParams)\"\n >\n <template #tooltip>\n Penalty score assigned to each additional residue added to an existing\n gap\n </template>\n </PlNumberField>\n <PlNumberField\n v-model=\"alignmentParams.tgpe\"\n label=\"Terminal gap extension penalty\"\n :step=\"0.1\"\n @keyup.enter=\"updateSetting('alignmentParams', alignmentParams)\"\n >\n <template #tooltip>\n Penalty score assigned to extending gaps at the ends of sequences\n </template>\n </PlNumberField>\n <div\n v-if=\"alignmentParamsChangesPending\"\n :class=\"$style['pending-changes']\"\n >\n <PlBtnPrimary @click=\"updateSetting('alignmentParams', alignmentParams)\">\n Apply\n </PlBtnPrimary>\n <PlBtnGhost @click=\"alignmentParams = settings.alignmentParams\">\n Cancel\n </PlBtnGhost>\n </div>\n <PlBtnSecondary\n v-if=\"canResetAlignmentParams\"\n :class=\"$style['reset-button']\"\n icon=\"reverse\"\n @click=\"updateSetting('alignmentParams', undefined)\"\n >\n Reset to Default\n </PlBtnSecondary>\n </PlSlideModal>\n</template>\n\n<style module>\n.container {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.line {\n display: flex;\n justify-content: space-between;\n}\n\n.section {\n display: flex;\n flex-wrap: wrap;\n gap: 24px;\n}\n\n.buttons {\n display: flex;\n}\n\n.pending-changes {\n display: flex;\n button {\n min-width: 160px;\n }\n}\n\n.reset-button {\n margin-block-start: auto;\n span {\n text-transform: none;\n }\n}\n</style>\n"],"names":["emit","__emit","settingsOpen","ref","updateSetting","key","value","toggleWidget","widget","checked","__props","w","alignmentParams","watchEffect","alignmentParamsChangesPending","computed","isJsonEqual","canResetAlignmentParams","defaultAlignmentParams"],"mappings":";;;;;;;;;;;;;;;AA6BA,UAAMA,IAAOC,GAKPC,IAAeC,EAAI,EAAK;AAE9B,aAASC,EACPC,GACAC,GACA;AACA,MAAAN,EAAK,kBAAkB,EAAE,CAACK,CAAG,GAAGC,GAAO;AAAA,IACzC;AAEA,aAASC,EACPC,GACAC,GACA;AACA,MAAAL;AAAA,QACE;AAAA,QACAK,IACI,CAAC,GAAGC,EAAA,SAAS,SAASF,CAAM,IAC5BE,EAAA,SAAS,QAAQ,OAAO,CAACC,MAAMH,MAAWG,CAAC;AAAA,MAAA;AAAA,IAEnD;AAEA,UAAMC,IAAkBT,EAAI,EAAE,GAAGO,WAAS,iBAAiB;AAC3D,IAAAG,EAAY,MAAM;AAChB,MAAAD,EAAgB,QAAQ,EAAE,GAAGF,WAAS,gBAAA;AAAA,IACxC,CAAC;AAED,UAAMI,IAAgCC;AAAA,MAAS,MAC7C,CAACC,EAAYN,EAAA,SAAS,iBAAiBE,EAAgB,KAAK;AAAA,IAAA,GAGxDK,IAA0BF;AAAA,MAAS,MACvC,CAACC,EAAYN,EAAA,SAAS,iBAAiBQ,CAAsB;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,17 +1,18 @@
1
1
  import { isJsonEqual as J } from "../../lib/util/helpers/dist/objects.js";
2
+ import "../../lib/util/helpers/dist/test_timeouts.js";
2
3
  import { ensureError as G, getRawPlatformaInstance as H, readAnnotation as A, Annotation as g, canonicalizeJson as v, getAxisId as O, parseJson as S, isLabelColumn as N, matchAxisId as K, readAnnotationJson as j, isLinkerColumn as Q, createRowSelectionColumn as X, pTableValue as M } from "@platforma-sdk/model";
3
4
  import { ref as q, watch as Y } from "vue";
4
5
  import { highlightByChemicalProperties as Z } from "./chemical-properties.js";
5
6
  import { parseMarkup as tt, markupAlignedSequence as nt, highlightByMarkup as et } from "./markup.js";
6
7
  import { multiSequenceAlignment as rt } from "./multi-sequence-alignment.js";
7
8
  import { getResidueCounts as ot } from "./residue-counts.js";
8
- const C = () => H().pFrameDriver, E = 1e3, gt = k(
9
+ const C = () => H().pFrameDriver, E = 1e3, ht = k(
9
10
  at
10
- ), ht = k(
11
- st
12
11
  ), wt = k(
13
- it
12
+ st
14
13
  ), bt = k(
14
+ it
15
+ ), At = k(
15
16
  lt
16
17
  );
17
18
  async function at({
@@ -255,9 +256,9 @@ function k(l) {
255
256
  }
256
257
  export {
257
258
  E as sequenceLimit,
258
- ht as useLabelColumnsOptions,
259
- wt as useMarkupColumnsOptions,
260
- bt as useMultipleAlignmentData,
261
- gt as useSequenceColumnsOptions
259
+ wt as useLabelColumnsOptions,
260
+ bt as useMarkupColumnsOptions,
261
+ At as useMultipleAlignmentData,
262
+ ht as useSequenceColumnsOptions
262
263
  };
263
264
  //# sourceMappingURL=data.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"data.js","sources":["../../../src/components/PlMultiSequenceAlignment/data.ts"],"sourcesContent":["import { isJsonEqual } from '@milaboratories/helpers';\nimport type { ListOptionNormalized } from '@milaboratories/uikit';\nimport {\n type CalculateTableDataRequest,\n type CanonicalizedJson,\n canonicalizeJson,\n createRowSelectionColumn,\n ensureError,\n getAxisId,\n getRawPlatformaInstance,\n isLabelColumn,\n isLinkerColumn,\n type JoinEntry,\n matchAxisId,\n parseJson,\n type PColumnIdAndSpec,\n type PFrameHandle,\n type PlMultiSequenceAlignmentColorSchemeOption,\n type PlMultiSequenceAlignmentSettings,\n type PlSelectionModel,\n type PObjectId,\n type PTableColumnId,\n type PTableSorting,\n pTableValue,\n readAnnotation,\n Annotation,\n readAnnotationJson,\n} from '@platforma-sdk/model';\nimport { ref, watch } from 'vue';\nimport { highlightByChemicalProperties } from './chemical-properties';\nimport {\n highlightByMarkup,\n markupAlignedSequence,\n parseMarkup,\n} from './markup';\nimport { multiSequenceAlignment } from './multi-sequence-alignment';\nimport { getResidueCounts } from './residue-counts';\nimport type { HighlightLegend, ResidueCounts } from './types';\n\nconst getPFrameDriver = () => getRawPlatformaInstance().pFrameDriver;\n\nexport const sequenceLimit = 1000;\n\nexport const useSequenceColumnsOptions = refreshOnDeepChange(\n getSequenceColumnsOptions,\n);\n\nexport const useLabelColumnsOptions = refreshOnDeepChange(\n getLabelColumnsOptions,\n);\n\nexport const useMarkupColumnsOptions = refreshOnDeepChange(\n getMarkupColumnsOptions,\n);\n\nexport const useMultipleAlignmentData = refreshOnDeepChange(\n getMultipleAlignmentData,\n);\n\nasync function getSequenceColumnsOptions({\n pFrame,\n sequenceColumnPredicate,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnPredicate: (column: PColumnIdAndSpec) => boolean;\n}): Promise<OptionsWithDefaults<PObjectId> | undefined> {\n if (!pFrame) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const options = columns.values()\n .filter((column) => sequenceColumnPredicate(column))\n .map(({ spec, columnId }) => ({\n label: readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',\n value: columnId,\n }))\n .toArray();\n const defaults = options.map(({ value }) => value);\n return { options, defaults };\n}\n\nasync function getLabelColumnsOptions({\n pFrame,\n sequenceColumnIds,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n}): Promise<OptionsWithDefaults<PTableColumnId> | undefined> {\n if (!pFrame || !sequenceColumnIds) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const optionMap = new Map<CanonicalizedJson<PTableColumnId>, string>();\n\n const sequenceColumnsAxes = new Map(\n sequenceColumnIds.values().flatMap((id) => {\n const column = columns.find(({ columnId }) => columnId === id);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: \\`${id}\\`).`);\n }\n return column.spec.axesSpec.values()\n .map((spec) => [canonicalizeJson(getAxisId(spec)), spec]);\n }),\n );\n\n for (const [axisIdJson, axisSpec] of sequenceColumnsAxes.entries()) {\n const axisId = parseJson(axisIdJson);\n const labelColumn = columns.find(({ spec }) =>\n isLabelColumn(spec) && matchAxisId(axisId, getAxisId(spec.axesSpec[0])),\n );\n optionMap.set(\n labelColumn\n ? canonicalizeJson({ type: 'column', id: labelColumn.columnId })\n : canonicalizeJson({ type: 'axis', id: axisId }),\n readAnnotation(labelColumn?.spec, Annotation.Label)\n ?? readAnnotation(axisSpec, Annotation.Label)\n ?? 'Unlabeled axis',\n );\n }\n\n const { hits: compatibleColumns } = await pFrameDriver.findColumns(pFrame, {\n columnFilter: {},\n compatibleWith: sequenceColumnsAxes.keys()\n .map((axisIdJson) => parseJson(axisIdJson))\n .toArray(),\n strictlyCompatible: false,\n });\n\n for (const { columnId, spec } of compatibleColumns) {\n const columnIdJson = canonicalizeJson({ type: 'column', id: columnId } satisfies PTableColumnId);\n if (optionMap.has(columnIdJson)) continue;\n optionMap.set(\n columnIdJson,\n readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',\n );\n }\n\n const options = optionMap.entries()\n .map(([value, label]) => ({ label, value: parseJson(value) }))\n .toArray();\n\n const defaults = options.values()\n .filter(({ value }) => {\n if (value.type === 'axis') return true;\n const column = columns.find(({ columnId }) => columnId === value.id);\n return column && isLabelColumn(column.spec);\n })\n .map(({ value }) => value)\n .toArray();\n return { options, defaults };\n}\n\nasync function getMarkupColumnsOptions({\n pFrame,\n sequenceColumnIds,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n}): Promise<ListOptionNormalized<PObjectId>[] | undefined> {\n if (!pFrame || sequenceColumnIds?.length !== 1) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const sequenceColumn = columns.find((column) =>\n column.columnId === sequenceColumnIds[0],\n );\n if (!sequenceColumn) {\n throw new Error(\n `Couldn't find sequence column (ID: \\`${sequenceColumnIds[0]}\\`).`,\n );\n }\n return columns.values()\n .filter((column) =>\n !!readAnnotationJson(column.spec, Annotation.Sequence.IsAnnotation)\n && isJsonEqual(sequenceColumn.spec.axesSpec, column.spec.axesSpec)\n && Object.entries(sequenceColumn.spec.domain ?? {}).every((\n [key, value],\n ) => column.spec.domain?.[key] === value),\n ).map(({ columnId, spec }) => ({\n value: columnId,\n label: readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',\n }))\n .toArray();\n}\n\nasync function getMultipleAlignmentData({\n pFrame,\n sequenceColumnIds,\n labelColumnIds,\n selection,\n colorScheme,\n alignmentParams,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n labelColumnIds: PTableColumnId[] | undefined;\n selection: PlSelectionModel | undefined;\n colorScheme: PlMultiSequenceAlignmentColorSchemeOption;\n alignmentParams: PlMultiSequenceAlignmentSettings['alignmentParams'];\n}): Promise<MultipleAlignmentData | undefined> {\n if (!pFrame || !sequenceColumnIds?.length || !labelColumnIds) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const linkerColumns = columns.filter((column) => isLinkerColumn(column.spec));\n\n const filterColumn = createRowSelectionColumn({ selection });\n\n // inner join of sequence columns\n let primaryEntry: JoinEntry<PObjectId> = {\n type: 'inner',\n entries: sequenceColumnIds.map((column) => ({\n type: 'column',\n column,\n })),\n };\n\n // if we have linkers, left join them\n if (linkerColumns.length > 0) {\n primaryEntry = {\n type: 'outer',\n primary: primaryEntry,\n secondary: linkerColumns.map(({ columnId }) => ({\n type: 'column',\n column: columnId,\n })),\n };\n }\n\n // inner join with filters\n if (filterColumn) {\n primaryEntry = {\n type: 'inner',\n entries: [\n primaryEntry,\n {\n type: 'inlineColumn',\n column: filterColumn,\n },\n ],\n };\n }\n\n // left join with labels\n const secondaryEntry: JoinEntry<PObjectId>[] = labelColumnIds\n .flatMap((column) => {\n if (column.type !== 'column') return [];\n return { type: 'column', column: column.id };\n });\n\n // and markup\n if (colorScheme.type === 'markup') {\n secondaryEntry.push({ type: 'column', column: colorScheme.columnId });\n }\n\n const sorting: PTableSorting[] = Array.from(\n new Set(\n sequenceColumnIds.values().flatMap((id) => {\n const column = columns.find(({ columnId }) => columnId === id);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: ${id})`);\n }\n return column.spec.axesSpec\n .map((spec) => canonicalizeJson(getAxisId(spec)));\n }),\n ),\n )\n .sort()\n .map((id) => ({\n column: { type: 'axis', id: parseJson(id) },\n ascending: true,\n naAndAbsentAreLeastValues: true,\n }));\n\n const request: CalculateTableDataRequest<PObjectId> = {\n src: {\n type: 'outer',\n primary: primaryEntry,\n secondary: secondaryEntry,\n },\n filters: [],\n sorting,\n };\n\n const table = await pFrameDriver.calculateTableData(\n pFrame,\n JSON.parse(JSON.stringify(request)),\n {\n offset: 0,\n // +1 is a hack to check whether the selection is over the limit\n length: sequenceLimit + 1,\n },\n );\n\n let rowCount = table?.[0].data.data.length ?? 0;\n let exceedsLimit = false;\n if (rowCount > sequenceLimit) {\n rowCount = sequenceLimit;\n exceedsLimit = true;\n }\n\n const sequenceColumns = sequenceColumnIds.map((columnId) => {\n const column = table.find(({ spec }) => spec.id === columnId);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: \\`${columnId}\\`).`);\n }\n return column;\n });\n\n const labelColumns = labelColumnIds.map((labelColumn) => {\n const column = table.find(({ spec }) => {\n if (labelColumn.type === 'axis' && spec.type === 'axis') {\n return isJsonEqual(labelColumn.id, spec.id);\n }\n if (labelColumn.type === 'column' && spec.type === 'column') {\n return labelColumn.id === spec.id;\n }\n });\n if (!column) {\n throw new Error(`Couldn't find label column (ID: \\`${labelColumn}\\`).`);\n }\n return column;\n });\n\n const alignedSequences = await Promise.all(\n sequenceColumns.map((column) =>\n multiSequenceAlignment(\n Array.from(\n { length: rowCount },\n (_, row) =>\n pTableValue(column.data, row, { na: '', absent: '' })?.toString()\n ?? '',\n ),\n alignmentParams,\n ),\n ),\n );\n\n const sequences = Array.from(\n { length: rowCount },\n (_, row) => alignedSequences.map((column) => column[row]),\n );\n\n const sequenceNames = sequenceColumns.map((column) =>\n readAnnotation(column.spec.spec, Annotation.Label) ?? 'Unlabeled column',\n );\n\n const labels = Array.from(\n { length: rowCount },\n (_, row) =>\n labelColumns.map((column) =>\n pTableValue(column.data, row, { na: '', absent: '' })?.toString() ?? '',\n ),\n );\n\n const concatenatedSequences = sequences.map((row) => row.join(' '));\n const residueCounts = getResidueCounts(concatenatedSequences);\n\n const result: MultipleAlignmentData = {\n sequences: concatenatedSequences,\n sequenceNames,\n labelRows: labels,\n exceedsLimit,\n residueCounts,\n };\n\n if (colorScheme.type === 'chemical-properties') {\n result.highlightImage = highlightByChemicalProperties({\n sequences: concatenatedSequences,\n residueCounts,\n });\n } else if (colorScheme.type === 'markup') {\n const markupColumn = table.find(({ spec }) =>\n spec.id === colorScheme.columnId,\n );\n if (!markupColumn) {\n throw new Error(\n `Couldn't find markup column (ID: \\`${colorScheme.columnId}\\`).`,\n );\n }\n const markupRows = Array.from(\n { length: rowCount },\n (_, row) => {\n const markup = parseMarkup(\n pTableValue(markupColumn.data, row, { na: '', absent: '' })\n ?.toString()\n ?? '',\n );\n return markupAlignedSequence(sequences[row][0], markup);\n },\n );\n const labels = readAnnotationJson(markupColumn.spec.spec, Annotation.Sequence.Annotation.Mapping) ?? {};\n result.highlightImage = highlightByMarkup({\n markupRows,\n columnCount: concatenatedSequences.at(0)?.length ?? 0,\n labels,\n });\n }\n\n return result;\n}\n\nfunction refreshOnDeepChange<T, P>(cb: (params: P) => Promise<T>) {\n const data = ref<T>();\n const isLoading = ref(true);\n const error = ref<Error>();\n let requestId: symbol;\n return (paramsGetter: () => P) => {\n watch(paramsGetter, async (params, prevParams) => {\n if (isJsonEqual(params, prevParams)) return;\n const currentRequestId = requestId = Symbol();\n try {\n error.value = undefined;\n isLoading.value = true;\n const result = await cb(params);\n if (currentRequestId === requestId) {\n data.value = result;\n }\n } catch (err) {\n console.error(err);\n if (currentRequestId === requestId) {\n error.value = ensureError(err);\n }\n } finally {\n if (currentRequestId === requestId) {\n isLoading.value = false;\n }\n }\n }, { immediate: true });\n return { data, isLoading, error };\n };\n}\n\ntype MultipleAlignmentData = {\n sequences: string[];\n sequenceNames: string[];\n labelRows: string[][];\n residueCounts: ResidueCounts;\n highlightImage?: {\n blob: Blob;\n legend: HighlightLegend;\n };\n exceedsLimit: boolean;\n};\n\ntype OptionsWithDefaults<T> = {\n options: ListOptionNormalized<T>[];\n defaults: T[];\n};\n"],"names":["getPFrameDriver","getRawPlatformaInstance","sequenceLimit","useSequenceColumnsOptions","refreshOnDeepChange","getSequenceColumnsOptions","useLabelColumnsOptions","getLabelColumnsOptions","useMarkupColumnsOptions","getMarkupColumnsOptions","useMultipleAlignmentData","getMultipleAlignmentData","pFrame","sequenceColumnPredicate","options","column","spec","columnId","readAnnotation","Annotation","defaults","value","sequenceColumnIds","pFrameDriver","columns","optionMap","sequenceColumnsAxes","id","canonicalizeJson","getAxisId","axisIdJson","axisSpec","axisId","parseJson","labelColumn","isLabelColumn","matchAxisId","compatibleColumns","columnIdJson","label","sequenceColumn","readAnnotationJson","isJsonEqual","key","_a","labelColumnIds","selection","colorScheme","alignmentParams","linkerColumns","isLinkerColumn","filterColumn","createRowSelectionColumn","primaryEntry","secondaryEntry","sorting","request","table","rowCount","exceedsLimit","sequenceColumns","labelColumns","alignedSequences","multiSequenceAlignment","_","row","pTableValue","sequences","sequenceNames","labels","concatenatedSequences","residueCounts","getResidueCounts","result","highlightByChemicalProperties","markupColumn","markupRows","markup","parseMarkup","markupAlignedSequence","highlightByMarkup","cb","data","ref","isLoading","error","requestId","paramsGetter","watch","params","prevParams","currentRequestId","err","ensureError"],"mappings":"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"}
1
+ {"version":3,"file":"data.js","sources":["../../../src/components/PlMultiSequenceAlignment/data.ts"],"sourcesContent":["import { isJsonEqual } from '@milaboratories/helpers';\nimport type { ListOptionNormalized } from '@milaboratories/uikit';\nimport {\n type CalculateTableDataRequest,\n type CanonicalizedJson,\n canonicalizeJson,\n createRowSelectionColumn,\n ensureError,\n getAxisId,\n getRawPlatformaInstance,\n isLabelColumn,\n isLinkerColumn,\n type JoinEntry,\n matchAxisId,\n parseJson,\n type PColumnIdAndSpec,\n type PFrameHandle,\n type PlMultiSequenceAlignmentColorSchemeOption,\n type PlMultiSequenceAlignmentSettings,\n type PlSelectionModel,\n type PObjectId,\n type PTableColumnId,\n type PTableSorting,\n pTableValue,\n readAnnotation,\n Annotation,\n readAnnotationJson,\n} from '@platforma-sdk/model';\nimport { ref, watch } from 'vue';\nimport { highlightByChemicalProperties } from './chemical-properties';\nimport {\n highlightByMarkup,\n markupAlignedSequence,\n parseMarkup,\n} from './markup';\nimport { multiSequenceAlignment } from './multi-sequence-alignment';\nimport { getResidueCounts } from './residue-counts';\nimport type { HighlightLegend, ResidueCounts } from './types';\n\nconst getPFrameDriver = () => getRawPlatformaInstance().pFrameDriver;\n\nexport const sequenceLimit = 1000;\n\nexport const useSequenceColumnsOptions = refreshOnDeepChange(\n getSequenceColumnsOptions,\n);\n\nexport const useLabelColumnsOptions = refreshOnDeepChange(\n getLabelColumnsOptions,\n);\n\nexport const useMarkupColumnsOptions = refreshOnDeepChange(\n getMarkupColumnsOptions,\n);\n\nexport const useMultipleAlignmentData = refreshOnDeepChange(\n getMultipleAlignmentData,\n);\n\nasync function getSequenceColumnsOptions({\n pFrame,\n sequenceColumnPredicate,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnPredicate: (column: PColumnIdAndSpec) => boolean;\n}): Promise<OptionsWithDefaults<PObjectId> | undefined> {\n if (!pFrame) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const options = columns.values()\n .filter((column) => sequenceColumnPredicate(column))\n .map(({ spec, columnId }) => ({\n label: readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',\n value: columnId,\n }))\n .toArray();\n const defaults = options.map(({ value }) => value);\n return { options, defaults };\n}\n\nasync function getLabelColumnsOptions({\n pFrame,\n sequenceColumnIds,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n}): Promise<OptionsWithDefaults<PTableColumnId> | undefined> {\n if (!pFrame || !sequenceColumnIds) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const optionMap = new Map<CanonicalizedJson<PTableColumnId>, string>();\n\n const sequenceColumnsAxes = new Map(\n sequenceColumnIds.values().flatMap((id) => {\n const column = columns.find(({ columnId }) => columnId === id);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: \\`${id}\\`).`);\n }\n return column.spec.axesSpec.values()\n .map((spec) => [canonicalizeJson(getAxisId(spec)), spec]);\n }),\n );\n\n for (const [axisIdJson, axisSpec] of sequenceColumnsAxes.entries()) {\n const axisId = parseJson(axisIdJson);\n const labelColumn = columns.find(({ spec }) =>\n isLabelColumn(spec) && matchAxisId(axisId, getAxisId(spec.axesSpec[0])),\n );\n optionMap.set(\n labelColumn\n ? canonicalizeJson({ type: 'column', id: labelColumn.columnId })\n : canonicalizeJson({ type: 'axis', id: axisId }),\n readAnnotation(labelColumn?.spec, Annotation.Label)\n ?? readAnnotation(axisSpec, Annotation.Label)\n ?? 'Unlabeled axis',\n );\n }\n\n const { hits: compatibleColumns } = await pFrameDriver.findColumns(pFrame, {\n columnFilter: {},\n compatibleWith: sequenceColumnsAxes.keys()\n .map((axisIdJson) => parseJson(axisIdJson))\n .toArray(),\n strictlyCompatible: false,\n });\n\n for (const { columnId, spec } of compatibleColumns) {\n const columnIdJson = canonicalizeJson({ type: 'column', id: columnId } satisfies PTableColumnId);\n if (optionMap.has(columnIdJson)) continue;\n optionMap.set(\n columnIdJson,\n readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',\n );\n }\n\n const options = optionMap.entries()\n .map(([value, label]) => ({ label, value: parseJson(value) }))\n .toArray();\n\n const defaults = options.values()\n .filter(({ value }) => {\n if (value.type === 'axis') return true;\n const column = columns.find(({ columnId }) => columnId === value.id);\n return column && isLabelColumn(column.spec);\n })\n .map(({ value }) => value)\n .toArray();\n return { options, defaults };\n}\n\nasync function getMarkupColumnsOptions({\n pFrame,\n sequenceColumnIds,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n}): Promise<ListOptionNormalized<PObjectId>[] | undefined> {\n if (!pFrame || sequenceColumnIds?.length !== 1) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const sequenceColumn = columns.find((column) =>\n column.columnId === sequenceColumnIds[0],\n );\n if (!sequenceColumn) {\n throw new Error(\n `Couldn't find sequence column (ID: \\`${sequenceColumnIds[0]}\\`).`,\n );\n }\n return columns.values()\n .filter((column) =>\n !!readAnnotationJson(column.spec, Annotation.Sequence.IsAnnotation)\n && isJsonEqual(sequenceColumn.spec.axesSpec, column.spec.axesSpec)\n && Object.entries(sequenceColumn.spec.domain ?? {}).every((\n [key, value],\n ) => column.spec.domain?.[key] === value),\n ).map(({ columnId, spec }) => ({\n value: columnId,\n label: readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',\n }))\n .toArray();\n}\n\nasync function getMultipleAlignmentData({\n pFrame,\n sequenceColumnIds,\n labelColumnIds,\n selection,\n colorScheme,\n alignmentParams,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n labelColumnIds: PTableColumnId[] | undefined;\n selection: PlSelectionModel | undefined;\n colorScheme: PlMultiSequenceAlignmentColorSchemeOption;\n alignmentParams: PlMultiSequenceAlignmentSettings['alignmentParams'];\n}): Promise<MultipleAlignmentData | undefined> {\n if (!pFrame || !sequenceColumnIds?.length || !labelColumnIds) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const linkerColumns = columns.filter((column) => isLinkerColumn(column.spec));\n\n const filterColumn = createRowSelectionColumn({ selection });\n\n // inner join of sequence columns\n let primaryEntry: JoinEntry<PObjectId> = {\n type: 'inner',\n entries: sequenceColumnIds.map((column) => ({\n type: 'column',\n column,\n })),\n };\n\n // if we have linkers, left join them\n if (linkerColumns.length > 0) {\n primaryEntry = {\n type: 'outer',\n primary: primaryEntry,\n secondary: linkerColumns.map(({ columnId }) => ({\n type: 'column',\n column: columnId,\n })),\n };\n }\n\n // inner join with filters\n if (filterColumn) {\n primaryEntry = {\n type: 'inner',\n entries: [\n primaryEntry,\n {\n type: 'inlineColumn',\n column: filterColumn,\n },\n ],\n };\n }\n\n // left join with labels\n const secondaryEntry: JoinEntry<PObjectId>[] = labelColumnIds\n .flatMap((column) => {\n if (column.type !== 'column') return [];\n return { type: 'column', column: column.id };\n });\n\n // and markup\n if (colorScheme.type === 'markup') {\n secondaryEntry.push({ type: 'column', column: colorScheme.columnId });\n }\n\n const sorting: PTableSorting[] = Array.from(\n new Set(\n sequenceColumnIds.values().flatMap((id) => {\n const column = columns.find(({ columnId }) => columnId === id);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: ${id})`);\n }\n return column.spec.axesSpec\n .map((spec) => canonicalizeJson(getAxisId(spec)));\n }),\n ),\n )\n .sort()\n .map((id) => ({\n column: { type: 'axis', id: parseJson(id) },\n ascending: true,\n naAndAbsentAreLeastValues: true,\n }));\n\n const request: CalculateTableDataRequest<PObjectId> = {\n src: {\n type: 'outer',\n primary: primaryEntry,\n secondary: secondaryEntry,\n },\n filters: [],\n sorting,\n };\n\n const table = await pFrameDriver.calculateTableData(\n pFrame,\n JSON.parse(JSON.stringify(request)),\n {\n offset: 0,\n // +1 is a hack to check whether the selection is over the limit\n length: sequenceLimit + 1,\n },\n );\n\n let rowCount = table?.[0].data.data.length ?? 0;\n let exceedsLimit = false;\n if (rowCount > sequenceLimit) {\n rowCount = sequenceLimit;\n exceedsLimit = true;\n }\n\n const sequenceColumns = sequenceColumnIds.map((columnId) => {\n const column = table.find(({ spec }) => spec.id === columnId);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: \\`${columnId}\\`).`);\n }\n return column;\n });\n\n const labelColumns = labelColumnIds.map((labelColumn) => {\n const column = table.find(({ spec }) => {\n if (labelColumn.type === 'axis' && spec.type === 'axis') {\n return isJsonEqual(labelColumn.id, spec.id);\n }\n if (labelColumn.type === 'column' && spec.type === 'column') {\n return labelColumn.id === spec.id;\n }\n });\n if (!column) {\n throw new Error(`Couldn't find label column (ID: \\`${labelColumn}\\`).`);\n }\n return column;\n });\n\n const alignedSequences = await Promise.all(\n sequenceColumns.map((column) =>\n multiSequenceAlignment(\n Array.from(\n { length: rowCount },\n (_, row) =>\n pTableValue(column.data, row, { na: '', absent: '' })?.toString()\n ?? '',\n ),\n alignmentParams,\n ),\n ),\n );\n\n const sequences = Array.from(\n { length: rowCount },\n (_, row) => alignedSequences.map((column) => column[row]),\n );\n\n const sequenceNames = sequenceColumns.map((column) =>\n readAnnotation(column.spec.spec, Annotation.Label) ?? 'Unlabeled column',\n );\n\n const labels = Array.from(\n { length: rowCount },\n (_, row) =>\n labelColumns.map((column) =>\n pTableValue(column.data, row, { na: '', absent: '' })?.toString() ?? '',\n ),\n );\n\n const concatenatedSequences = sequences.map((row) => row.join(' '));\n const residueCounts = getResidueCounts(concatenatedSequences);\n\n const result: MultipleAlignmentData = {\n sequences: concatenatedSequences,\n sequenceNames,\n labelRows: labels,\n exceedsLimit,\n residueCounts,\n };\n\n if (colorScheme.type === 'chemical-properties') {\n result.highlightImage = highlightByChemicalProperties({\n sequences: concatenatedSequences,\n residueCounts,\n });\n } else if (colorScheme.type === 'markup') {\n const markupColumn = table.find(({ spec }) =>\n spec.id === colorScheme.columnId,\n );\n if (!markupColumn) {\n throw new Error(\n `Couldn't find markup column (ID: \\`${colorScheme.columnId}\\`).`,\n );\n }\n const markupRows = Array.from(\n { length: rowCount },\n (_, row) => {\n const markup = parseMarkup(\n pTableValue(markupColumn.data, row, { na: '', absent: '' })\n ?.toString()\n ?? '',\n );\n return markupAlignedSequence(sequences[row][0], markup);\n },\n );\n const labels = readAnnotationJson(markupColumn.spec.spec, Annotation.Sequence.Annotation.Mapping) ?? {};\n result.highlightImage = highlightByMarkup({\n markupRows,\n columnCount: concatenatedSequences.at(0)?.length ?? 0,\n labels,\n });\n }\n\n return result;\n}\n\nfunction refreshOnDeepChange<T, P>(cb: (params: P) => Promise<T>) {\n const data = ref<T>();\n const isLoading = ref(true);\n const error = ref<Error>();\n let requestId: symbol;\n return (paramsGetter: () => P) => {\n watch(paramsGetter, async (params, prevParams) => {\n if (isJsonEqual(params, prevParams)) return;\n const currentRequestId = requestId = Symbol();\n try {\n error.value = undefined;\n isLoading.value = true;\n const result = await cb(params);\n if (currentRequestId === requestId) {\n data.value = result;\n }\n } catch (err) {\n console.error(err);\n if (currentRequestId === requestId) {\n error.value = ensureError(err);\n }\n } finally {\n if (currentRequestId === requestId) {\n isLoading.value = false;\n }\n }\n }, { immediate: true });\n return { data, isLoading, error };\n };\n}\n\ntype MultipleAlignmentData = {\n sequences: string[];\n sequenceNames: string[];\n labelRows: string[][];\n residueCounts: ResidueCounts;\n highlightImage?: {\n blob: Blob;\n legend: HighlightLegend;\n };\n exceedsLimit: boolean;\n};\n\ntype OptionsWithDefaults<T> = {\n options: ListOptionNormalized<T>[];\n defaults: T[];\n};\n"],"names":["getPFrameDriver","getRawPlatformaInstance","sequenceLimit","useSequenceColumnsOptions","refreshOnDeepChange","getSequenceColumnsOptions","useLabelColumnsOptions","getLabelColumnsOptions","useMarkupColumnsOptions","getMarkupColumnsOptions","useMultipleAlignmentData","getMultipleAlignmentData","pFrame","sequenceColumnPredicate","options","column","spec","columnId","readAnnotation","Annotation","defaults","value","sequenceColumnIds","pFrameDriver","columns","optionMap","sequenceColumnsAxes","id","canonicalizeJson","getAxisId","axisIdJson","axisSpec","axisId","parseJson","labelColumn","isLabelColumn","matchAxisId","compatibleColumns","columnIdJson","label","sequenceColumn","readAnnotationJson","isJsonEqual","key","_a","labelColumnIds","selection","colorScheme","alignmentParams","linkerColumns","isLinkerColumn","filterColumn","createRowSelectionColumn","primaryEntry","secondaryEntry","sorting","request","table","rowCount","exceedsLimit","sequenceColumns","labelColumns","alignedSequences","multiSequenceAlignment","_","row","pTableValue","sequences","sequenceNames","labels","concatenatedSequences","residueCounts","getResidueCounts","result","highlightByChemicalProperties","markupColumn","markupRows","markup","parseMarkup","markupAlignedSequence","highlightByMarkup","cb","data","ref","isLoading","error","requestId","paramsGetter","watch","params","prevParams","currentRequestId","err","ensureError"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { defineComponent as k, mergeModels as x, useModel as y, computed as b, ref as v, watch as w, createBlock as c, openBlock as n, unref as r, withCtx as u, createElementVNode as B, createVNode as s, createElementBlock as P, createCommentVNode as V, createTextVNode as m } from "vue";
2
2
  import { deepClone as M } from "../../lib/util/helpers/dist/objects.js";
3
+ import "../../lib/util/helpers/dist/test_timeouts.js";
3
4
  import { PlSlideModal as N, PlDropdown as g, PlBtnPrimary as A, PlBtnGhost as U } from "@milaboratories/uikit";
4
5
  import { getFilterDefault as j } from "./filters_logic.js";
5
6
  import D from "./PlTableFilterEntryV2.vue.js";
@@ -7,7 +8,7 @@ const E = { class: "d-flex flex-column gap-24" }, T = {
7
8
  key: 0,
8
9
  class: "text-subtitle-m",
9
10
  style: { color: "var(--txt-mask)" }
10
- }, $ = /* @__PURE__ */ k({
11
+ }, z = /* @__PURE__ */ k({
11
12
  __name: "PlTableAddFilterV2",
12
13
  props: /* @__PURE__ */ x({
13
14
  filters: {},
@@ -92,6 +93,6 @@ const E = { class: "d-flex flex-column gap-24" }, T = {
92
93
  }
93
94
  });
94
95
  export {
95
- $ as default
96
+ z as default
96
97
  };
97
98
  //# sourceMappingURL=PlTableAddFilterV2.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlTableAddFilterV2.vue.js","sources":["../../../src/components/PlTableFilters/PlTableAddFilterV2.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n deepClone,\n} from '@milaboratories/helpers';\nimport {\n PlBtnGhost,\n PlBtnPrimary,\n PlDropdown,\n PlSlideModal,\n type ListOption,\n} from '@milaboratories/uikit';\nimport {\n computed,\n ref,\n watch,\n} from 'vue';\nimport {\n type PlDataTableFilterStateInternal,\n} from './types';\nimport {\n getFilterDefault,\n} from './filters_logic';\nimport PlTableFilterEntryV2 from './PlTableFilterEntryV2.vue';\n\nconst show = defineModel<boolean>({ required: true });\nconst props = defineProps<{\n filters: Readonly<PlDataTableFilterStateInternal[]>;\n setFilter(idx: number, filter: PlDataTableFilterStateInternal): void;\n}>();\n\nconst filterOptions = computed<ListOption<number>[]>(() => {\n return props.filters\n .map((s, i) => {\n return {\n value: i,\n text: s.label,\n };\n })\n .filter((o) => props.filters[o.value].filter === null);\n});\n\nconst newFilterIdx = ref<number>();\nconst newFilter = ref<PlDataTableFilterStateInternal | null>(null);\nwatch(\n () => newFilterIdx.value,\n (newFilterIdx) => {\n if (newFilterIdx === undefined) {\n newFilter.value = null;\n } else {\n const filterClone = deepClone(props.filters[newFilterIdx]);\n if (!filterClone.filter) {\n filterClone.filter = {\n value: filterClone.defaultFilter ?? getFilterDefault(filterClone.options[0].value),\n disabled: false,\n open: true,\n };\n }\n newFilter.value = filterClone;\n }\n },\n);\nconst discardFilter = () => {\n newFilterIdx.value = undefined;\n show.value = false;\n};\nconst applyFilter = () => {\n if (newFilterIdx.value !== undefined && newFilter.value) {\n props.setFilter(newFilterIdx.value, newFilter.value);\n }\n discardFilter();\n};\n</script>\n\n<template>\n <PlSlideModal v-model=\"show\" :close-on-outside-click=\"false\">\n <template #title>Add Filter</template>\n <div class=\"d-flex flex-column gap-24\">\n <PlDropdown\n v-model=\"newFilterIdx\"\n :options=\"filterOptions\"\n label=\"Column\"\n placeholder=\"Choose...\"\n />\n <div\n v-if=\"newFilterIdx === undefined\"\n class=\"text-subtitle-m\"\n style=\"color: var(--txt-mask)\"\n >\n Choose a column to view and adjust its options\n </div>\n <PlTableFilterEntryV2\n v-if=\"newFilter\"\n v-model=\"newFilter\"\n />\n </div>\n <template #actions>\n <PlBtnPrimary :disabled=\"!newFilter\" @click=\"applyFilter\">Add Filter</PlBtnPrimary>\n <PlBtnGhost :justify-center=\"false\" @click=\"discardFilter\">Cancel</PlBtnGhost>\n </template>\n </PlSlideModal>\n</template>\n"],"names":["show","_useModel","__props","props","filterOptions","computed","s","i","newFilterIdx","ref","newFilter","watch","filterClone","deepClone","getFilterDefault","discardFilter","applyFilter"],"mappings":";;;;;;;;;;;;;;;;;;;;AAwBA,UAAMA,IAAOC,EAAoBC,GAAA,YAAmB,GAC9CC,IAAQD,GAKRE,IAAgBC,EAA+B,MAC5CF,EAAM,QACV,IAAI,CAACG,GAAGC,OACA;AAAA,MACL,OAAOA;AAAA,MACP,MAAMD,EAAE;AAAA,IAAA,EAEX,EACA,OAAO,CAAC,MAAMH,EAAM,QAAQ,EAAE,KAAK,EAAE,WAAW,IAAI,CACxD,GAEKK,IAAeC,EAAA,GACfC,IAAYD,EAA2C,IAAI;AACjE,IAAAE;AAAA,MACE,MAAMH,EAAa;AAAA,MACnB,CAACA,MAAiB;AAChB,YAAIA,MAAiB;AACnB,UAAAE,EAAU,QAAQ;AAAA,aACb;AACL,gBAAME,IAAcC,EAAUV,EAAM,QAAQK,CAAY,CAAC;AACzD,UAAKI,EAAY,WACfA,EAAY,SAAS;AAAA,YACnB,OAAOA,EAAY,iBAAiBE,EAAiBF,EAAY,QAAQ,CAAC,EAAE,KAAK;AAAA,YACjF,UAAU;AAAA,YACV,MAAM;AAAA,UAAA,IAGVF,EAAU,QAAQE;AAAA,QACpB;AAAA,MACF;AAAA,IAAA;AAEF,UAAMG,IAAgB,MAAM;AAC1B,MAAAP,EAAa,QAAQ,QACrBR,EAAK,QAAQ;AAAA,IACf,GACMgB,IAAc,MAAM;AACxB,MAAIR,EAAa,UAAU,UAAaE,EAAU,SAChDP,EAAM,UAAUK,EAAa,OAAOE,EAAU,KAAK,GAErDK,EAAA;AAAA,IACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"PlTableAddFilterV2.vue.js","sources":["../../../src/components/PlTableFilters/PlTableAddFilterV2.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n deepClone,\n} from '@milaboratories/helpers';\nimport {\n PlBtnGhost,\n PlBtnPrimary,\n PlDropdown,\n PlSlideModal,\n type ListOption,\n} from '@milaboratories/uikit';\nimport {\n computed,\n ref,\n watch,\n} from 'vue';\nimport {\n type PlDataTableFilterStateInternal,\n} from './types';\nimport {\n getFilterDefault,\n} from './filters_logic';\nimport PlTableFilterEntryV2 from './PlTableFilterEntryV2.vue';\n\nconst show = defineModel<boolean>({ required: true });\nconst props = defineProps<{\n filters: Readonly<PlDataTableFilterStateInternal[]>;\n setFilter(idx: number, filter: PlDataTableFilterStateInternal): void;\n}>();\n\nconst filterOptions = computed<ListOption<number>[]>(() => {\n return props.filters\n .map((s, i) => {\n return {\n value: i,\n text: s.label,\n };\n })\n .filter((o) => props.filters[o.value].filter === null);\n});\n\nconst newFilterIdx = ref<number>();\nconst newFilter = ref<PlDataTableFilterStateInternal | null>(null);\nwatch(\n () => newFilterIdx.value,\n (newFilterIdx) => {\n if (newFilterIdx === undefined) {\n newFilter.value = null;\n } else {\n const filterClone = deepClone(props.filters[newFilterIdx]);\n if (!filterClone.filter) {\n filterClone.filter = {\n value: filterClone.defaultFilter ?? getFilterDefault(filterClone.options[0].value),\n disabled: false,\n open: true,\n };\n }\n newFilter.value = filterClone;\n }\n },\n);\nconst discardFilter = () => {\n newFilterIdx.value = undefined;\n show.value = false;\n};\nconst applyFilter = () => {\n if (newFilterIdx.value !== undefined && newFilter.value) {\n props.setFilter(newFilterIdx.value, newFilter.value);\n }\n discardFilter();\n};\n</script>\n\n<template>\n <PlSlideModal v-model=\"show\" :close-on-outside-click=\"false\">\n <template #title>Add Filter</template>\n <div class=\"d-flex flex-column gap-24\">\n <PlDropdown\n v-model=\"newFilterIdx\"\n :options=\"filterOptions\"\n label=\"Column\"\n placeholder=\"Choose...\"\n />\n <div\n v-if=\"newFilterIdx === undefined\"\n class=\"text-subtitle-m\"\n style=\"color: var(--txt-mask)\"\n >\n Choose a column to view and adjust its options\n </div>\n <PlTableFilterEntryV2\n v-if=\"newFilter\"\n v-model=\"newFilter\"\n />\n </div>\n <template #actions>\n <PlBtnPrimary :disabled=\"!newFilter\" @click=\"applyFilter\">Add Filter</PlBtnPrimary>\n <PlBtnGhost :justify-center=\"false\" @click=\"discardFilter\">Cancel</PlBtnGhost>\n </template>\n </PlSlideModal>\n</template>\n"],"names":["show","_useModel","__props","props","filterOptions","computed","s","i","newFilterIdx","ref","newFilter","watch","filterClone","deepClone","getFilterDefault","discardFilter","applyFilter"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwBA,UAAMA,IAAOC,EAAoBC,GAAA,YAAmB,GAC9CC,IAAQD,GAKRE,IAAgBC,EAA+B,MAC5CF,EAAM,QACV,IAAI,CAACG,GAAGC,OACA;AAAA,MACL,OAAOA;AAAA,MACP,MAAMD,EAAE;AAAA,IAAA,EAEX,EACA,OAAO,CAAC,MAAMH,EAAM,QAAQ,EAAE,KAAK,EAAE,WAAW,IAAI,CACxD,GAEKK,IAAeC,EAAA,GACfC,IAAYD,EAA2C,IAAI;AACjE,IAAAE;AAAA,MACE,MAAMH,EAAa;AAAA,MACnB,CAACA,MAAiB;AAChB,YAAIA,MAAiB;AACnB,UAAAE,EAAU,QAAQ;AAAA,aACb;AACL,gBAAME,IAAcC,EAAUV,EAAM,QAAQK,CAAY,CAAC;AACzD,UAAKI,EAAY,WACfA,EAAY,SAAS;AAAA,YACnB,OAAOA,EAAY,iBAAiBE,EAAiBF,EAAY,QAAQ,CAAC,EAAE,KAAK;AAAA,YACjF,UAAU;AAAA,YACV,MAAM;AAAA,UAAA,IAGVF,EAAU,QAAQE;AAAA,QACpB;AAAA,MACF;AAAA,IAAA;AAEF,UAAMG,IAAgB,MAAM;AAC1B,MAAAP,EAAa,QAAQ,QACrBR,EAAK,QAAQ;AAAA,IACf,GACMgB,IAAc,MAAM;AACxB,MAAIR,EAAa,UAAU,UAAaE,EAAU,SAChDP,EAAM,UAAUK,EAAa,OAAOE,EAAU,KAAK,GAErDK,EAAA;AAAA,IACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { defineComponent as V, useModel as y, watchEffect as g, createElementBlock as o, createCommentVNode as d, openBlock as r, createVNode as t, createBlock as n, unref as u, Fragment as s, withCtx as U, createTextVNode as k } from "vue";
2
2
  import { PlDropdown as v, PlTextField as i, PlToggleSwitch as f, Slider as w, PlBtnGhost as x } from "@milaboratories/uikit";
3
3
  import { isJsonEqual as B } from "../../lib/util/helpers/dist/objects.js";
4
+ import "../../lib/util/helpers/dist/test_timeouts.js";
4
5
  import { getFilterDefault as E, changeFilter as F, isFilterDiscrete as T, parseNumber as p, parseString as m, parseRegex as c, makeWildcardOptions as q } from "./filters_logic.js";
5
6
  const O = {
6
7
  key: 0,
@@ -8,7 +9,7 @@ const O = {
8
9
  }, N = {
9
10
  key: 2,
10
11
  class: "d-flex justify-center"
11
- }, D = /* @__PURE__ */ V({
12
+ }, L = /* @__PURE__ */ V({
12
13
  __name: "PlTableFilterEntryV2",
13
14
  props: {
14
15
  modelValue: { required: !0 },
@@ -137,6 +138,6 @@ const O = {
137
138
  }
138
139
  });
139
140
  export {
140
- D as default
141
+ L as default
141
142
  };
142
143
  //# sourceMappingURL=PlTableFilterEntryV2.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlTableFilterEntryV2.vue.js","sources":["../../../src/components/PlTableFilters/PlTableFilterEntryV2.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n PlDropdown,\n PlTextField,\n PlToggleSwitch,\n Slider,\n PlBtnGhost,\n} from '@milaboratories/uikit';\nimport { isJsonEqual } from '@milaboratories/helpers';\nimport {\n changeFilter,\n parseNumber,\n parseString,\n parseRegex,\n makeWildcardOptions,\n isFilterDiscrete,\n getFilterDefault,\n} from './filters_logic';\nimport type { PlDataTableFilterStateInternal } from './types';\nimport { watchEffect } from 'vue';\n\nconst entry = defineModel<PlDataTableFilterStateInternal>({ required: true });\nwatchEffect(() => {\n if (!entry.value.filter) {\n entry.value.filter = {\n value: getFilterDefault(entry.value.options[0].value),\n disabled: false,\n open: true,\n };\n }\n});\n</script>\n\n<template>\n <div v-if=\"entry.filter\" class=\"d-flex flex-column gap-24\">\n <PlDropdown\n :model-value=\"entry.filter.value.type\"\n :options=\"entry.options\"\n :disabled=\"entry.filter.disabled\"\n label=\"Predicate\"\n @update:model-value=\"(type) => (entry.filter!.value = changeFilter(entry.filter!.value, type!, entry.discreteOptions))\"\n />\n\n <template v-if=\"entry.discreteOptions.length > 0 && isFilterDiscrete(entry.filter.value)\">\n <PlDropdown\n v-model=\"entry.filter.value.reference\"\n :options=\"entry.discreteOptions\"\n />\n </template>\n <template v-else>\n <template\n v-if=\"\n entry.filter.value.type === 'number_equals' ||\n entry.filter.value.type === 'number_notEquals' ||\n entry.filter.value.type === 'number_lessThan' ||\n entry.filter.value.type === 'number_lessThanOrEqualTo' ||\n entry.filter.value.type === 'number_greaterThan' ||\n entry.filter.value.type === 'number_greaterThanOrEqualTo'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.reference\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): number => parseNumber(entry.spec, value)\"\n label=\"Reference value\"\n />\n </template>\n\n <template\n v-if=\"\n entry.filter.value.type === 'number_between'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.lowerBound\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): number => parseNumber(entry.spec, value)\"\n label=\"Lower bound\"\n />\n <PlToggleSwitch\n v-model=\"entry.filter.value.includeLowerBound\"\n :disabled=\"entry.filter.disabled\"\n label=\"Include lower bound\"\n />\n <PlTextField\n v-model=\"entry.filter.value.upperBound\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): number => parseNumber(entry.spec, value)\"\n label=\"Upper bound\"\n />\n <PlToggleSwitch\n v-model=\"entry.filter.value.includeUpperBound\"\n :disabled=\"entry.filter.disabled\"\n label=\"Include upper bound\"\n />\n </template>\n\n <template\n v-if=\"\n entry.filter.value.type === 'string_equals' ||\n entry.filter.value.type === 'string_notEquals' ||\n entry.filter.value.type === 'string_contains' ||\n entry.filter.value.type === 'string_doesNotContain'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.reference\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): string => parseString(entry.spec, value)\"\n label=\"Reference value\"\n />\n </template>\n\n <template\n v-if=\"\n entry.filter.value.type === 'string_matches' ||\n entry.filter.value.type === 'string_doesNotMatch'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.reference\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"parseRegex\"\n label=\"Reference value\"\n />\n </template>\n\n <template\n v-if=\"\n entry.filter.value.type === 'string_containsFuzzyMatch'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.reference\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): string => parseString(entry.spec, value)\"\n label=\"Reference value\"\n />\n <Slider\n v-model=\"entry.filter.value.maxEdits\"\n :max=\"5\"\n :disabled=\"entry.filter.disabled\"\n breakpoints label=\"Maximum nuber of substitutions and indels\"\n />\n <PlToggleSwitch\n v-model=\"entry.filter.value.substitutionsOnly\"\n :disabled=\"entry.filter.disabled\"\n label=\"Substitutions only\"\n />\n <PlDropdown\n v-model=\"entry.filter.value.wildcard\"\n :disabled=\"entry.filter.disabled\"\n :options=\"makeWildcardOptions(entry.spec, entry.filter.value.reference)\"\n clearable\n label=\"Wildcard symbol\"\n />\n </template>\n </template>\n\n <div v-if=\"entry.defaultFilter\" class=\"d-flex justify-center\">\n <PlBtnGhost\n :disabled=\"entry.filter.disabled || isJsonEqual(entry.filter.value, entry.defaultFilter)\"\n icon=\"reverse\"\n @click=\"entry.filter.value = entry.defaultFilter\"\n >\n Revert Settings to Default\n </PlBtnGhost>\n </div>\n </div>\n</template>\n"],"names":["entry","_useModel","__props","watchEffect","getFilterDefault"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,UAAMA,IAAQC,EAA2CC,GAAA,YAAmB;AAC5E,WAAAC,EAAY,MAAM;AAChB,MAAKH,EAAM,MAAM,WACfA,EAAM,MAAM,SAAS;AAAA,QACnB,OAAOI,EAAiBJ,EAAM,MAAM,QAAQ,CAAC,EAAE,KAAK;AAAA,QACpD,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,IAGZ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"PlTableFilterEntryV2.vue.js","sources":["../../../src/components/PlTableFilters/PlTableFilterEntryV2.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n PlDropdown,\n PlTextField,\n PlToggleSwitch,\n Slider,\n PlBtnGhost,\n} from '@milaboratories/uikit';\nimport { isJsonEqual } from '@milaboratories/helpers';\nimport {\n changeFilter,\n parseNumber,\n parseString,\n parseRegex,\n makeWildcardOptions,\n isFilterDiscrete,\n getFilterDefault,\n} from './filters_logic';\nimport type { PlDataTableFilterStateInternal } from './types';\nimport { watchEffect } from 'vue';\n\nconst entry = defineModel<PlDataTableFilterStateInternal>({ required: true });\nwatchEffect(() => {\n if (!entry.value.filter) {\n entry.value.filter = {\n value: getFilterDefault(entry.value.options[0].value),\n disabled: false,\n open: true,\n };\n }\n});\n</script>\n\n<template>\n <div v-if=\"entry.filter\" class=\"d-flex flex-column gap-24\">\n <PlDropdown\n :model-value=\"entry.filter.value.type\"\n :options=\"entry.options\"\n :disabled=\"entry.filter.disabled\"\n label=\"Predicate\"\n @update:model-value=\"(type) => (entry.filter!.value = changeFilter(entry.filter!.value, type!, entry.discreteOptions))\"\n />\n\n <template v-if=\"entry.discreteOptions.length > 0 && isFilterDiscrete(entry.filter.value)\">\n <PlDropdown\n v-model=\"entry.filter.value.reference\"\n :options=\"entry.discreteOptions\"\n />\n </template>\n <template v-else>\n <template\n v-if=\"\n entry.filter.value.type === 'number_equals' ||\n entry.filter.value.type === 'number_notEquals' ||\n entry.filter.value.type === 'number_lessThan' ||\n entry.filter.value.type === 'number_lessThanOrEqualTo' ||\n entry.filter.value.type === 'number_greaterThan' ||\n entry.filter.value.type === 'number_greaterThanOrEqualTo'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.reference\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): number => parseNumber(entry.spec, value)\"\n label=\"Reference value\"\n />\n </template>\n\n <template\n v-if=\"\n entry.filter.value.type === 'number_between'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.lowerBound\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): number => parseNumber(entry.spec, value)\"\n label=\"Lower bound\"\n />\n <PlToggleSwitch\n v-model=\"entry.filter.value.includeLowerBound\"\n :disabled=\"entry.filter.disabled\"\n label=\"Include lower bound\"\n />\n <PlTextField\n v-model=\"entry.filter.value.upperBound\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): number => parseNumber(entry.spec, value)\"\n label=\"Upper bound\"\n />\n <PlToggleSwitch\n v-model=\"entry.filter.value.includeUpperBound\"\n :disabled=\"entry.filter.disabled\"\n label=\"Include upper bound\"\n />\n </template>\n\n <template\n v-if=\"\n entry.filter.value.type === 'string_equals' ||\n entry.filter.value.type === 'string_notEquals' ||\n entry.filter.value.type === 'string_contains' ||\n entry.filter.value.type === 'string_doesNotContain'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.reference\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): string => parseString(entry.spec, value)\"\n label=\"Reference value\"\n />\n </template>\n\n <template\n v-if=\"\n entry.filter.value.type === 'string_matches' ||\n entry.filter.value.type === 'string_doesNotMatch'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.reference\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"parseRegex\"\n label=\"Reference value\"\n />\n </template>\n\n <template\n v-if=\"\n entry.filter.value.type === 'string_containsFuzzyMatch'\n \"\n >\n <PlTextField\n v-model=\"entry.filter.value.reference\"\n :disabled=\"entry.filter.disabled\"\n :parse=\"(value: string): string => parseString(entry.spec, value)\"\n label=\"Reference value\"\n />\n <Slider\n v-model=\"entry.filter.value.maxEdits\"\n :max=\"5\"\n :disabled=\"entry.filter.disabled\"\n breakpoints label=\"Maximum nuber of substitutions and indels\"\n />\n <PlToggleSwitch\n v-model=\"entry.filter.value.substitutionsOnly\"\n :disabled=\"entry.filter.disabled\"\n label=\"Substitutions only\"\n />\n <PlDropdown\n v-model=\"entry.filter.value.wildcard\"\n :disabled=\"entry.filter.disabled\"\n :options=\"makeWildcardOptions(entry.spec, entry.filter.value.reference)\"\n clearable\n label=\"Wildcard symbol\"\n />\n </template>\n </template>\n\n <div v-if=\"entry.defaultFilter\" class=\"d-flex justify-center\">\n <PlBtnGhost\n :disabled=\"entry.filter.disabled || isJsonEqual(entry.filter.value, entry.defaultFilter)\"\n icon=\"reverse\"\n @click=\"entry.filter.value = entry.defaultFilter\"\n >\n Revert Settings to Default\n </PlBtnGhost>\n </div>\n </div>\n</template>\n"],"names":["entry","_useModel","__props","watchEffect","getFilterDefault"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,UAAMA,IAAQC,EAA2CC,GAAA,YAAmB;AAC5E,WAAAC,EAAY,MAAM;AAChB,MAAKH,EAAM,MAAM,WACfA,EAAM,MAAM,SAAS;AAAA,QACnB,OAAOI,EAAiBJ,EAAM,MAAM,QAAQ,CAAC,EAAE,KAAK;AAAA,QACpD,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,IAGZ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -5,7 +5,8 @@ import { useFilters as Y } from "./filters-state.js";
5
5
  import Z from "./PlTableAddFilterV2.vue.js";
6
6
  import _ from "./PlTableFilterEntryV2.vue.js";
7
7
  import { isJsonEqual as ee } from "../../lib/util/helpers/dist/objects.js";
8
- const le = ["disabled"], te = { key: 1 }, ue = /* @__PURE__ */ D({
8
+ import "../../lib/util/helpers/dist/test_timeouts.js";
9
+ const le = ["disabled"], te = { key: 1 }, fe = /* @__PURE__ */ D({
9
10
  __name: "PlTableFiltersV2",
10
11
  props: /* @__PURE__ */ S({
11
12
  settings: {}
@@ -148,6 +149,6 @@ const le = ["disabled"], te = { key: 1 }, ue = /* @__PURE__ */ D({
148
149
  }
149
150
  });
150
151
  export {
151
- ue as default
152
+ fe as default
152
153
  };
153
154
  //# sourceMappingURL=PlTableFiltersV2.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlTableFiltersV2.vue2.js","sources":["../../../src/components/PlTableFilters/PlTableFiltersV2.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport {\n type PlDataTableFilterState,\n canonicalizeJson,\n type PTableColumnId,\n} from '@platforma-sdk/model';\nimport type {\n PlDataTableFiltersSettings,\n} from './types';\nimport {\n computed,\n onBeforeUnmount,\n onMounted,\n ref,\n toRefs,\n watch,\n} from 'vue';\nimport {\n PlBtnGhost,\n PlSlideModal,\n PlBtnSecondary,\n PlMaskIcon16,\n PlElementList,\n usePlBlockPageTitleTeleportTarget,\n} from '@milaboratories/uikit';\nimport { useFilters } from './filters-state';\nimport PlTableAddFilterV2 from './PlTableAddFilterV2.vue';\nimport PlTableFilterEntryV2 from './PlTableFilterEntryV2.vue';\nimport { isJsonEqual } from '@milaboratories/helpers';\n\nconst state = defineModel<PlDataTableFilterState[]>({\n default: [],\n});\nconst props = defineProps<{\n settings: Readonly<PlDataTableFiltersSettings>;\n}>();\nconst { settings } = toRefs(props);\n\nconst filters = useFilters(settings, state);\n\nconst filtersOn = computed<boolean>(() => filters.value.some((s) => s.filter && !s.filter.disabled));\n\nconst mounted = ref(false);\nonMounted(() => {\n mounted.value = true;\n});\nconst teleportTarget = usePlBlockPageTitleTeleportTarget('PlTableFiltersV2');\n\nconst showManager = ref(false);\n\nconst scrollIsActive = ref(false);\nconst filterManager = ref<HTMLElement>();\nlet observer: ResizeObserver;\nonMounted(() => {\n observer = new ResizeObserver(() => {\n const parent = filterManager.value?.parentElement;\n if (!parent) return;\n scrollIsActive.value = parent.scrollHeight > parent.clientHeight || parent.scrollWidth > parent.clientWidth;\n });\n if (filterManager.value && filterManager.value.parentElement) {\n observer.observe(filterManager.value!.parentElement);\n }\n});\n\nwatch(filterManager, (newElement, oldElement) => {\n if (oldElement?.parentElement) {\n observer.unobserve(oldElement.parentElement);\n }\n if (newElement?.parentElement) {\n observer.observe(newElement.parentElement);\n }\n});\n\nonBeforeUnmount(() => {\n if (observer !== undefined) {\n observer.disconnect();\n }\n});\n\nconst canAddFilter = computed<boolean>(() => filters.value.some((s) => !s.filter));\nconst showAddFilter = ref(false);\n\nconst canResetToDefaults = computed<boolean>(() => {\n return filters.value\n .some((s) => (!s.defaultFilter && s.filter) || (s.defaultFilter\n && (s.filter?.disabled === true || !isJsonEqual(s.filter?.value, s.defaultFilter))));\n});\nconst resetToDefaults = () => {\n filters.value.forEach((s) => {\n if (s.defaultFilter) {\n s.filter = {\n value: s.defaultFilter,\n disabled: false,\n open: false,\n };\n } else {\n s.filter = null;\n }\n });\n};\n\nconst items = computed(() => filters.value.filter((s) => s.filter !== null));\n</script>\n\n<template>\n <Teleport v-if=\"mounted && teleportTarget\" :to=\"teleportTarget\">\n <PlBtnGhost :icon=\"filtersOn ? 'filter-on' : 'filter'\" @click.stop=\"showManager = true\">\n Filters\n </PlBtnGhost>\n </Teleport>\n\n <PlSlideModal v-model=\"showManager\" :close-on-outside-click=\"false\">\n <template #title>Manage Filters</template>\n\n <div ref=\"filterManager\" :class=\"$style['filter-manager']\">\n <PlElementList\n v-model:items=\"items\"\n :on-expand=\"(item) => {\n if (item.filter) {\n item.filter.open = !item.filter.open;\n }\n }\"\n :is-expanded=\"(item) => item.filter?.open ?? false\"\n :on-toggle=\"(item) => {\n if (item.filter) {\n item.filter.disabled = !item.filter.disabled;\n }\n }\"\n :is-toggled=\"(item) => item.filter?.disabled ?? false\"\n :on-remove=\"(item) => {\n if (item.filter) {\n item.filter = null;\n }\n }\"\n :get-item-key=\"(item) => canonicalizeJson<PTableColumnId>(item.id)\"\n disable-dragging\n >\n <template #item-title=\"{ item }\">\n {{ item.label }}\n </template>\n <template #item-content=\"{ index }\">\n <PlTableFilterEntryV2 v-model=\"filters.value[index]\" />\n </template>\n </PlElementList>\n\n <div\n v-if=\"filters.value.length\"\n :class=\"$style['add-action-wrapper']\"\n >\n <button\n :disabled=\"!canAddFilter\"\n :class=\"$style['add-btn']\"\n @click=\"showAddFilter = true\"\n >\n <PlMaskIcon16 name=\"add\" />\n <div :class=\"$style['add-btn-title']\">Add Filter</div>\n </button>\n\n <PlBtnSecondary\n :disabled=\"!canResetToDefaults\"\n @click.stop=\"resetToDefaults\"\n >\n Reset to defaults\n </PlBtnSecondary>\n </div>\n\n <div v-if=\"!filters.value.length\">No filters applicable</div>\n </div>\n </PlSlideModal>\n\n <PlTableAddFilterV2\n v-model=\"showAddFilter\"\n :filters=\"filters.value\"\n :set-filter=\"(idx, filter) => filters.value[idx] = filter\"\n />\n</template>\n\n<style lang=\"scss\" module>\n.filter-manager {\n --expand-icon-rotation: rotate(0deg);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.add-action-wrapper {\n position: sticky;\n bottom: -16px;\n background-color: var(--bg-elevated-01);\n transition: all .15s ease-in-out;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.add-btn {\n height: 40px;\n background-color: var(--bg-elevated-01);\n display: flex;\n align-items: center;\n gap: 8px;\n padding-left: 12px;\n padding-right: 12px;\n border-radius: 6px;\n border: 1px dashed var(--border-color-div-grey);\n line-height: 0;\n cursor: pointer;\n text-align: left;\n}\n\n.add-btn:disabled {\n --icon-color: var(--dis-01);\n cursor: auto;\n}\n\n.add-btn:not([disabled]):hover {\n border-radius: 6px;\n border: 1px dashed var(--border-color-focus, #49CC49);\n background: rgba(99, 224, 36, 0.12);\n}\n\n.add-btn-title {\n flex-grow: 1;\n font-weight: 600;\n}\n\n.expand-icon {\n transition: all .15s ease-in-out;\n transform: var(--expand-icon-rotation);\n line-height: 0;\n cursor: pointer;\n}\n\n.toggle,\n.delete {\n line-height: 0;\n cursor: pointer;\n display: none;\n}\n\n.toggle .mask-24,\n.delete .mask-24 {\n --icon-color: var(--ic-02);\n}\n\n.toggle:hover .mask-24 {\n --icon-color: var(--ic-01);\n}\n\n.delete:hover .mask-24 {\n --icon-color: var(--ic-01);\n}\n\n.filter:hover .toggle,\n.filter:hover .delete {\n display: block;\n}\n\n.filter {\n border-radius: 6px;\n border: 1px solid var(--border-color-div-grey);\n background-color: var(--bg-base-light);\n transition: background-color .15s ease-in-out;\n overflow: auto;\n}\n\n.filter.disabled .expand-icon,\n.filter.disabled .title {\n opacity: 0.3;\n}\n\n.filter:hover {\n background-color: var(--bg-elevated-01);\n}\n\n.filter:global(.open) {\n background-color: var(--bg-elevated-01);\n --expand-icon-rotation: rotate(90deg);\n}\n</style>\n"],"names":["state","_useModel","props","__props","settings","toRefs","filters","useFilters","filtersOn","computed","s","mounted","ref","onMounted","teleportTarget","usePlBlockPageTitleTeleportTarget","showManager","scrollIsActive","filterManager","observer","parent","_a","watch","newElement","oldElement","onBeforeUnmount","canAddFilter","showAddFilter","canResetToDefaults","isJsonEqual","_b","resetToDefaults","items"],"mappings":";;;;;;;;;;;;;;;;;;;AA8BA,UAAMA,IAAQC,iBAEb,GACKC,IAAQC,GAGR,EAAE,UAAAC,EAAA,IAAaC,EAAOH,CAAK,GAE3BI,IAAUC,EAAWH,GAAUJ,CAAK,GAEpCQ,IAAYC,EAAkB,MAAMH,EAAQ,MAAM,KAAK,CAACI,MAAMA,EAAE,UAAU,CAACA,EAAE,OAAO,QAAQ,CAAC,GAE7FC,IAAUC,EAAI,EAAK;AACzB,IAAAC,EAAU,MAAM;AACd,MAAAF,EAAQ,QAAQ;AAAA,IAClB,CAAC;AACD,UAAMG,IAAiBC,EAAkC,kBAAkB,GAErEC,IAAcJ,EAAI,EAAK,GAEvBK,IAAiBL,EAAI,EAAK,GAC1BM,IAAgBN,EAAA;AACtB,QAAIO;AACJ,IAAAN,EAAU,MAAM;AACd,MAAAM,IAAW,IAAI,eAAe,MAAM;;AAClC,cAAMC,KAASC,IAAAH,EAAc,UAAd,gBAAAG,EAAqB;AACpC,QAAKD,MACLH,EAAe,QAAQG,EAAO,eAAeA,EAAO,gBAAgBA,EAAO,cAAcA,EAAO;AAAA,MAClG,CAAC,GACGF,EAAc,SAASA,EAAc,MAAM,iBAC7CC,EAAS,QAAQD,EAAc,MAAO,aAAa;AAAA,IAEvD,CAAC,GAEDI,EAAMJ,GAAe,CAACK,GAAYC,MAAe;AAC/C,MAAIA,KAAA,QAAAA,EAAY,iBACdL,EAAS,UAAUK,EAAW,aAAa,GAEzCD,KAAA,QAAAA,EAAY,iBACdJ,EAAS,QAAQI,EAAW,aAAa;AAAA,IAE7C,CAAC,GAEDE,EAAgB,MAAM;AACpB,MAAIN,MAAa,UACfA,EAAS,WAAA;AAAA,IAEb,CAAC;AAED,UAAMO,IAAejB,EAAkB,MAAMH,EAAQ,MAAM,KAAK,CAACI,MAAM,CAACA,EAAE,MAAM,CAAC,GAC3EiB,IAAgBf,EAAI,EAAK,GAEzBgB,IAAqBnB,EAAkB,MACpCH,EAAQ,MACZ,KAAK,CAACI;;AAAO,cAACA,EAAE,iBAAiBA,EAAE,UAAYA,EAAE,oBAC5CW,IAAAX,EAAE,WAAF,gBAAAW,EAAU,cAAa,MAAQ,CAACQ,IAAYC,IAAApB,EAAE,WAAF,gBAAAoB,EAAU,OAAOpB,EAAE,aAAa;AAAA,KAAG,CACxF,GACKqB,IAAkB,MAAM;AAC5B,MAAAzB,EAAQ,MAAM,QAAQ,CAACI,MAAM;AAC3B,QAAIA,EAAE,gBACJA,EAAE,SAAS;AAAA,UACT,OAAOA,EAAE;AAAA,UACT,UAAU;AAAA,UACV,MAAM;AAAA,QAAA,IAGRA,EAAE,SAAS;AAAA,MAEf,CAAC;AAAA,IACH,GAEMsB,IAAQvB,EAAS,MAAMH,EAAQ,MAAM,OAAO,CAACI,MAAMA,EAAE,WAAW,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"PlTableFiltersV2.vue2.js","sources":["../../../src/components/PlTableFilters/PlTableFiltersV2.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport {\n type PlDataTableFilterState,\n canonicalizeJson,\n type PTableColumnId,\n} from '@platforma-sdk/model';\nimport type {\n PlDataTableFiltersSettings,\n} from './types';\nimport {\n computed,\n onBeforeUnmount,\n onMounted,\n ref,\n toRefs,\n watch,\n} from 'vue';\nimport {\n PlBtnGhost,\n PlSlideModal,\n PlBtnSecondary,\n PlMaskIcon16,\n PlElementList,\n usePlBlockPageTitleTeleportTarget,\n} from '@milaboratories/uikit';\nimport { useFilters } from './filters-state';\nimport PlTableAddFilterV2 from './PlTableAddFilterV2.vue';\nimport PlTableFilterEntryV2 from './PlTableFilterEntryV2.vue';\nimport { isJsonEqual } from '@milaboratories/helpers';\n\nconst state = defineModel<PlDataTableFilterState[]>({\n default: [],\n});\nconst props = defineProps<{\n settings: Readonly<PlDataTableFiltersSettings>;\n}>();\nconst { settings } = toRefs(props);\n\nconst filters = useFilters(settings, state);\n\nconst filtersOn = computed<boolean>(() => filters.value.some((s) => s.filter && !s.filter.disabled));\n\nconst mounted = ref(false);\nonMounted(() => {\n mounted.value = true;\n});\nconst teleportTarget = usePlBlockPageTitleTeleportTarget('PlTableFiltersV2');\n\nconst showManager = ref(false);\n\nconst scrollIsActive = ref(false);\nconst filterManager = ref<HTMLElement>();\nlet observer: ResizeObserver;\nonMounted(() => {\n observer = new ResizeObserver(() => {\n const parent = filterManager.value?.parentElement;\n if (!parent) return;\n scrollIsActive.value = parent.scrollHeight > parent.clientHeight || parent.scrollWidth > parent.clientWidth;\n });\n if (filterManager.value && filterManager.value.parentElement) {\n observer.observe(filterManager.value!.parentElement);\n }\n});\n\nwatch(filterManager, (newElement, oldElement) => {\n if (oldElement?.parentElement) {\n observer.unobserve(oldElement.parentElement);\n }\n if (newElement?.parentElement) {\n observer.observe(newElement.parentElement);\n }\n});\n\nonBeforeUnmount(() => {\n if (observer !== undefined) {\n observer.disconnect();\n }\n});\n\nconst canAddFilter = computed<boolean>(() => filters.value.some((s) => !s.filter));\nconst showAddFilter = ref(false);\n\nconst canResetToDefaults = computed<boolean>(() => {\n return filters.value\n .some((s) => (!s.defaultFilter && s.filter) || (s.defaultFilter\n && (s.filter?.disabled === true || !isJsonEqual(s.filter?.value, s.defaultFilter))));\n});\nconst resetToDefaults = () => {\n filters.value.forEach((s) => {\n if (s.defaultFilter) {\n s.filter = {\n value: s.defaultFilter,\n disabled: false,\n open: false,\n };\n } else {\n s.filter = null;\n }\n });\n};\n\nconst items = computed(() => filters.value.filter((s) => s.filter !== null));\n</script>\n\n<template>\n <Teleport v-if=\"mounted && teleportTarget\" :to=\"teleportTarget\">\n <PlBtnGhost :icon=\"filtersOn ? 'filter-on' : 'filter'\" @click.stop=\"showManager = true\">\n Filters\n </PlBtnGhost>\n </Teleport>\n\n <PlSlideModal v-model=\"showManager\" :close-on-outside-click=\"false\">\n <template #title>Manage Filters</template>\n\n <div ref=\"filterManager\" :class=\"$style['filter-manager']\">\n <PlElementList\n v-model:items=\"items\"\n :on-expand=\"(item) => {\n if (item.filter) {\n item.filter.open = !item.filter.open;\n }\n }\"\n :is-expanded=\"(item) => item.filter?.open ?? false\"\n :on-toggle=\"(item) => {\n if (item.filter) {\n item.filter.disabled = !item.filter.disabled;\n }\n }\"\n :is-toggled=\"(item) => item.filter?.disabled ?? false\"\n :on-remove=\"(item) => {\n if (item.filter) {\n item.filter = null;\n }\n }\"\n :get-item-key=\"(item) => canonicalizeJson<PTableColumnId>(item.id)\"\n disable-dragging\n >\n <template #item-title=\"{ item }\">\n {{ item.label }}\n </template>\n <template #item-content=\"{ index }\">\n <PlTableFilterEntryV2 v-model=\"filters.value[index]\" />\n </template>\n </PlElementList>\n\n <div\n v-if=\"filters.value.length\"\n :class=\"$style['add-action-wrapper']\"\n >\n <button\n :disabled=\"!canAddFilter\"\n :class=\"$style['add-btn']\"\n @click=\"showAddFilter = true\"\n >\n <PlMaskIcon16 name=\"add\" />\n <div :class=\"$style['add-btn-title']\">Add Filter</div>\n </button>\n\n <PlBtnSecondary\n :disabled=\"!canResetToDefaults\"\n @click.stop=\"resetToDefaults\"\n >\n Reset to defaults\n </PlBtnSecondary>\n </div>\n\n <div v-if=\"!filters.value.length\">No filters applicable</div>\n </div>\n </PlSlideModal>\n\n <PlTableAddFilterV2\n v-model=\"showAddFilter\"\n :filters=\"filters.value\"\n :set-filter=\"(idx, filter) => filters.value[idx] = filter\"\n />\n</template>\n\n<style lang=\"scss\" module>\n.filter-manager {\n --expand-icon-rotation: rotate(0deg);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.add-action-wrapper {\n position: sticky;\n bottom: -16px;\n background-color: var(--bg-elevated-01);\n transition: all .15s ease-in-out;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.add-btn {\n height: 40px;\n background-color: var(--bg-elevated-01);\n display: flex;\n align-items: center;\n gap: 8px;\n padding-left: 12px;\n padding-right: 12px;\n border-radius: 6px;\n border: 1px dashed var(--border-color-div-grey);\n line-height: 0;\n cursor: pointer;\n text-align: left;\n}\n\n.add-btn:disabled {\n --icon-color: var(--dis-01);\n cursor: auto;\n}\n\n.add-btn:not([disabled]):hover {\n border-radius: 6px;\n border: 1px dashed var(--border-color-focus, #49CC49);\n background: rgba(99, 224, 36, 0.12);\n}\n\n.add-btn-title {\n flex-grow: 1;\n font-weight: 600;\n}\n\n.expand-icon {\n transition: all .15s ease-in-out;\n transform: var(--expand-icon-rotation);\n line-height: 0;\n cursor: pointer;\n}\n\n.toggle,\n.delete {\n line-height: 0;\n cursor: pointer;\n display: none;\n}\n\n.toggle .mask-24,\n.delete .mask-24 {\n --icon-color: var(--ic-02);\n}\n\n.toggle:hover .mask-24 {\n --icon-color: var(--ic-01);\n}\n\n.delete:hover .mask-24 {\n --icon-color: var(--ic-01);\n}\n\n.filter:hover .toggle,\n.filter:hover .delete {\n display: block;\n}\n\n.filter {\n border-radius: 6px;\n border: 1px solid var(--border-color-div-grey);\n background-color: var(--bg-base-light);\n transition: background-color .15s ease-in-out;\n overflow: auto;\n}\n\n.filter.disabled .expand-icon,\n.filter.disabled .title {\n opacity: 0.3;\n}\n\n.filter:hover {\n background-color: var(--bg-elevated-01);\n}\n\n.filter:global(.open) {\n background-color: var(--bg-elevated-01);\n --expand-icon-rotation: rotate(90deg);\n}\n</style>\n"],"names":["state","_useModel","props","__props","settings","toRefs","filters","useFilters","filtersOn","computed","s","mounted","ref","onMounted","teleportTarget","usePlBlockPageTitleTeleportTarget","showManager","scrollIsActive","filterManager","observer","parent","_a","watch","newElement","oldElement","onBeforeUnmount","canAddFilter","showAddFilter","canResetToDefaults","isJsonEqual","_b","resetToDefaults","items"],"mappings":";;;;;;;;;;;;;;;;;;;;AA8BA,UAAMA,IAAQC,iBAEb,GACKC,IAAQC,GAGR,EAAE,UAAAC,EAAA,IAAaC,EAAOH,CAAK,GAE3BI,IAAUC,EAAWH,GAAUJ,CAAK,GAEpCQ,IAAYC,EAAkB,MAAMH,EAAQ,MAAM,KAAK,CAACI,MAAMA,EAAE,UAAU,CAACA,EAAE,OAAO,QAAQ,CAAC,GAE7FC,IAAUC,EAAI,EAAK;AACzB,IAAAC,EAAU,MAAM;AACd,MAAAF,EAAQ,QAAQ;AAAA,IAClB,CAAC;AACD,UAAMG,IAAiBC,EAAkC,kBAAkB,GAErEC,IAAcJ,EAAI,EAAK,GAEvBK,IAAiBL,EAAI,EAAK,GAC1BM,IAAgBN,EAAA;AACtB,QAAIO;AACJ,IAAAN,EAAU,MAAM;AACd,MAAAM,IAAW,IAAI,eAAe,MAAM;;AAClC,cAAMC,KAASC,IAAAH,EAAc,UAAd,gBAAAG,EAAqB;AACpC,QAAKD,MACLH,EAAe,QAAQG,EAAO,eAAeA,EAAO,gBAAgBA,EAAO,cAAcA,EAAO;AAAA,MAClG,CAAC,GACGF,EAAc,SAASA,EAAc,MAAM,iBAC7CC,EAAS,QAAQD,EAAc,MAAO,aAAa;AAAA,IAEvD,CAAC,GAEDI,EAAMJ,GAAe,CAACK,GAAYC,MAAe;AAC/C,MAAIA,KAAA,QAAAA,EAAY,iBACdL,EAAS,UAAUK,EAAW,aAAa,GAEzCD,KAAA,QAAAA,EAAY,iBACdJ,EAAS,QAAQI,EAAW,aAAa;AAAA,IAE7C,CAAC,GAEDE,EAAgB,MAAM;AACpB,MAAIN,MAAa,UACfA,EAAS,WAAA;AAAA,IAEb,CAAC;AAED,UAAMO,IAAejB,EAAkB,MAAMH,EAAQ,MAAM,KAAK,CAACI,MAAM,CAACA,EAAE,MAAM,CAAC,GAC3EiB,IAAgBf,EAAI,EAAK,GAEzBgB,IAAqBnB,EAAkB,MACpCH,EAAQ,MACZ,KAAK,CAACI;;AAAO,cAACA,EAAE,iBAAiBA,EAAE,UAAYA,EAAE,oBAC5CW,IAAAX,EAAE,WAAF,gBAAAW,EAAU,cAAa,MAAQ,CAACQ,IAAYC,IAAApB,EAAE,WAAF,gBAAAoB,EAAU,OAAOpB,EAAE,aAAa;AAAA,KAAG,CACxF,GACKqB,IAAkB,MAAM;AAC5B,MAAAzB,EAAQ,MAAM,QAAQ,CAACI,MAAM;AAC3B,QAAIA,EAAE,gBACJA,EAAE,SAAS;AAAA,UACT,OAAOA,EAAE;AAAA,UACT,UAAU;AAAA,UACV,MAAM;AAAA,QAAA,IAGRA,EAAE,SAAS;AAAA,MAEf,CAAC;AAAA,IACH,GAEMsB,IAAQvB,EAAS,MAAMH,EAAQ,MAAM,OAAO,CAACI,MAAMA,EAAE,WAAW,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,21 +1,22 @@
1
1
  import { ref as J, reactive as V, watch as h } from "vue";
2
2
  import { getPTableColumnId as k, canonicalizeJson as f } from "@platforma-sdk/model";
3
3
  import { isJsonEqual as b } from "../../lib/util/helpers/dist/objects.js";
4
+ import "../../lib/util/helpers/dist/test_timeouts.js";
4
5
  import { getFilterOptions as g, makeDiscreteOptions as q, isFilterValid as F, isAlphabetic as x, getColumnName as z } from "./filters_logic.js";
5
- function K(M, m) {
6
+ function N(M, m) {
6
7
  const w = J(/* @__PURE__ */ new Map()), o = V({
7
8
  value: []
8
9
  });
9
10
  return h(
10
11
  () => M.value,
11
12
  ({ columns: d, config: n, cachedState: i }) => {
12
- const c = w.value = new Map(
13
+ const p = w.value = new Map(
13
14
  d.map((e, t) => {
14
15
  try {
15
16
  const a = k(e), l = n(e), r = l.options ? g(e).filter((y) => l.options.includes(y.value)) : g(e);
16
17
  if (r.length === 0) return null;
17
- const u = q(e), p = l.default && F(l.default, r, u) ? l.default : null, S = p ? {
18
- value: p,
18
+ const u = q(e), c = l.default && F(l.default, r, u) ? l.default : null, S = c ? {
19
+ value: c,
19
20
  disabled: !1,
20
21
  open: !1
21
22
  } : null, C = {
@@ -25,7 +26,7 @@ function K(M, m) {
25
26
  alphabetic: x(e),
26
27
  options: r,
27
28
  discreteOptions: u,
28
- defaultFilter: p,
29
+ defaultFilter: c,
29
30
  filter: S
30
31
  };
31
32
  return [f(a), C];
@@ -34,9 +35,9 @@ function K(M, m) {
34
35
  }
35
36
  }).filter((e) => e !== null)
36
37
  ), s = new Map(
37
- i.filter((e) => c.has(f(e.id))).map((e) => {
38
+ i.filter((e) => p.has(f(e.id))).map((e) => {
38
39
  var l, r;
39
- const t = c.get(f(e.id)), a = {
40
+ const t = p.get(f(e.id)), a = {
40
41
  ...t,
41
42
  filter: e.filter && F(e.filter.value, t.options, t.discreteOptions) ? {
42
43
  ...e.filter,
@@ -46,7 +47,7 @@ function K(M, m) {
46
47
  return [f(e.id), a];
47
48
  })
48
49
  );
49
- for (const [e, t] of c)
50
+ for (const [e, t] of p)
50
51
  s.has(e) || s.set(e, t);
51
52
  const v = [...s.values().filter((e) => e.filter)], O = [...s.values().filter((e) => !e.filter)];
52
53
  v.push(...O.sort((e, t) => e.label.localeCompare(t.label))), o.value = v;
@@ -72,6 +73,6 @@ function K(M, m) {
72
73
  ), o;
73
74
  }
74
75
  export {
75
- K as useFilters
76
+ N as useFilters
76
77
  };
77
78
  //# sourceMappingURL=filters-state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filters-state.js","sources":["../../../src/components/PlTableFilters/filters-state.ts"],"sourcesContent":["import type {\n Reactive,\n Ref } from 'vue';\nimport {\n reactive,\n ref,\n watch,\n} from 'vue';\nimport type {\n PlDataTableFiltersSettings,\n PlDataTableFilterStateInternal,\n} from './types';\nimport {\n canonicalizeJson,\n getPTableColumnId,\n type CanonicalizedJson,\n type PTableColumnId,\n type PlDataTableFilterState,\n} from '@platforma-sdk/model';\nimport { isJsonEqual } from '@milaboratories/helpers';\nimport {\n getFilterOptions,\n makeDiscreteOptions,\n isFilterValid,\n getColumnName,\n isAlphabetic,\n} from './filters_logic';\n\nexport function useFilters(\n settings: Ref<PlDataTableFiltersSettings>,\n state: Ref<PlDataTableFilterState[]>,\n): Reactive<{\n value: PlDataTableFilterStateInternal[];\n }> {\n// Watcher instead of computed to preserve open state of filters locally\n const defaultStateMap = ref<Map<CanonicalizedJson<PTableColumnId>, PlDataTableFilterStateInternal>>(new Map());\n const filters = reactive<{\n value: PlDataTableFilterStateInternal[];\n }>({\n value: [],\n });\n watch(\n () => settings.value,\n ({ columns, config: configFn, cachedState }) => {\n // Comptute default states for columns\n const defaultStateMapValue = defaultStateMap.value = new Map(\n columns\n .map((c, i) => {\n try {\n const id = getPTableColumnId(c);\n const config = configFn(c);\n const options = config.options\n ? getFilterOptions(c).filter((o) => config.options!.includes(o.value))\n : getFilterOptions(c);\n if (options.length === 0) return null;\n const discreteOptions = makeDiscreteOptions(c);\n const defaultFilter = config.default && isFilterValid(config.default, options, discreteOptions) ? config.default : null;\n const filter = defaultFilter\n ? {\n value: defaultFilter,\n disabled: false,\n open: false,\n }\n : null;\n const state: PlDataTableFilterStateInternal = {\n id,\n spec: c,\n label: getColumnName(c, i),\n alphabetic: isAlphabetic(c),\n options,\n discreteOptions,\n defaultFilter,\n filter,\n };\n return [canonicalizeJson<PTableColumnId>(id), state] as const;\n } catch (err: unknown) {\n console.error(`Filter creation for column ${c.id} has failed`, err);\n return null;\n }\n })\n .filter((e) => e !== null),\n );\n\n // Go through cached state, filter out states for not present columns, update state to match valid options\n const stateMap = new Map<CanonicalizedJson<PTableColumnId>, PlDataTableFilterStateInternal>(\n cachedState\n .filter((s) => defaultStateMapValue.has(canonicalizeJson<PTableColumnId>(s.id)))\n .map((s) => {\n const defaultState = defaultStateMapValue.get(canonicalizeJson<PTableColumnId>(s.id))!;\n const state = {\n ...defaultState,\n filter: s.filter && isFilterValid(s.filter.value, defaultState.options, defaultState.discreteOptions)\n ? {\n ...s.filter,\n open: filters.value.find((f) => isJsonEqual(f.id, s.id))?.filter?.open ?? false,\n }\n : null,\n } satisfies PlDataTableFilterStateInternal;\n return [canonicalizeJson<PTableColumnId>(s.id), state] as const;\n }),\n );\n\n // Set default states for columns not present in cached state\n for (const [idKey, state] of defaultStateMapValue) {\n if (!stateMap.has(idKey)) {\n stateMap.set(idKey, state);\n }\n }\n\n // States with not null filters should go first, in order they were added, then follow null filters in alphabetic order\n const states = [...stateMap.values().filter((s) => s.filter)];\n const hiddenFilters = [...stateMap.values().filter((s) => !s.filter)];\n states.push(...hiddenFilters.sort((a, b) => a.label.localeCompare(b.label)));\n filters.value = states;\n },\n { immediate: true },\n );\n\n // Persist state on change\n watch(\n () => filters.value,\n (filters) => {\n const cachedState = filters.map((f) => ({\n id: f.id,\n alphabetic: f.alphabetic,\n filter: f.filter\n ? {\n value: f.filter.value,\n disabled: f.filter.disabled,\n }\n : null,\n } satisfies PlDataTableFilterState));\n if (cachedState.length > 0 && !isJsonEqual(cachedState, state.value)) {\n state.value = cachedState;\n }\n },\n {\n immediate: true,\n deep: true,\n },\n );\n\n return filters;\n}\n"],"names":["useFilters","settings","state","defaultStateMap","ref","filters","reactive","watch","columns","configFn","cachedState","defaultStateMapValue","c","i","id","getPTableColumnId","config","options","getFilterOptions","o","discreteOptions","makeDiscreteOptions","defaultFilter","isFilterValid","filter","getColumnName","isAlphabetic","canonicalizeJson","err","stateMap","s","defaultState","_b","_a","f","isJsonEqual","idKey","states","hiddenFilters","a","b"],"mappings":"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"}
1
+ {"version":3,"file":"filters-state.js","sources":["../../../src/components/PlTableFilters/filters-state.ts"],"sourcesContent":["import type {\n Reactive,\n Ref } from 'vue';\nimport {\n reactive,\n ref,\n watch,\n} from 'vue';\nimport type {\n PlDataTableFiltersSettings,\n PlDataTableFilterStateInternal,\n} from './types';\nimport {\n canonicalizeJson,\n getPTableColumnId,\n type CanonicalizedJson,\n type PTableColumnId,\n type PlDataTableFilterState,\n} from '@platforma-sdk/model';\nimport { isJsonEqual } from '@milaboratories/helpers';\nimport {\n getFilterOptions,\n makeDiscreteOptions,\n isFilterValid,\n getColumnName,\n isAlphabetic,\n} from './filters_logic';\n\nexport function useFilters(\n settings: Ref<PlDataTableFiltersSettings>,\n state: Ref<PlDataTableFilterState[]>,\n): Reactive<{\n value: PlDataTableFilterStateInternal[];\n }> {\n// Watcher instead of computed to preserve open state of filters locally\n const defaultStateMap = ref<Map<CanonicalizedJson<PTableColumnId>, PlDataTableFilterStateInternal>>(new Map());\n const filters = reactive<{\n value: PlDataTableFilterStateInternal[];\n }>({\n value: [],\n });\n watch(\n () => settings.value,\n ({ columns, config: configFn, cachedState }) => {\n // Comptute default states for columns\n const defaultStateMapValue = defaultStateMap.value = new Map(\n columns\n .map((c, i) => {\n try {\n const id = getPTableColumnId(c);\n const config = configFn(c);\n const options = config.options\n ? getFilterOptions(c).filter((o) => config.options!.includes(o.value))\n : getFilterOptions(c);\n if (options.length === 0) return null;\n const discreteOptions = makeDiscreteOptions(c);\n const defaultFilter = config.default && isFilterValid(config.default, options, discreteOptions) ? config.default : null;\n const filter = defaultFilter\n ? {\n value: defaultFilter,\n disabled: false,\n open: false,\n }\n : null;\n const state: PlDataTableFilterStateInternal = {\n id,\n spec: c,\n label: getColumnName(c, i),\n alphabetic: isAlphabetic(c),\n options,\n discreteOptions,\n defaultFilter,\n filter,\n };\n return [canonicalizeJson<PTableColumnId>(id), state] as const;\n } catch (err: unknown) {\n console.error(`Filter creation for column ${c.id} has failed`, err);\n return null;\n }\n })\n .filter((e) => e !== null),\n );\n\n // Go through cached state, filter out states for not present columns, update state to match valid options\n const stateMap = new Map<CanonicalizedJson<PTableColumnId>, PlDataTableFilterStateInternal>(\n cachedState\n .filter((s) => defaultStateMapValue.has(canonicalizeJson<PTableColumnId>(s.id)))\n .map((s) => {\n const defaultState = defaultStateMapValue.get(canonicalizeJson<PTableColumnId>(s.id))!;\n const state = {\n ...defaultState,\n filter: s.filter && isFilterValid(s.filter.value, defaultState.options, defaultState.discreteOptions)\n ? {\n ...s.filter,\n open: filters.value.find((f) => isJsonEqual(f.id, s.id))?.filter?.open ?? false,\n }\n : null,\n } satisfies PlDataTableFilterStateInternal;\n return [canonicalizeJson<PTableColumnId>(s.id), state] as const;\n }),\n );\n\n // Set default states for columns not present in cached state\n for (const [idKey, state] of defaultStateMapValue) {\n if (!stateMap.has(idKey)) {\n stateMap.set(idKey, state);\n }\n }\n\n // States with not null filters should go first, in order they were added, then follow null filters in alphabetic order\n const states = [...stateMap.values().filter((s) => s.filter)];\n const hiddenFilters = [...stateMap.values().filter((s) => !s.filter)];\n states.push(...hiddenFilters.sort((a, b) => a.label.localeCompare(b.label)));\n filters.value = states;\n },\n { immediate: true },\n );\n\n // Persist state on change\n watch(\n () => filters.value,\n (filters) => {\n const cachedState = filters.map((f) => ({\n id: f.id,\n alphabetic: f.alphabetic,\n filter: f.filter\n ? {\n value: f.filter.value,\n disabled: f.filter.disabled,\n }\n : null,\n } satisfies PlDataTableFilterState));\n if (cachedState.length > 0 && !isJsonEqual(cachedState, state.value)) {\n state.value = cachedState;\n }\n },\n {\n immediate: true,\n deep: true,\n },\n );\n\n return filters;\n}\n"],"names":["useFilters","settings","state","defaultStateMap","ref","filters","reactive","watch","columns","configFn","cachedState","defaultStateMapValue","c","i","id","getPTableColumnId","config","options","getFilterOptions","o","discreteOptions","makeDiscreteOptions","defaultFilter","isFilterValid","filter","getColumnName","isAlphabetic","canonicalizeJson","err","stateMap","s","defaultState","_b","_a","f","isJsonEqual","idKey","states","hiddenFilters","a","b"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import { ref as v, watch as i, computed as l, unref as y, reactive as C } from "vue";
2
2
  import { isJsonEqual as Z, deepClone as m } from "./lib/util/helpers/dist/objects.js";
3
+ import "./lib/util/helpers/dist/test_timeouts.js";
3
4
  import { identity as q, isZodError as w, ensureError as x, formatZodError as J } from "./utils.js";
4
- function j(o) {
5
+ function k(o) {
5
6
  const u = o.validate ?? q, { autoSave: f } = o, r = v(), a = v(), c = (e) => {
6
7
  a.value = {
7
8
  model: m(e)
@@ -56,6 +57,6 @@ function j(o) {
56
57
  });
57
58
  }
58
59
  export {
59
- j as createModel
60
+ k as createModel
60
61
  };
61
62
  //# sourceMappingURL=createModel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createModel.js","sources":["../src/createModel.ts"],"sourcesContent":["import { reactive, computed, ref, watch, unref } from 'vue';\nimport type { ModelOptions, Model } from './types';\nimport { deepClone, isJsonEqual } from '@milaboratories/helpers';\nimport { identity, ensureError, isZodError, formatZodError } from './utils';\n\nexport function createModel<M, V = unknown>(options: ModelOptions<M, V>): Model<M> {\n const validate = options.validate ?? identity;\n\n const { autoSave } = options;\n\n const error = ref<Error | undefined>();\n\n const local = ref<{ model: M }>();\n\n const setSource = (v: M) => {\n local.value = {\n model: deepClone(v),\n };\n };\n\n watch(\n () => options.get(),\n (v) => setSource(v),\n { immediate: true },\n );\n\n const save = () => {\n options.onSave(validate(deepClone(local.value?.model)));\n };\n\n const revert = () => {\n setSource(options.get());\n error.value = undefined;\n };\n\n const setError = (cause: unknown) => {\n const err = ensureError(cause);\n if (isZodError(err)) {\n error.value = Error(formatZodError(err)); // @todo temp\n } else {\n error.value = err;\n }\n };\n\n const setValue = (v: M) => {\n error.value = undefined;\n try {\n validate(v);\n if (autoSave) {\n save();\n }\n } catch (cause: unknown) {\n setError(cause);\n }\n };\n\n const model = computed<M>({\n get: () => {\n return local.value?.model as M;\n },\n set(v) {\n setSource(v);\n setValue(v);\n },\n });\n\n watch(\n local,\n (n, o) => {\n if (n && n === o) {\n setValue(n.model);\n }\n },\n { deep: true },\n );\n\n const valid = computed(() => !error.value);\n\n const isChanged = computed(() => {\n return !isJsonEqual(options.get(), unref(local));\n });\n\n const errorString = computed(() => (error.value ? error.value.message : ''));\n\n return reactive({\n model,\n valid,\n isChanged,\n error,\n errorString,\n save,\n revert,\n setError,\n });\n}\n"],"names":["createModel","options","validate","identity","autoSave","error","ref","local","setSource","v","deepClone","watch","save","_a","revert","setError","cause","err","ensureError","isZodError","formatZodError","setValue","model","computed","n","o","valid","isChanged","isJsonEqual","unref","errorString","reactive"],"mappings":";;;AAKO,SAASA,EAA4BC,GAAuC;AACjF,QAAMC,IAAWD,EAAQ,YAAYE,GAE/B,EAAE,UAAAC,MAAaH,GAEfI,IAAQC,EAAA,GAERC,IAAQD,EAAA,GAERE,IAAY,CAACC,MAAS;AAC1B,IAAAF,EAAM,QAAQ;AAAA,MACZ,OAAOG,EAAUD,CAAC;AAAA,IAAA;AAAA,EAEtB;AAEA,EAAAE;AAAA,IACE,MAAMV,EAAQ,IAAA;AAAA,IACd,CAACQ,MAAMD,EAAUC,CAAC;AAAA,IAClB,EAAE,WAAW,GAAA;AAAA,EAAK;AAGpB,QAAMG,IAAO,MAAM;;AACjB,IAAAX,EAAQ,OAAOC,EAASQ,GAAUG,IAAAN,EAAM,UAAN,gBAAAM,EAAa,KAAK,CAAC,CAAC;AAAA,EACxD,GAEMC,IAAS,MAAM;AACnB,IAAAN,EAAUP,EAAQ,KAAK,GACvBI,EAAM,QAAQ;AAAA,EAChB,GAEMU,IAAW,CAACC,MAAmB;AACnC,UAAMC,IAAMC,EAAYF,CAAK;AAC7B,IAAIG,EAAWF,CAAG,IAChBZ,EAAM,QAAQ,MAAMe,EAAeH,CAAG,CAAC,IAEvCZ,EAAM,QAAQY;AAAA,EAElB,GAEMI,IAAW,CAACZ,MAAS;AACzB,IAAAJ,EAAM,QAAQ;AACd,QAAI;AACF,MAAAH,EAASO,CAAC,GACNL,KACFQ,EAAA;AAAA,IAEJ,SAASI,GAAgB;AACvB,MAAAD,EAASC,CAAK;AAAA,IAChB;AAAA,EACF,GAEMM,IAAQC,EAAY;AAAA,IACxB,KAAK,MAAM;;AACT,cAAOV,IAAAN,EAAM,UAAN,gBAAAM,EAAa;AAAA,IACtB;AAAA,IACA,IAAIJ,GAAG;AACL,MAAAD,EAAUC,CAAC,GACXY,EAASZ,CAAC;AAAA,IACZ;AAAA,EAAA,CACD;AAED,EAAAE;AAAA,IACEJ;AAAA,IACA,CAACiB,GAAGC,MAAM;AACR,MAAID,KAAKA,MAAMC,KACbJ,EAASG,EAAE,KAAK;AAAA,IAEpB;AAAA,IACA,EAAE,MAAM,GAAA;AAAA,EAAK;AAGf,QAAME,IAAQH,EAAS,MAAM,CAAClB,EAAM,KAAK,GAEnCsB,IAAYJ,EAAS,MAClB,CAACK,EAAY3B,EAAQ,OAAO4B,EAAMtB,CAAK,CAAC,CAChD,GAEKuB,IAAcP,EAAS,MAAOlB,EAAM,QAAQA,EAAM,MAAM,UAAU,EAAG;AAE3E,SAAO0B,EAAS;AAAA,IACd,OAAAT;AAAA,IACA,OAAAI;AAAA,IACA,WAAAC;AAAA,IACA,OAAAtB;AAAA,IACA,aAAAyB;AAAA,IACA,MAAAlB;AAAA,IACA,QAAAE;AAAA,IACA,UAAAC;AAAA,EAAA,CACD;AACH;"}
1
+ {"version":3,"file":"createModel.js","sources":["../src/createModel.ts"],"sourcesContent":["import { reactive, computed, ref, watch, unref } from 'vue';\nimport type { ModelOptions, Model } from './types';\nimport { deepClone, isJsonEqual } from '@milaboratories/helpers';\nimport { identity, ensureError, isZodError, formatZodError } from './utils';\n\nexport function createModel<M, V = unknown>(options: ModelOptions<M, V>): Model<M> {\n const validate = options.validate ?? identity;\n\n const { autoSave } = options;\n\n const error = ref<Error | undefined>();\n\n const local = ref<{ model: M }>();\n\n const setSource = (v: M) => {\n local.value = {\n model: deepClone(v),\n };\n };\n\n watch(\n () => options.get(),\n (v) => setSource(v),\n { immediate: true },\n );\n\n const save = () => {\n options.onSave(validate(deepClone(local.value?.model)));\n };\n\n const revert = () => {\n setSource(options.get());\n error.value = undefined;\n };\n\n const setError = (cause: unknown) => {\n const err = ensureError(cause);\n if (isZodError(err)) {\n error.value = Error(formatZodError(err)); // @todo temp\n } else {\n error.value = err;\n }\n };\n\n const setValue = (v: M) => {\n error.value = undefined;\n try {\n validate(v);\n if (autoSave) {\n save();\n }\n } catch (cause: unknown) {\n setError(cause);\n }\n };\n\n const model = computed<M>({\n get: () => {\n return local.value?.model as M;\n },\n set(v) {\n setSource(v);\n setValue(v);\n },\n });\n\n watch(\n local,\n (n, o) => {\n if (n && n === o) {\n setValue(n.model);\n }\n },\n { deep: true },\n );\n\n const valid = computed(() => !error.value);\n\n const isChanged = computed(() => {\n return !isJsonEqual(options.get(), unref(local));\n });\n\n const errorString = computed(() => (error.value ? error.value.message : ''));\n\n return reactive({\n model,\n valid,\n isChanged,\n error,\n errorString,\n save,\n revert,\n setError,\n });\n}\n"],"names":["createModel","options","validate","identity","autoSave","error","ref","local","setSource","v","deepClone","watch","save","_a","revert","setError","cause","err","ensureError","isZodError","formatZodError","setValue","model","computed","n","o","valid","isChanged","isJsonEqual","unref","errorString","reactive"],"mappings":";;;;AAKO,SAASA,EAA4BC,GAAuC;AACjF,QAAMC,IAAWD,EAAQ,YAAYE,GAE/B,EAAE,UAAAC,MAAaH,GAEfI,IAAQC,EAAA,GAERC,IAAQD,EAAA,GAERE,IAAY,CAACC,MAAS;AAC1B,IAAAF,EAAM,QAAQ;AAAA,MACZ,OAAOG,EAAUD,CAAC;AAAA,IAAA;AAAA,EAEtB;AAEA,EAAAE;AAAA,IACE,MAAMV,EAAQ,IAAA;AAAA,IACd,CAACQ,MAAMD,EAAUC,CAAC;AAAA,IAClB,EAAE,WAAW,GAAA;AAAA,EAAK;AAGpB,QAAMG,IAAO,MAAM;;AACjB,IAAAX,EAAQ,OAAOC,EAASQ,GAAUG,IAAAN,EAAM,UAAN,gBAAAM,EAAa,KAAK,CAAC,CAAC;AAAA,EACxD,GAEMC,IAAS,MAAM;AACnB,IAAAN,EAAUP,EAAQ,KAAK,GACvBI,EAAM,QAAQ;AAAA,EAChB,GAEMU,IAAW,CAACC,MAAmB;AACnC,UAAMC,IAAMC,EAAYF,CAAK;AAC7B,IAAIG,EAAWF,CAAG,IAChBZ,EAAM,QAAQ,MAAMe,EAAeH,CAAG,CAAC,IAEvCZ,EAAM,QAAQY;AAAA,EAElB,GAEMI,IAAW,CAACZ,MAAS;AACzB,IAAAJ,EAAM,QAAQ;AACd,QAAI;AACF,MAAAH,EAASO,CAAC,GACNL,KACFQ,EAAA;AAAA,IAEJ,SAASI,GAAgB;AACvB,MAAAD,EAASC,CAAK;AAAA,IAChB;AAAA,EACF,GAEMM,IAAQC,EAAY;AAAA,IACxB,KAAK,MAAM;;AACT,cAAOV,IAAAN,EAAM,UAAN,gBAAAM,EAAa;AAAA,IACtB;AAAA,IACA,IAAIJ,GAAG;AACL,MAAAD,EAAUC,CAAC,GACXY,EAASZ,CAAC;AAAA,IACZ;AAAA,EAAA,CACD;AAED,EAAAE;AAAA,IACEJ;AAAA,IACA,CAACiB,GAAGC,MAAM;AACR,MAAID,KAAKA,MAAMC,KACbJ,EAASG,EAAE,KAAK;AAAA,IAEpB;AAAA,IACA,EAAE,MAAM,GAAA;AAAA,EAAK;AAGf,QAAME,IAAQH,EAAS,MAAM,CAAClB,EAAM,KAAK,GAEnCsB,IAAYJ,EAAS,MAClB,CAACK,EAAY3B,EAAQ,OAAO4B,EAAMtB,CAAK,CAAC,CAChD,GAEKuB,IAAcP,EAAS,MAAOlB,EAAM,QAAQA,EAAM,MAAM,UAAU,EAAG;AAE3E,SAAO0B,EAAS;AAAA,IACd,OAAAT;AAAA,IACA,OAAAI;AAAA,IACA,WAAAC;AAAA,IACA,OAAAtB;AAAA,IACA,aAAAyB;AAAA,IACA,MAAAlB;AAAA,IACA,QAAAE;AAAA,IACA,UAAAC;AAAA,EAAA,CACD;AACH;"}
package/dist/defineApp.js CHANGED
@@ -1,17 +1,18 @@
1
1
  import { notEmpty as V } from "./lib/util/helpers/dist/utils.js";
2
+ import "./lib/util/helpers/dist/test_timeouts.js";
2
3
  import { getPlatformaApiVersion as g, unwrapResult as k } from "@platforma-sdk/model";
3
4
  import { inject as h, reactive as j, markRaw as f } from "vue";
4
5
  import { createAppV1 as w } from "./internal/createAppV1.js";
5
6
  import { createAppV2 as y } from "./internal/createAppV2.js";
6
7
  import { activateAgGrid as O } from "./aggrid.js";
7
- const b = Symbol("sdk-vue");
8
- function q() {
9
- return h(b);
8
+ const m = Symbol("sdk-vue");
9
+ function $() {
10
+ return h(m);
10
11
  }
11
- function $(e, p, l = {}) {
12
+ function G(e, p, l = {}) {
12
13
  let u;
13
14
  O();
14
- const d = e.apiVersion ?? 1, A = g(), m = async () => {
15
+ const d = e.apiVersion ?? 1, A = g(), b = async () => {
15
16
  if (A !== d)
16
17
  throw new Error(`Block requested API version ${A} but runtime API version is ${d}.
17
18
  Please update the desktop app to use the latest API version.`);
@@ -55,7 +56,7 @@ function $(e, p, l = {}) {
55
56
  // @todo type portability issue with Vue
56
57
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
58
  install(r) {
58
- r.provide(b, this), m().catch((t) => {
59
+ r.provide(m, this), b().catch((t) => {
59
60
  console.error("load initial state error", t), c.error = t;
60
61
  });
61
62
  }
@@ -63,7 +64,7 @@ function $(e, p, l = {}) {
63
64
  return c;
64
65
  }
65
66
  export {
66
- $ as defineApp,
67
- q as useSdkPlugin
67
+ G as defineApp,
68
+ $ as useSdkPlugin
68
69
  };
69
70
  //# sourceMappingURL=defineApp.js.map