@leaflink/stash 48.10.0 → 48.10.1

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 (130) hide show
  1. package/dist/Accordion.js +1 -1
  2. package/dist/ActionsDropdown.js +1 -1
  3. package/dist/AddressSelect.js +1 -1
  4. package/dist/AddressSelect.js.map +1 -1
  5. package/dist/Alert.js +1 -1
  6. package/dist/Alert.js.map +1 -1
  7. package/dist/AppNavigationItem.js +1 -1
  8. package/dist/AppTopbar.js +1 -1
  9. package/dist/Avatar.vue.d.ts +1 -1
  10. package/dist/Badge.js.map +1 -1
  11. package/dist/Button.vue.d.ts +3 -1
  12. package/dist/CardMedia.js +1 -1
  13. package/dist/Carousel.js.map +1 -1
  14. package/dist/ChevronToggle.js +1 -1
  15. package/dist/ChevronToggle.vue_vue_type_script_setup_true_lang-1591294c.js.map +1 -1
  16. package/dist/Chip.js +1 -1
  17. package/dist/Chip.js.map +1 -1
  18. package/dist/Chip.vue.d.ts +1 -1
  19. package/dist/ConfirmationCodeInput.js.map +1 -1
  20. package/dist/ContextSwitcher.js.map +1 -1
  21. package/dist/Copy.js +1 -1
  22. package/dist/CurrencyInput.js +39 -34
  23. package/dist/CurrencyInput.js.map +1 -1
  24. package/dist/DataView.js +1 -1
  25. package/dist/DataView.js.map +1 -1
  26. package/dist/DataViewFilters.js +1 -1
  27. package/dist/DataViewFilters.js.map +1 -1
  28. package/dist/DataViewSortButton.js +1 -1
  29. package/dist/DataViewToolbar.js +1 -1
  30. package/dist/DatePicker.js +3355 -3368
  31. package/dist/DatePicker.js.map +1 -1
  32. package/dist/Dialog.js +75 -69
  33. package/dist/Dialog.js.map +1 -1
  34. package/dist/Dropdown.js +1 -1
  35. package/dist/Dropdown.js.map +1 -1
  36. package/dist/EmptyState.js +2 -2
  37. package/dist/Expand.vue_vue_type_script_setup_true_lang-1751f4a6.js.map +1 -1
  38. package/dist/FileUpload.js +1 -1
  39. package/dist/FileUpload.js.map +1 -1
  40. package/dist/FilterChip.js +1 -1
  41. package/dist/FilterDrawerItem.js +1 -1
  42. package/dist/FilterDropdown.js +1 -1
  43. package/dist/FilterSelect.js +1 -1
  44. package/dist/FilterSelect.js.map +1 -1
  45. package/dist/Filters.js +1 -1
  46. package/dist/Filters.js.map +1 -1
  47. package/dist/HttpError.js +2 -2
  48. package/dist/Icon.js +1 -1
  49. package/dist/Icon.js.map +1 -1
  50. package/dist/IconLabel.js +1 -1
  51. package/dist/IconLabel.vue.d.ts +1 -1
  52. package/dist/Illustration.js +3 -3
  53. package/dist/{Illustration.vue_vue_type_script_setup_true_lang-4b8944da.js → Illustration.vue_vue_type_script_setup_true_lang-e26c3841.js} +2 -2
  54. package/dist/{Illustration.vue_vue_type_script_setup_true_lang-4b8944da.js.map → Illustration.vue_vue_type_script_setup_true_lang-e26c3841.js.map} +1 -1
  55. package/dist/Image.js.map +1 -1
  56. package/dist/InlineEdit.js +1 -1
  57. package/dist/Input.js +1 -1
  58. package/dist/Input.js.map +1 -1
  59. package/dist/InputOptions.js +1 -1
  60. package/dist/LicenseChip.js +1 -1
  61. package/dist/ListView.js +2 -2
  62. package/dist/ListView.js.map +1 -1
  63. package/dist/Logo.vue_vue_type_script_setup_true_lang-d7da48a0.js.map +1 -1
  64. package/dist/Metric.vue.d.ts +1 -1
  65. package/dist/Modal.js +1 -1
  66. package/dist/Modals.js +6 -6
  67. package/dist/Modals.js.map +1 -1
  68. package/dist/ObfuscateText.js +1 -1
  69. package/dist/PageNavigation.js +1 -1
  70. package/dist/PageNavigation.js.map +1 -1
  71. package/dist/Paginate.js +1 -1
  72. package/dist/PlaidLink.js.map +1 -1
  73. package/dist/QuickAction.js +1 -1
  74. package/dist/RadioNew.js.map +1 -1
  75. package/dist/RangeInput.js +1 -1
  76. package/dist/SearchBar.js +1 -1
  77. package/dist/Select.js +709 -653
  78. package/dist/Select.js.map +1 -1
  79. package/dist/SelectStatus.js +1 -1
  80. package/dist/SelectStatus.js.map +1 -1
  81. package/dist/SelectStatus.vue.d.ts +1 -1
  82. package/dist/Skeleton.js.map +1 -1
  83. package/dist/Step.js +1 -1
  84. package/dist/Stepper.js +1 -1
  85. package/dist/Tab.js +1 -1
  86. package/dist/Tab.vue_vue_type_script_setup_true_lang-69d1b046.js.map +1 -1
  87. package/dist/Table.js +2 -2
  88. package/dist/TableCell.js +2 -2
  89. package/dist/TableHeaderCell.js +2 -2
  90. package/dist/TableHeaderRow.js +2 -2
  91. package/dist/TableRow.js +2 -2
  92. package/dist/TableRow.vue.d.ts +1 -1
  93. package/dist/Tabs.js +1 -1
  94. package/dist/TextEditor.js +991 -991
  95. package/dist/TextEditor.js.map +1 -1
  96. package/dist/Textarea.js.map +1 -1
  97. package/dist/Toast.js +274 -252
  98. package/dist/Toast.js.map +1 -1
  99. package/dist/Toasts.js +1 -1
  100. package/dist/ToastsPlugin.js +1 -1
  101. package/dist/components.css +2 -2
  102. package/dist/index-5e5945a9.js.map +1 -1
  103. package/dist/{index-79ce320f.js → index-9e1095ef.js} +6 -4
  104. package/dist/index-9e1095ef.js.map +1 -0
  105. package/dist/index.d.ts +1 -1
  106. package/dist/index.js +1 -1
  107. package/dist/index.js.map +1 -1
  108. package/dist/isDefined-2ce6cde4.js.map +1 -1
  109. package/dist/observe.js.map +1 -1
  110. package/dist/searchFuzzy-74a7de1c.js.map +1 -1
  111. package/dist/sticky.js.map +1 -1
  112. package/dist/tailwind-base.js.map +1 -1
  113. package/dist/toTimeZone-e6e9ab75.js.map +1 -1
  114. package/dist/tooltip.js.map +1 -1
  115. package/dist/useGoogleMaps.js +109 -119
  116. package/dist/useGoogleMaps.js.map +1 -1
  117. package/dist/useModals.d.ts +6 -363
  118. package/dist/useModals.js.map +1 -1
  119. package/dist/useScriptTag.js.map +1 -1
  120. package/dist/useStepper.js.map +1 -1
  121. package/dist/useValidation.js.map +1 -1
  122. package/dist/utils/colorScheme.js.map +1 -1
  123. package/dist/utils/createQueryString.js.map +1 -1
  124. package/dist/utils/formatDateTime.js.map +1 -1
  125. package/dist/utils/helpers.js.map +1 -1
  126. package/dist/utils/i18n.js.map +1 -1
  127. package/dist/utils/storage.js.map +1 -1
  128. package/dist/viewable.js.map +1 -1
  129. package/package.json +30 -46
  130. package/dist/index-79ce320f.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DataView.js","sources":["../src/components/DataView/DataView.utils.ts","../src/components/DataView/DataView.types.ts","../src/components/DataView/DataView.vue"],"sourcesContent":["import { SortId, SortOrder, SortValue, SortValueDeserialized } from './DataView.types';\n\n/**\n * Receives a SortValue (ex: `'-product_name'`) and returns an object with a `id` and an `order`.\n */\nexport function deserializeSortValue(sort: SortValue): SortValueDeserialized {\n const order = sort[0] === '-' ? 'desc' : 'asc';\n const id = order === 'asc' ? sort : sort.slice(1);\n\n return { id, order };\n}\n\n/**\n * Receives an object with a `id` and an `order` and returns a SortValue (ex: `'-product_name'`).\n */\nexport function serializeSortValue({ id, order }: SortValueDeserialized): SortValue {\n return `${order === 'desc' ? '-' : ''}${id}`;\n}\n\ninterface GetNextSortArgs {\n newId: SortId | undefined;\n newOrder?: SortOrder;\n oldId?: SortId;\n oldOrder?: SortOrder;\n}\n\n/**\n * Given new and old sorting data, it returns the next sorting value using the following sorting cycle:\n *\n * \"unsorted --> ascending --> descending --> unsorted\"\n */\nexport function getNextSort({ newId, newOrder, oldId, oldOrder }: GetNextSortArgs): SortValue | undefined {\n if (!newId) {\n return undefined;\n }\n\n if (newId !== oldId) {\n // if sorting by a new field, sort ascending\n return serializeSortValue({ id: newId, order: newOrder || 'asc' });\n }\n\n /**\n * `newOrder` and `oldOrder` can each have 3 different values: undefined, 'asc', or 'desc'.\n * Therefore, there are 9 possible combinations (3 times 3). See below:\n */\n\n // #region newOrder: undefined\n if (!newOrder && !oldOrder) {\n return newId; // ascending\n }\n\n if (!newOrder && oldOrder === 'desc') {\n return undefined; // unsorted\n }\n\n if (!newOrder && oldOrder === 'asc') {\n return `-${newId}`; // descending\n }\n // #endregion\n\n // #region newOrder: asc\n if (newOrder === 'asc' && !oldOrder) {\n return newId;\n }\n\n if (newOrder === 'asc' && oldOrder === 'asc') {\n return undefined;\n }\n\n if (newOrder === 'asc' && oldOrder === 'desc') {\n return newId;\n }\n // #endregion\n\n // #region newOrder: desc\n if (newOrder === 'desc' && !oldOrder) {\n return `-${newId}`;\n }\n\n if (newOrder === 'desc' && oldOrder === 'desc') {\n return undefined;\n }\n\n if (newOrder === 'desc' && oldOrder === 'asc') {\n return `-${newId}`;\n }\n // #endregion\n}\n","import { ComputedRef, Ref } from 'vue';\n\nimport { SpacingDensities } from '../../../types/misc';\n\nexport enum DataViewVariant {\n Table = 'table',\n}\n\nexport type DataViewVariants = `${DataViewVariant}`;\n\n/**\n * A unique id for a sorting strategy. If the order is descending, it must begin with \"-\" (a hyphen/dash).\n *\n * Ex: `'product_name'` if ascending or `'-product_name'` if descending\n */\nexport type SortValue = string;\n\n/**\n * The SortValue with its leading hyphen/dash removed\n */\nexport type SortId = string;\n\n/**\n * Determined by whether or not there is a leading hyphen/dash in the SortValue\n */\nexport type SortOrder = 'asc' | 'desc';\n\n/**\n * A deserialized instance of a `SortValue`.\n */\nexport type SortValueDeserialized = {\n id: SortId;\n order: SortOrder;\n};\n\n/** Updates the DataView internal state with the given sortId */\nexport type UpdateCurrentSort = (\n sortId: SortId | undefined,\n options?: {\n sortOrder?: SortOrder;\n /** If true, emits the `update:currentSort` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the given page */\nexport type SetPage = (\n page: number,\n options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the previous page */\nexport type GoPrevPage = (options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n}) => void;\n\n/** Updates the DataView internal state with the next page */\nexport type GoNextPage = (options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n}) => void;\n\n/** Updates the DataView internal state with the given searchTerm */\nexport type UpdateCurrentSearch = (\n searchTerm?: string,\n options?: {\n /** If true, emits the `update:currentSearch` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the given filter values */\nexport type UpdateCurrentFilters<FilterValues = object> = (\n newFilters: FilterValues,\n options?: {\n /** If true, emits the `update:currentSearch` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\nexport interface UpdateEvent<FilterValues = object> {\n page?: number;\n pageSize?: number;\n ordering?: string;\n search?: string;\n filters?: FilterValues;\n}\n\nexport interface DataViewInjection {\n currentPage: ComputedRef<number>;\n\n isPaginationEnabled: ComputedRef<boolean>;\n\n pageCount: ComputedRef<number>;\n\n pageSize: ComputedRef<number>;\n\n totalDataCount: ComputedRef<number>;\n\n /** Updates the DataView internal state with the given page */\n setPage: SetPage;\n\n /** Updates the DataView internal state with the previous page */\n goPrevPage: GoPrevPage;\n\n /** Updates the DataView internal state with the next page */\n goNextPage: GoNextPage;\n\n currentSortId: ComputedRef<SortId | undefined>;\n\n currentSortOrder: ComputedRef<SortOrder | undefined>;\n\n /** Updates the DataView internal state with the given sortId */\n updateCurrentSort: UpdateCurrentSort;\n\n currentSearch: ComputedRef<string>;\n\n /** Updates the DataView internal state with the given searchTerm */\n updateCurrentSearch: UpdateCurrentSearch;\n\n /**\n * The DataView's padding; the default value is \"comfortable\". On small screens, the density will always be \"compact\".\n */\n density: ComputedRef<SpacingDensities | undefined>;\n\n /**\n * Defines if a DataView has a Toolbar rendered. This prop is updated when DataViewToolbar exists and is mounted.\n */\n hasToolbar?: Ref<boolean>;\n\n /**\n * Enables certain loading indicators to be displayed within the DataView.\n */\n isLoading?: ComputedRef<boolean>;\n\n /**\n * Enables certain empty states to be displayed within the DataView.\n */\n isEmpty?: ComputedRef<boolean>;\n\n /**\n * Allows Table to control whether or not a DataViewToolbar should show a checkmark\n */\n isSelectable?: Ref<boolean>;\n\n /**\n * Whether or not the DataView is rendered within a Module; the value is inferred based on being\n * able to inject details from Module.\n *\n * Note: This is sent to DataView child components so they only need to worry about interfacing\n * with the DataViewInjection API.\n */\n isWithinModule: ComputedRef<boolean>;\n\n /**\n * The DataView's variant; the default value is undefined.\n */\n variant: ComputedRef<DataViewVariants | undefined>;\n}\n","<script lang=\"ts\">\n export * from './DataView.constants';\n export * from './DataView.keys';\n export * from './DataView.types';\n export * from './DataView.utils';\n</script>\n\n<script setup lang=\"ts\">\n import cloneDeep from 'lodash-es/cloneDeep';\n import { computed, inject, provide, ref, useCssModule, watch } from 'vue';\n\n import { SpacingDensities } from '../../../types/misc';\n import { MODULE_INJECTION } from '../Module/Module.keys';\n import Paginate from '../Paginate/Paginate.vue';\n import { DEFAULT_PAGE_SIZE } from './DataView.constants';\n import { DATA_VIEW_INJECTION } from './DataView.keys';\n import {\n DataViewVariants,\n GoNextPage,\n GoPrevPage,\n SetPage,\n SortId,\n SortOrder,\n SortValue,\n UpdateCurrentFilters,\n UpdateCurrentSearch,\n UpdateCurrentSort,\n UpdateEvent,\n } from './DataView.types';\n import { deserializeSortValue, getNextSort } from './DataView.utils';\n\n export interface DataViewProps {\n /**\n * Can be used to provide the initial page.\n * Also, it can be used to control the active page with `v-model:current-page=\"myPage\"`.\n */\n currentPage?: number;\n\n /**\n * Can be used to set the initial search term.\n * Also, it can be used to control the active search term with `v-model:current-search=\"mySearchTerm\"`.\n */\n currentSearch?: string;\n\n /**\n * Can be used to provide the initial sort order.\n * Also, it can be used to control the active sort order with `v-model:current-sort=\"mySortOrder\"`.\n */\n currentSort?: SortValue;\n\n /**\n * A list of records. If pagination is enabled, `data` must be only the current page of records.\n */\n data?: object[];\n\n /**\n * Controls the DataView's padding; the default value is \"comfortable\". On small screens, \"compact\" density is applied regardless of this prop's value.\n */\n density?: SpacingDensities;\n\n pageSize?: number;\n\n /**\n * Opt-out of displaying pagination. Hides the pagination buttons and page stats.\n */\n disablePagination?: boolean;\n\n /**\n * Hides the bottom pagination without disabling the pagination from the toolbar\n */\n hideBottomPagination?: boolean;\n\n /**\n * The total number of records available.\n * Used to auto-enable pagination when results exist.\n * DataView does not paginate data for you; instead, `props.data` should always show\n * the current page of results.\n */\n totalDataCount?: number;\n\n /**\n * DataView variant. The default value is `undefined`. Will default to `table` when used within\n * a `<Module variant=\"table\">`.\n */\n variant?: DataViewVariants;\n\n isLoading?: boolean;\n }\n\n const props = withDefaults(defineProps<DataViewProps>(), {\n currentPage: 1,\n currentSearch: undefined,\n currentSort: undefined,\n data: () => [],\n density: 'comfortable',\n pageSize: DEFAULT_PAGE_SIZE,\n disablePagination: false,\n totalDataCount: 0,\n hideBottomPagination: false,\n variant: undefined,\n });\n\n const emit =\n defineEmits<{\n (e: 'update', state: UpdateEvent): void;\n (e: 'update:currentFilters', newFilters: object): void;\n (e: 'update:currentPage', page: number, pageSize: number): void;\n (e: 'update:currentSearch', searchTerm?: string): void;\n (e: 'update:currentSort', payload?: SortValue): void;\n }>();\n\n const classes = useCssModule();\n const rootRef = ref<HTMLElement | null>(null);\n const moduleInjection = inject(MODULE_INJECTION.key, MODULE_INJECTION.defaults);\n const computedVariant = computed<DataViewVariants | undefined>(() => {\n if (props.variant) {\n return props.variant;\n }\n\n if (moduleInjection.variant?.value === 'table') {\n return 'table';\n }\n\n return undefined;\n });\n const isWithinModule = computed(() => moduleInjection.variant !== undefined);\n\n // #region pagination\n const internalPage = ref(1);\n const isPaginationEnabled = computed(() => !props.disablePagination && props.totalDataCount > 0);\n const pageCount = computed(() => Math.ceil(props.totalDataCount / props.pageSize));\n\n const setPage: SetPage = function (page: number, { shouldEmit } = {}) {\n internalPage.value = page;\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentPage', page, props.pageSize);\n }\n\n if (Number(rootRef.value?.getBoundingClientRect().top) < 0) {\n rootRef.value?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n };\n\n const goPrevPage: GoPrevPage = function ({ shouldEmit } = {}) {\n const page = Math.max(internalPage.value - 1, 1);\n\n setPage(page, { shouldEmit });\n };\n\n /** Updates the DataView internal state with the previous page */\n const goNextPage: GoNextPage = function ({ shouldEmit } = {}) {\n const page = Math.min(internalPage.value + 1, pageCount.value);\n\n setPage(page, { shouldEmit });\n };\n\n watch(\n () => props.currentPage,\n () => {\n setPage(props.currentPage);\n },\n { immediate: true },\n );\n // #endregion pagination\n\n // #region sorting\n const internalSort = ref<SortValue | undefined>(undefined);\n\n const internalSortId = computed<SortId | undefined>(() =>\n internalSort.value ? deserializeSortValue(internalSort.value).id : undefined,\n );\n const internalSortOrder = computed<SortOrder | undefined>(() =>\n internalSort.value ? deserializeSortValue(internalSort.value).order : undefined,\n );\n\n const updateCurrentSort: UpdateCurrentSort = function (sortId, { sortOrder, shouldEmit } = {}) {\n const { id: oldId, order: oldOrder } = deserializeSortValue(internalSort.value || '');\n const nextSort = getNextSort({ newId: sortId, newOrder: sortOrder, oldId, oldOrder });\n\n internalSort.value = nextSort;\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentSort', nextSort);\n }\n };\n\n watch(\n () => props.currentSort,\n () => {\n updateCurrentSort(props.currentSort);\n },\n { immediate: true },\n );\n // #endregion sorting\n\n // #region search\n const internalSearch = ref('');\n\n const hasToolbar = ref(false);\n const isSelectable = ref(false);\n\n const updateCurrentSearch: UpdateCurrentSearch = function (searchTerm, { shouldEmit } = {}) {\n internalSearch.value = searchTerm || '';\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentSearch', searchTerm);\n }\n };\n\n watch(\n () => props.currentSearch,\n () => {\n updateCurrentSearch(props.currentSearch);\n },\n { immediate: true },\n );\n // #endregion search\n\n // #region filters\n const internalFilters = ref<object>({});\n\n const updateCurrentFilters: UpdateCurrentFilters = function (newFilters: object, { shouldEmit } = {}) {\n internalFilters.value = newFilters;\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentFilters', newFilters);\n }\n };\n // #endregion filters\n\n function emitUpdate() {\n emit('update', {\n page: internalPage.value,\n pageSize: props.pageSize,\n ordering: internalSort.value,\n search: internalSearch.value,\n filters: cloneDeep(internalFilters.value),\n });\n }\n\n provide(\n DATA_VIEW_INJECTION.key,\n Object.freeze({\n // Pagination\n currentPage: computed(() => internalPage.value),\n isPaginationEnabled,\n pageCount,\n pageSize: computed(() => props.pageSize),\n totalDataCount: computed(() => props.totalDataCount),\n setPage,\n goPrevPage,\n goNextPage,\n\n // Sorting\n currentSortId: internalSortId,\n currentSortOrder: internalSortOrder,\n updateCurrentSort,\n\n // Search\n currentSearch: computed(() => internalSearch.value),\n updateCurrentSearch,\n\n // Miscellaneous\n density: computed(() => props.density),\n hasToolbar,\n isEmpty: computed(() => props.data.length === 0),\n isSelectable,\n isLoading: computed(() => props.isLoading),\n isWithinModule,\n variant: computedVariant,\n }),\n );\n\n defineExpose({\n page: computed(() => internalPage.value),\n pageSize: computed(() => props.pageSize),\n setPage,\n goPrevPage,\n goNextPage,\n ordering: computed(() => internalSort.value),\n updateCurrentSort,\n search: computed(() => internalSearch.value),\n updateCurrentSearch,\n filters: computed(() => internalFilters.value),\n updateCurrentFilters,\n });\n</script>\n\n<template>\n <div ref=\"rootRef\" class=\"stash-data-view tw-relative\" data-test=\"stash-data-view\">\n <!-- @slot default -->\n <slot\n :current-page=\"internalPage\"\n :current-sort-id=\"internalSortId\"\n :current-sort-order=\"internalSortOrder\"\n :data=\"data\"\n :go-prev-page=\"goPrevPage\"\n :go-next-page=\"goNextPage\"\n :page-count=\"pageCount\"\n :set-page=\"setPage\"\n :total-data-count=\"props.totalDataCount\"\n :update-current-sort=\"updateCurrentSort\"\n :update-current-search=\"updateCurrentSearch\"\n ></slot>\n\n <Paginate\n v-if=\"isPaginationEnabled && !isWithinModule && pageCount > 1 && !props.hideBottomPagination\"\n class=\"tw-mt-6\"\n :class=\"classes.paginate\"\n :current-page=\"internalPage\"\n :list-length=\"props.totalDataCount\"\n :page-size=\"props.pageSize\"\n @set-page=\"(page: number) => setPage(page, { shouldEmit: true })\"\n />\n </div>\n</template>\n\n<style module>\n .paginate ul {\n margin: 0;\n }\n</style>\n"],"names":["deserializeSortValue","sort","order","serializeSortValue","id","getNextSort","newId","newOrder","oldId","oldOrder","DataViewVariant","classes","useCssModule","rootRef","ref","moduleInjection","inject","MODULE_INJECTION","computedVariant","computed","props","_a","isWithinModule","internalPage","isPaginationEnabled","pageCount","setPage","page","shouldEmit","emitUpdate","emit","_b","goPrevPage","goNextPage","watch","internalSort","internalSortId","internalSortOrder","updateCurrentSort","sortId","sortOrder","nextSort","internalSearch","hasToolbar","isSelectable","updateCurrentSearch","searchTerm","internalFilters","updateCurrentFilters","newFilters","cloneDeep","provide","DATA_VIEW_INJECTION","__expose"],"mappings":"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"}
1
+ {"version":3,"file":"DataView.js","sources":["../src/components/DataView/DataView.utils.ts","../src/components/DataView/DataView.types.ts","../src/components/DataView/DataView.vue"],"sourcesContent":["import { SortId, SortOrder, SortValue, SortValueDeserialized } from './DataView.types';\n\n/**\n * Receives a SortValue (ex: `'-product_name'`) and returns an object with a `id` and an `order`.\n */\nexport function deserializeSortValue(sort: SortValue): SortValueDeserialized {\n const order = sort[0] === '-' ? 'desc' : 'asc';\n const id = order === 'asc' ? sort : sort.slice(1);\n\n return { id, order };\n}\n\n/**\n * Receives an object with a `id` and an `order` and returns a SortValue (ex: `'-product_name'`).\n */\nexport function serializeSortValue({ id, order }: SortValueDeserialized): SortValue {\n return `${order === 'desc' ? '-' : ''}${id}`;\n}\n\ninterface GetNextSortArgs {\n newId: SortId | undefined;\n newOrder?: SortOrder;\n oldId?: SortId;\n oldOrder?: SortOrder;\n}\n\n/**\n * Given new and old sorting data, it returns the next sorting value using the following sorting cycle:\n *\n * \"unsorted --> ascending --> descending --> unsorted\"\n */\nexport function getNextSort({ newId, newOrder, oldId, oldOrder }: GetNextSortArgs): SortValue | undefined {\n if (!newId) {\n return undefined;\n }\n\n if (newId !== oldId) {\n // if sorting by a new field, sort ascending\n return serializeSortValue({ id: newId, order: newOrder || 'asc' });\n }\n\n /**\n * `newOrder` and `oldOrder` can each have 3 different values: undefined, 'asc', or 'desc'.\n * Therefore, there are 9 possible combinations (3 times 3). See below:\n */\n\n // #region newOrder: undefined\n if (!newOrder && !oldOrder) {\n return newId; // ascending\n }\n\n if (!newOrder && oldOrder === 'desc') {\n return undefined; // unsorted\n }\n\n if (!newOrder && oldOrder === 'asc') {\n return `-${newId}`; // descending\n }\n // #endregion\n\n // #region newOrder: asc\n if (newOrder === 'asc' && !oldOrder) {\n return newId;\n }\n\n if (newOrder === 'asc' && oldOrder === 'asc') {\n return undefined;\n }\n\n if (newOrder === 'asc' && oldOrder === 'desc') {\n return newId;\n }\n // #endregion\n\n // #region newOrder: desc\n if (newOrder === 'desc' && !oldOrder) {\n return `-${newId}`;\n }\n\n if (newOrder === 'desc' && oldOrder === 'desc') {\n return undefined;\n }\n\n if (newOrder === 'desc' && oldOrder === 'asc') {\n return `-${newId}`;\n }\n // #endregion\n}\n","import { ComputedRef, Ref } from 'vue';\n\nimport { SpacingDensities } from '../../../types/misc';\n\nexport enum DataViewVariant {\n Table = 'table',\n}\n\nexport type DataViewVariants = `${DataViewVariant}`;\n\n/**\n * A unique id for a sorting strategy. If the order is descending, it must begin with \"-\" (a hyphen/dash).\n *\n * Ex: `'product_name'` if ascending or `'-product_name'` if descending\n */\nexport type SortValue = string;\n\n/**\n * The SortValue with its leading hyphen/dash removed\n */\nexport type SortId = string;\n\n/**\n * Determined by whether or not there is a leading hyphen/dash in the SortValue\n */\nexport type SortOrder = 'asc' | 'desc';\n\n/**\n * A deserialized instance of a `SortValue`.\n */\nexport type SortValueDeserialized = {\n id: SortId;\n order: SortOrder;\n};\n\n/** Updates the DataView internal state with the given sortId */\nexport type UpdateCurrentSort = (\n sortId: SortId | undefined,\n options?: {\n sortOrder?: SortOrder;\n /** If true, emits the `update:currentSort` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the given page */\nexport type SetPage = (\n page: number,\n options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the previous page */\nexport type GoPrevPage = (options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n}) => void;\n\n/** Updates the DataView internal state with the next page */\nexport type GoNextPage = (options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n}) => void;\n\n/** Updates the DataView internal state with the given searchTerm */\nexport type UpdateCurrentSearch = (\n searchTerm?: string,\n options?: {\n /** If true, emits the `update:currentSearch` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the given filter values */\nexport type UpdateCurrentFilters<FilterValues = object> = (\n newFilters: FilterValues,\n options?: {\n /** If true, emits the `update:currentSearch` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\nexport interface UpdateEvent<FilterValues = object> {\n page?: number;\n pageSize?: number;\n ordering?: string;\n search?: string;\n filters?: FilterValues;\n}\n\nexport interface DataViewInjection {\n currentPage: ComputedRef<number>;\n\n isPaginationEnabled: ComputedRef<boolean>;\n\n pageCount: ComputedRef<number>;\n\n pageSize: ComputedRef<number>;\n\n totalDataCount: ComputedRef<number>;\n\n /** Updates the DataView internal state with the given page */\n setPage: SetPage;\n\n /** Updates the DataView internal state with the previous page */\n goPrevPage: GoPrevPage;\n\n /** Updates the DataView internal state with the next page */\n goNextPage: GoNextPage;\n\n currentSortId: ComputedRef<SortId | undefined>;\n\n currentSortOrder: ComputedRef<SortOrder | undefined>;\n\n /** Updates the DataView internal state with the given sortId */\n updateCurrentSort: UpdateCurrentSort;\n\n currentSearch: ComputedRef<string>;\n\n /** Updates the DataView internal state with the given searchTerm */\n updateCurrentSearch: UpdateCurrentSearch;\n\n /**\n * The DataView's padding; the default value is \"comfortable\". On small screens, the density will always be \"compact\".\n */\n density: ComputedRef<SpacingDensities | undefined>;\n\n /**\n * Defines if a DataView has a Toolbar rendered. This prop is updated when DataViewToolbar exists and is mounted.\n */\n hasToolbar?: Ref<boolean>;\n\n /**\n * Enables certain loading indicators to be displayed within the DataView.\n */\n isLoading?: ComputedRef<boolean>;\n\n /**\n * Enables certain empty states to be displayed within the DataView.\n */\n isEmpty?: ComputedRef<boolean>;\n\n /**\n * Allows Table to control whether or not a DataViewToolbar should show a checkmark\n */\n isSelectable?: Ref<boolean>;\n\n /**\n * Whether or not the DataView is rendered within a Module; the value is inferred based on being\n * able to inject details from Module.\n *\n * Note: This is sent to DataView child components so they only need to worry about interfacing\n * with the DataViewInjection API.\n */\n isWithinModule: ComputedRef<boolean>;\n\n /**\n * The DataView's variant; the default value is undefined.\n */\n variant: ComputedRef<DataViewVariants | undefined>;\n}\n","<script lang=\"ts\">\n export * from './DataView.constants';\n export * from './DataView.keys';\n export * from './DataView.types';\n export * from './DataView.utils';\n</script>\n\n<script setup lang=\"ts\">\n import cloneDeep from 'lodash-es/cloneDeep';\n import { computed, inject, provide, ref, useCssModule, watch } from 'vue';\n\n import { SpacingDensities } from '../../../types/misc';\n import { MODULE_INJECTION } from '../Module/Module.keys';\n import Paginate from '../Paginate/Paginate.vue';\n import { DEFAULT_PAGE_SIZE } from './DataView.constants';\n import { DATA_VIEW_INJECTION } from './DataView.keys';\n import {\n DataViewVariants,\n GoNextPage,\n GoPrevPage,\n SetPage,\n SortId,\n SortOrder,\n SortValue,\n UpdateCurrentFilters,\n UpdateCurrentSearch,\n UpdateCurrentSort,\n UpdateEvent,\n } from './DataView.types';\n import { deserializeSortValue, getNextSort } from './DataView.utils';\n\n export interface DataViewProps {\n /**\n * Can be used to provide the initial page.\n * Also, it can be used to control the active page with `v-model:current-page=\"myPage\"`.\n */\n currentPage?: number;\n\n /**\n * Can be used to set the initial search term.\n * Also, it can be used to control the active search term with `v-model:current-search=\"mySearchTerm\"`.\n */\n currentSearch?: string;\n\n /**\n * Can be used to provide the initial sort order.\n * Also, it can be used to control the active sort order with `v-model:current-sort=\"mySortOrder\"`.\n */\n currentSort?: SortValue;\n\n /**\n * A list of records. If pagination is enabled, `data` must be only the current page of records.\n */\n data?: object[];\n\n /**\n * Controls the DataView's padding; the default value is \"comfortable\". On small screens, \"compact\" density is applied regardless of this prop's value.\n */\n density?: SpacingDensities;\n\n pageSize?: number;\n\n /**\n * Opt-out of displaying pagination. Hides the pagination buttons and page stats.\n */\n disablePagination?: boolean;\n\n /**\n * Hides the bottom pagination without disabling the pagination from the toolbar\n */\n hideBottomPagination?: boolean;\n\n /**\n * The total number of records available.\n * Used to auto-enable pagination when results exist.\n * DataView does not paginate data for you; instead, `props.data` should always show\n * the current page of results.\n */\n totalDataCount?: number;\n\n /**\n * DataView variant. The default value is `undefined`. Will default to `table` when used within\n * a `<Module variant=\"table\">`.\n */\n variant?: DataViewVariants;\n\n isLoading?: boolean;\n }\n\n const props = withDefaults(defineProps<DataViewProps>(), {\n currentPage: 1,\n currentSearch: undefined,\n currentSort: undefined,\n data: () => [],\n density: 'comfortable',\n pageSize: DEFAULT_PAGE_SIZE,\n disablePagination: false,\n totalDataCount: 0,\n hideBottomPagination: false,\n variant: undefined,\n });\n\n const emit =\n defineEmits<{\n (e: 'update', state: UpdateEvent): void;\n (e: 'update:currentFilters', newFilters: object): void;\n (e: 'update:currentPage', page: number, pageSize: number): void;\n (e: 'update:currentSearch', searchTerm?: string): void;\n (e: 'update:currentSort', payload?: SortValue): void;\n }>();\n\n const classes = useCssModule();\n const rootRef = ref<HTMLElement | null>(null);\n const moduleInjection = inject(MODULE_INJECTION.key, MODULE_INJECTION.defaults);\n const computedVariant = computed<DataViewVariants | undefined>(() => {\n if (props.variant) {\n return props.variant;\n }\n\n if (moduleInjection.variant?.value === 'table') {\n return 'table';\n }\n\n return undefined;\n });\n const isWithinModule = computed(() => moduleInjection.variant !== undefined);\n\n // #region pagination\n const internalPage = ref(1);\n const isPaginationEnabled = computed(() => !props.disablePagination && props.totalDataCount > 0);\n const pageCount = computed(() => Math.ceil(props.totalDataCount / props.pageSize));\n\n const setPage: SetPage = function (page: number, { shouldEmit } = {}) {\n internalPage.value = page;\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentPage', page, props.pageSize);\n }\n\n if (Number(rootRef.value?.getBoundingClientRect().top) < 0) {\n rootRef.value?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n };\n\n const goPrevPage: GoPrevPage = function ({ shouldEmit } = {}) {\n const page = Math.max(internalPage.value - 1, 1);\n\n setPage(page, { shouldEmit });\n };\n\n /** Updates the DataView internal state with the previous page */\n const goNextPage: GoNextPage = function ({ shouldEmit } = {}) {\n const page = Math.min(internalPage.value + 1, pageCount.value);\n\n setPage(page, { shouldEmit });\n };\n\n watch(\n () => props.currentPage,\n () => {\n setPage(props.currentPage);\n },\n { immediate: true },\n );\n // #endregion pagination\n\n // #region sorting\n const internalSort = ref<SortValue | undefined>(undefined);\n\n const internalSortId = computed<SortId | undefined>(() =>\n internalSort.value ? deserializeSortValue(internalSort.value).id : undefined,\n );\n const internalSortOrder = computed<SortOrder | undefined>(() =>\n internalSort.value ? deserializeSortValue(internalSort.value).order : undefined,\n );\n\n const updateCurrentSort: UpdateCurrentSort = function (sortId, { sortOrder, shouldEmit } = {}) {\n const { id: oldId, order: oldOrder } = deserializeSortValue(internalSort.value || '');\n const nextSort = getNextSort({ newId: sortId, newOrder: sortOrder, oldId, oldOrder });\n\n internalSort.value = nextSort;\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentSort', nextSort);\n }\n };\n\n watch(\n () => props.currentSort,\n () => {\n updateCurrentSort(props.currentSort);\n },\n { immediate: true },\n );\n // #endregion sorting\n\n // #region search\n const internalSearch = ref('');\n\n const hasToolbar = ref(false);\n const isSelectable = ref(false);\n\n const updateCurrentSearch: UpdateCurrentSearch = function (searchTerm, { shouldEmit } = {}) {\n internalSearch.value = searchTerm || '';\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentSearch', searchTerm);\n }\n };\n\n watch(\n () => props.currentSearch,\n () => {\n updateCurrentSearch(props.currentSearch);\n },\n { immediate: true },\n );\n // #endregion search\n\n // #region filters\n const internalFilters = ref<object>({});\n\n const updateCurrentFilters: UpdateCurrentFilters = function (newFilters: object, { shouldEmit } = {}) {\n internalFilters.value = newFilters;\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentFilters', newFilters);\n }\n };\n // #endregion filters\n\n function emitUpdate() {\n emit('update', {\n page: internalPage.value,\n pageSize: props.pageSize,\n ordering: internalSort.value,\n search: internalSearch.value,\n filters: cloneDeep(internalFilters.value),\n });\n }\n\n provide(\n DATA_VIEW_INJECTION.key,\n Object.freeze({\n // Pagination\n currentPage: computed(() => internalPage.value),\n isPaginationEnabled,\n pageCount,\n pageSize: computed(() => props.pageSize),\n totalDataCount: computed(() => props.totalDataCount),\n setPage,\n goPrevPage,\n goNextPage,\n\n // Sorting\n currentSortId: internalSortId,\n currentSortOrder: internalSortOrder,\n updateCurrentSort,\n\n // Search\n currentSearch: computed(() => internalSearch.value),\n updateCurrentSearch,\n\n // Miscellaneous\n density: computed(() => props.density),\n hasToolbar,\n isEmpty: computed(() => props.data.length === 0),\n isSelectable,\n isLoading: computed(() => props.isLoading),\n isWithinModule,\n variant: computedVariant,\n }),\n );\n\n defineExpose({\n page: computed(() => internalPage.value),\n pageSize: computed(() => props.pageSize),\n setPage,\n goPrevPage,\n goNextPage,\n ordering: computed(() => internalSort.value),\n updateCurrentSort,\n search: computed(() => internalSearch.value),\n updateCurrentSearch,\n filters: computed(() => internalFilters.value),\n updateCurrentFilters,\n });\n</script>\n\n<template>\n <div ref=\"rootRef\" class=\"stash-data-view tw-relative\" data-test=\"stash-data-view\">\n <!-- @slot default -->\n <slot\n :current-page=\"internalPage\"\n :current-sort-id=\"internalSortId\"\n :current-sort-order=\"internalSortOrder\"\n :data=\"data\"\n :go-prev-page=\"goPrevPage\"\n :go-next-page=\"goNextPage\"\n :page-count=\"pageCount\"\n :set-page=\"setPage\"\n :total-data-count=\"props.totalDataCount\"\n :update-current-sort=\"updateCurrentSort\"\n :update-current-search=\"updateCurrentSearch\"\n ></slot>\n\n <Paginate\n v-if=\"isPaginationEnabled && !isWithinModule && pageCount > 1 && !props.hideBottomPagination\"\n class=\"tw-mt-6\"\n :class=\"classes.paginate\"\n :current-page=\"internalPage\"\n :list-length=\"props.totalDataCount\"\n :page-size=\"props.pageSize\"\n @set-page=\"(page: number) => setPage(page, { shouldEmit: true })\"\n />\n </div>\n</template>\n\n<style module>\n .paginate ul {\n margin: 0;\n }\n</style>\n"],"names":["deserializeSortValue","sort","order","serializeSortValue","id","getNextSort","newId","newOrder","oldId","oldOrder","DataViewVariant","classes","useCssModule","rootRef","ref","moduleInjection","inject","MODULE_INJECTION","computedVariant","computed","props","_a","isWithinModule","internalPage","isPaginationEnabled","pageCount","setPage","page","shouldEmit","emitUpdate","emit","_b","goPrevPage","goNextPage","watch","internalSort","internalSortId","internalSortOrder","updateCurrentSort","sortId","sortOrder","nextSort","internalSearch","hasToolbar","isSelectable","updateCurrentSearch","searchTerm","internalFilters","updateCurrentFilters","newFilters","cloneDeep","provide","DATA_VIEW_INJECTION","__expose"],"mappings":"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"}
@@ -18,7 +18,7 @@ import "lodash-es/get";
18
18
  import "./Button.vue_used_vue_type_style_index_0_lang.module-a9290468.js";
19
19
  import "./_plugin-vue_export-helper-dad06003.js";
20
20
  import "lodash-es/uniqueId";
21
- import "./index-79ce320f.js";
21
+ import "./index-9e1095ef.js";
22
22
  import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
23
23
  import "./Chip.js";
24
24
  import "./utils/colorScheme.js";
@@ -1 +1 @@
1
- {"version":3,"file":"DataViewFilters.js","sources":["../src/components/DataViewFilters/useFilters.ts","../src/components/DataViewFilters/DataViewFilters.vue"],"sourcesContent":["import cloneDeep from 'lodash-es/cloneDeep';\nimport { computed, ComputedRef, Ref, ref } from 'vue';\n\nimport isDefined from '../../composables/useValidation/utils/isDefined';\nimport DataView from '../DataView/DataView.vue';\n\ntype DataViewInstance = InstanceType<typeof DataView>;\n\n/**\n * Contains metadata and configuration for the filters.\n * @see https://www.typescriptlang.org/docs/handbook/2/mapped-types.html\n */\nexport type UseFiltersSchema<Values extends object, Groups extends string> = {\n [Property in keyof Values]: {\n defaultValue?: Values[Property];\n group?: Groups;\n isActive?: (value: Values[Property]) => boolean;\n };\n};\n\nexport interface UseFiltersArgs<Values extends object, Groups extends string> {\n schema: UseFiltersSchema<Values, Groups>;\n /** A ref for an instance of DataView */\n dataViewRef: Ref<unknown>; // Note: using `Ref<InstanceType<typeof DataView>>` here causes type errors when providing a value for this argument\n}\n\nexport interface UseFiltersReturnType<Values = object, Groups extends string = string> {\n applyFilters: () => void;\n resetAllFilters: () => void;\n resetFilterGroup: (group: string) => void; // Note: group is intentionally not typed as `Groups` since there is no way to pass in a Groups type to UseFiltersReturnType within DataViewFilters.vue\n undoWorkingFilters: () => void;\n activeFiltersCounts: ComputedRef<Record<Groups, number>>;\n totalActiveFiltersCount: ComputedRef<number>;\n appliedFilters: Ref<Values>;\n workingFilters: Ref<Values>;\n}\n\n/**\n * Provides utility functions for working with `DataViewFilters`.\n */\nexport function useFilters<Values extends object, Groups extends string>({\n schema,\n dataViewRef,\n}: UseFiltersArgs<Values, Groups>): UseFiltersReturnType<Values, Groups> {\n const appliedFilters = ref({}) as Ref<Values>;\n const workingFilters = ref({}) as Ref<Values>;\n\n for (const filterName in schema) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n\n const dvRef = dataViewRef as Ref<DataViewInstance>;\n\n /**\n * For when an \"Apply\" button is clicked. It does the following:\n * 1) applies the working filter state\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function applyFilters() {\n appliedFilters.value = cloneDeep(workingFilters.value);\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * For when a \"Reset all\" button is clicked. It does the following:\n * 1) applies the defaultValue filter values to all filters\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function resetAllFilters() {\n for (const filterName in schema) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * For when a \"Reset\" button is clicked. It does the following:\n * 1) applies the defaultValue filter values to the given filter group\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function resetFilterGroup(group: Groups) {\n for (const filterName in schema) {\n if (schema[filterName].group === group) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n }\n\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * Resets the `workingFilters` to match the `appliedFilters`. This can be used when the FilterDrawer or a FilterDropdown is dismissed without clicking \"Reset\" or \"Apply\".\n */\n function undoWorkingFilters() {\n workingFilters.value = cloneDeep(appliedFilters.value);\n }\n\n const activeFiltersCounts = computed(() => {\n const counts = {} as Record<Groups, number>;\n\n for (const filterName in schema) {\n const config = schema[filterName];\n const value = appliedFilters.value[filterName];\n const isActive = config.isActive?.(value) || isDefined(value);\n\n if (isActive && config.group) {\n counts[config.group] = (counts[config.group] ?? 0) + 1;\n }\n }\n\n return counts;\n });\n\n const totalActiveFiltersCount = computed(() => {\n let count = 0;\n\n for (const filterName in schema) {\n const config = schema[filterName];\n const value = appliedFilters.value[filterName];\n const isActive = config.isActive?.(value) || isDefined(value);\n\n if (isActive) {\n count += 1;\n }\n }\n\n return count;\n });\n\n return {\n applyFilters,\n resetAllFilters,\n // @ts-expect-error \"could be instantiated with a different subtype\": TODO: figure out how to resolve the types\n resetFilterGroup,\n undoWorkingFilters,\n activeFiltersCounts,\n totalActiveFiltersCount,\n appliedFilters,\n workingFilters,\n };\n}\n\nexport default useFilters;\n","<script lang=\"ts\">\n export * from './DataViewFilters.keys';\n export * from './DataViewFilters.types';\n export * from './useFilters';\n</script>\n\n<script setup lang=\"ts\">\n import { computed, inject, provide, ref, watch } from 'vue';\n\n import useMediaQuery from '../../composables/useMediaQuery/useMediaQuery';\n import { SCREEN_SIZES } from '../../constants';\n import { t } from '../../locale';\n import Box from '../Box/Box.vue';\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n import Icon from '../Icon/Icon.vue';\n import Label from '../Label/Label.vue';\n import Modal, { type ModalProps } from '../Modal/Modal.vue';\n import SearchBar, { SearchBarProps } from '../SearchBar/SearchBar.vue';\n import { DATA_VIEW_FILTERS_UTILS_INJECTION } from './DataViewFilters.keys';\n import type { DrawerStyle, OnApplyFilters } from './DataViewFilters.types';\n import type { UseFiltersReturnType } from './useFilters';\n\n export interface DataViewFiltersProps {\n filtersLabelText?: string;\n /**\n * Props to pass to the `SearchBar` component.\n */\n searchBarProps?: SearchBarProps;\n showSearch?: boolean;\n /** 'cascade' displays all fields within every filter group; 'nested' displays only the group names and requires clicking a group to view its fields */\n drawerStyle?: DrawerStyle;\n drawerProps?: ModalProps;\n showDrawerPreviousButton?: boolean;\n /**\n * Required when using filters. This prop should contain the return value of the `useFilters()` composable.\n */\n useFiltersInstance?: UseFiltersReturnType;\n onApply?: OnApplyFilters;\n /** The name of the active filter group. The active filter group is determined by which instance of FilterDropdown or FilterDrawerItem is open. */\n activeGroup?: string;\n }\n\n export interface DataViewFiltersSlots {\n default?: void;\n drawer?: void;\n 'filters-label'?: void;\n }\n\n const props = withDefaults(defineProps<DataViewFiltersProps>(), {\n filtersLabelText: t('ll.filterBy'),\n isLoading: false,\n drawerStyle: 'nested',\n drawerProps: undefined,\n searchBarProps: undefined,\n showDrawerPreviousButton: false,\n showSearch: true,\n useFiltersInstance: undefined,\n onApply: undefined,\n activeGroup: '',\n });\n\n const emit =\n defineEmits<{\n /** When the drawer is opened */\n (e: 'open-drawer'): void;\n /** When the drawer is dismissed */\n (e: 'dismiss'): void;\n /** When the \"Previous\" button in the header is clicked */\n (e: 'previous'): void;\n /** When the \"Reset\" button is clicked while viewing a filter group */\n (e: 'reset-group'): void;\n /** When one of the \"Reset All\" buttons is clicked */\n (e: 'reset-all'): void;\n }>();\n\n const slots = defineSlots<DataViewFiltersSlots>();\n\n const isDesktop = useMediaQuery(`(min-width: ${SCREEN_SIZES.lg})`);\n\n const {\n density,\n isLoading: isDataViewLoading,\n isWithinModule,\n currentSearch,\n updateCurrentSearch,\n } = inject(DATA_VIEW_INJECTION.key, DATA_VIEW_INJECTION.defaults);\n\n provide(DATA_VIEW_FILTERS_UTILS_INJECTION.key, { useFiltersInstance: props.useFiltersInstance, drawerStyle: props.drawerStyle});\n\n const totalActiveFiltersCount = computed(() => props.useFiltersInstance?.totalActiveFiltersCount.value ?? 0);\n const activeGroupActiveFiltersCount = computed(\n () => props.useFiltersInstance?.activeFiltersCounts.value[props.activeGroup] ?? 0,\n );\n const isDrawerOpen = ref(false);\n\n async function handleApplyClick() {\n const { preventDismiss } = (await props.onApply?.()) || props.useFiltersInstance?.applyFilters() || {};\n\n if (!preventDismiss) {\n isDrawerOpen.value = false;\n }\n }\n\n function handleResetGroupClick() {\n props.useFiltersInstance?.resetFilterGroup(props.activeGroup);\n emit('reset-group');\n isDrawerOpen.value = false;\n }\n\n function handleResetAllClick() {\n props.useFiltersInstance?.resetAllFilters();\n emit('reset-all');\n isDrawerOpen.value = false;\n }\n\n function onDismiss() {\n props.useFiltersInstance?.undoWorkingFilters();\n isDrawerOpen.value = false;\n emit('dismiss');\n }\n\n watch(isDrawerOpen, () => {\n if (isDrawerOpen.value) {\n emit('open-drawer');\n }\n });\n</script>\n\n<template>\n <Box\n class=\"stash-data-view-filters tw-grid tw-grid-cols-12 tw-gap-6 tw-p-3\"\n :class=\"{ 'lg:tw-p-6': density === 'comfortable', 'tw-mb-3': !isWithinModule }\"\n :radius=\"isWithinModule ? 'none' : 'rounded'\"\n data-test=\"stash-data-view-filters\"\n disable-padding\n >\n <SearchBar\n v-if=\"props.showSearch\"\n class=\"tw-col-span-12 md:tw-col-span-6 lg:tw-col-span-4\"\n data-test=\"stash-data-view-filters|search-bar\"\n :is-loading=\"isDataViewLoading\"\n :label=\"t('ll.search')\"\n :model-value=\"currentSearch\"\n v-bind=\"props.searchBarProps\"\n @search=\"(searchTerm) => updateCurrentSearch(searchTerm, { shouldEmit: true })\"\n />\n <div\n v-if=\"slots.default\"\n class=\"tw-col-span-12 tw-row-start-2 md:tw-col-start-7 md:tw-row-start-1 lg:tw-col-span-8 lg:tw-col-start-5\"\n >\n <div class=\"tw-hidden md:tw-block\">\n <slot name=\"filters-label\">\n <Label>{{ props.filtersLabelText }}</Label>\n </slot>\n </div>\n <div class=\"tw-flex tw-gap-4\">\n <FilterChip\n secondary\n class=\"!tw-flex tw-w-full tw-justify-center tw-gap-4 md:!tw-inline-flex md:tw-w-auto\"\n data-test=\"stash-data-view-filters|drawer-toggle-button\"\n :filter-count=\"totalActiveFiltersCount\"\n @click=\"isDrawerOpen = true\"\n >\n <span class=\"tw-inline-flex tw-items-center tw-gap-3\">\n <Icon name=\"filter-line\" class=\"tw-text-ice-700\" />\n <span>{{ t('ll.filters') }}</span>\n </span>\n </FilterChip>\n <slot v-if=\"isDesktop\"></slot>\n <Button v-if=\"totalActiveFiltersCount > 0 && isDesktop\" inline @click=\"handleResetAllClick\">\n {{ t('ll.resetAll') }}\n </Button>\n </div>\n </div>\n <Modal\n v-if=\"slots.drawer\"\n data-test=\"stash-data-view-filters|drawer\"\n disable-body-padding\n position=\"right\"\n :is-open=\"isDrawerOpen\"\n :title=\"t('ll.allFilters')\"\n v-bind=\"props.drawerProps\"\n @dismiss=\"onDismiss\"\n >\n <template #headerAction>\n <Button\n v-if=\"props.showDrawerPreviousButton\"\n icon\n class=\"tw-text-ice-100\"\n data-test=\"stash-data-view-filters|drawer-previous-button\"\n :aria-label=\"t('ll.previous')\"\n :title=\"t('ll.previous')\"\n @click=\"emit('previous')\"\n >\n <Icon name=\"chevron-left\" />\n </Button>\n </template>\n\n <slot name=\"drawer\"></slot>\n\n <template #footer>\n <div class=\"tw-flex tw-flex-col-reverse tw-gap-gutter lg:tw-flex-row lg:tw-justify-end\">\n <Button\n v-if=\"!props.showDrawerPreviousButton && totalActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetAllClick\"\n >\n {{ t('ll.resetAll') }}\n </Button>\n <Button\n v-if=\"\n (props.showDrawerPreviousButton || props.drawerStyle === 'cascade') && activeGroupActiveFiltersCount > 0\n \"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetGroupClick\"\n >\n {{ t('ll.reset') }}\n </Button>\n <Button\n v-if=\"props.showDrawerPreviousButton || props.drawerStyle === 'cascade'\"\n :disabled=\"isDataViewLoading\"\n @click=\"handleApplyClick\"\n >\n {{ t('ll.apply') }}\n </Button>\n </div>\n </template>\n </Modal>\n </Box>\n</template>\n"],"names":["useFilters","schema","dataViewRef","appliedFilters","ref","workingFilters","filterName","dvRef","applyFilters","cloneDeep","resetAllFilters","resetFilterGroup","group","undoWorkingFilters","activeFiltersCounts","computed","counts","config","value","_a","isDefined","totalActiveFiltersCount","count","slots","_useSlots","isDesktop","useMediaQuery","SCREEN_SIZES","density","isDataViewLoading","isWithinModule","currentSearch","updateCurrentSearch","inject","DATA_VIEW_INJECTION","provide","DATA_VIEW_FILTERS_UTILS_INJECTION","props","activeGroupActiveFiltersCount","isDrawerOpen","handleApplyClick","preventDismiss","_b","handleResetGroupClick","emit","handleResetAllClick","onDismiss","watch"],"mappings":"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"}
1
+ {"version":3,"file":"DataViewFilters.js","sources":["../src/components/DataViewFilters/useFilters.ts","../src/components/DataViewFilters/DataViewFilters.vue"],"sourcesContent":["import cloneDeep from 'lodash-es/cloneDeep';\nimport { computed, ComputedRef, Ref, ref } from 'vue';\n\nimport isDefined from '../../composables/useValidation/utils/isDefined';\nimport DataView from '../DataView/DataView.vue';\n\ntype DataViewInstance = InstanceType<typeof DataView>;\n\n/**\n * Contains metadata and configuration for the filters.\n * @see https://www.typescriptlang.org/docs/handbook/2/mapped-types.html\n */\nexport type UseFiltersSchema<Values extends object, Groups extends string> = {\n [Property in keyof Values]: {\n defaultValue?: Values[Property];\n group?: Groups;\n isActive?: (value: Values[Property]) => boolean;\n };\n};\n\nexport interface UseFiltersArgs<Values extends object, Groups extends string> {\n schema: UseFiltersSchema<Values, Groups>;\n /** A ref for an instance of DataView */\n dataViewRef: Ref<unknown>; // Note: using `Ref<InstanceType<typeof DataView>>` here causes type errors when providing a value for this argument\n}\n\nexport interface UseFiltersReturnType<Values = object, Groups extends string = string> {\n applyFilters: () => void;\n resetAllFilters: () => void;\n resetFilterGroup: (group: string) => void; // Note: group is intentionally not typed as `Groups` since there is no way to pass in a Groups type to UseFiltersReturnType within DataViewFilters.vue\n undoWorkingFilters: () => void;\n activeFiltersCounts: ComputedRef<Record<Groups, number>>;\n totalActiveFiltersCount: ComputedRef<number>;\n appliedFilters: Ref<Values>;\n workingFilters: Ref<Values>;\n}\n\n/**\n * Provides utility functions for working with `DataViewFilters`.\n */\nexport function useFilters<Values extends object, Groups extends string>({\n schema,\n dataViewRef,\n}: UseFiltersArgs<Values, Groups>): UseFiltersReturnType<Values, Groups> {\n const appliedFilters = ref({}) as Ref<Values>;\n const workingFilters = ref({}) as Ref<Values>;\n\n for (const filterName in schema) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n\n const dvRef = dataViewRef as Ref<DataViewInstance>;\n\n /**\n * For when an \"Apply\" button is clicked. It does the following:\n * 1) applies the working filter state\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function applyFilters() {\n appliedFilters.value = cloneDeep(workingFilters.value);\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * For when a \"Reset all\" button is clicked. It does the following:\n * 1) applies the defaultValue filter values to all filters\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function resetAllFilters() {\n for (const filterName in schema) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * For when a \"Reset\" button is clicked. It does the following:\n * 1) applies the defaultValue filter values to the given filter group\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function resetFilterGroup(group: Groups) {\n for (const filterName in schema) {\n if (schema[filterName].group === group) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n }\n\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * Resets the `workingFilters` to match the `appliedFilters`. This can be used when the FilterDrawer or a FilterDropdown is dismissed without clicking \"Reset\" or \"Apply\".\n */\n function undoWorkingFilters() {\n workingFilters.value = cloneDeep(appliedFilters.value);\n }\n\n const activeFiltersCounts = computed(() => {\n const counts = {} as Record<Groups, number>;\n\n for (const filterName in schema) {\n const config = schema[filterName];\n const value = appliedFilters.value[filterName];\n const isActive = config.isActive?.(value) || isDefined(value);\n\n if (isActive && config.group) {\n counts[config.group] = (counts[config.group] ?? 0) + 1;\n }\n }\n\n return counts;\n });\n\n const totalActiveFiltersCount = computed(() => {\n let count = 0;\n\n for (const filterName in schema) {\n const config = schema[filterName];\n const value = appliedFilters.value[filterName];\n const isActive = config.isActive?.(value) || isDefined(value);\n\n if (isActive) {\n count += 1;\n }\n }\n\n return count;\n });\n\n return {\n applyFilters,\n resetAllFilters,\n // @ts-expect-error \"could be instantiated with a different subtype\": TODO: figure out how to resolve the types\n resetFilterGroup,\n undoWorkingFilters,\n activeFiltersCounts,\n totalActiveFiltersCount,\n appliedFilters,\n workingFilters,\n };\n}\n\nexport default useFilters;\n","<script lang=\"ts\">\n export * from './DataViewFilters.keys';\n export * from './DataViewFilters.types';\n export * from './useFilters';\n</script>\n\n<script setup lang=\"ts\">\n import { computed, inject, provide, ref, watch } from 'vue';\n\n import useMediaQuery from '../../composables/useMediaQuery/useMediaQuery';\n import { SCREEN_SIZES } from '../../constants';\n import { t } from '../../locale';\n import Box from '../Box/Box.vue';\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n import Icon from '../Icon/Icon.vue';\n import Label from '../Label/Label.vue';\n import Modal, { type ModalProps } from '../Modal/Modal.vue';\n import SearchBar, { SearchBarProps } from '../SearchBar/SearchBar.vue';\n import { DATA_VIEW_FILTERS_UTILS_INJECTION } from './DataViewFilters.keys';\n import type { DrawerStyle, OnApplyFilters } from './DataViewFilters.types';\n import type { UseFiltersReturnType } from './useFilters';\n\n export interface DataViewFiltersProps {\n filtersLabelText?: string;\n /**\n * Props to pass to the `SearchBar` component.\n */\n searchBarProps?: SearchBarProps;\n showSearch?: boolean;\n /** 'cascade' displays all fields within every filter group; 'nested' displays only the group names and requires clicking a group to view its fields */\n drawerStyle?: DrawerStyle;\n drawerProps?: ModalProps;\n showDrawerPreviousButton?: boolean;\n /**\n * Required when using filters. This prop should contain the return value of the `useFilters()` composable.\n */\n useFiltersInstance?: UseFiltersReturnType;\n onApply?: OnApplyFilters;\n /** The name of the active filter group. The active filter group is determined by which instance of FilterDropdown or FilterDrawerItem is open. */\n activeGroup?: string;\n }\n\n export interface DataViewFiltersSlots {\n default?: void;\n drawer?: void;\n 'filters-label'?: void;\n }\n\n const props = withDefaults(defineProps<DataViewFiltersProps>(), {\n filtersLabelText: t('ll.filterBy'),\n isLoading: false,\n drawerStyle: 'nested',\n drawerProps: undefined,\n searchBarProps: undefined,\n showDrawerPreviousButton: false,\n showSearch: true,\n useFiltersInstance: undefined,\n onApply: undefined,\n activeGroup: '',\n });\n\n const emit =\n defineEmits<{\n /** When the drawer is opened */\n (e: 'open-drawer'): void;\n /** When the drawer is dismissed */\n (e: 'dismiss'): void;\n /** When the \"Previous\" button in the header is clicked */\n (e: 'previous'): void;\n /** When the \"Reset\" button is clicked while viewing a filter group */\n (e: 'reset-group'): void;\n /** When one of the \"Reset All\" buttons is clicked */\n (e: 'reset-all'): void;\n }>();\n\n const slots = defineSlots<DataViewFiltersSlots>();\n\n const isDesktop = useMediaQuery(`(min-width: ${SCREEN_SIZES.lg})`);\n\n const {\n density,\n isLoading: isDataViewLoading,\n isWithinModule,\n currentSearch,\n updateCurrentSearch,\n } = inject(DATA_VIEW_INJECTION.key, DATA_VIEW_INJECTION.defaults);\n\n provide(DATA_VIEW_FILTERS_UTILS_INJECTION.key, { useFiltersInstance: props.useFiltersInstance, drawerStyle: props.drawerStyle});\n\n const totalActiveFiltersCount = computed(() => props.useFiltersInstance?.totalActiveFiltersCount.value ?? 0);\n const activeGroupActiveFiltersCount = computed(\n () => props.useFiltersInstance?.activeFiltersCounts.value[props.activeGroup] ?? 0,\n );\n const isDrawerOpen = ref(false);\n\n async function handleApplyClick() {\n const { preventDismiss } = (await props.onApply?.()) || props.useFiltersInstance?.applyFilters() || {};\n\n if (!preventDismiss) {\n isDrawerOpen.value = false;\n }\n }\n\n function handleResetGroupClick() {\n props.useFiltersInstance?.resetFilterGroup(props.activeGroup);\n emit('reset-group');\n isDrawerOpen.value = false;\n }\n\n function handleResetAllClick() {\n props.useFiltersInstance?.resetAllFilters();\n emit('reset-all');\n isDrawerOpen.value = false;\n }\n\n function onDismiss() {\n props.useFiltersInstance?.undoWorkingFilters();\n isDrawerOpen.value = false;\n emit('dismiss');\n }\n\n watch(isDrawerOpen, () => {\n if (isDrawerOpen.value) {\n emit('open-drawer');\n }\n });\n</script>\n\n<template>\n <Box\n class=\"stash-data-view-filters tw-grid tw-grid-cols-12 tw-gap-6 tw-p-3\"\n :class=\"{ 'lg:tw-p-6': density === 'comfortable', 'tw-mb-3': !isWithinModule }\"\n :radius=\"isWithinModule ? 'none' : 'rounded'\"\n data-test=\"stash-data-view-filters\"\n disable-padding\n >\n <SearchBar\n v-if=\"props.showSearch\"\n class=\"tw-col-span-12 md:tw-col-span-6 lg:tw-col-span-4\"\n data-test=\"stash-data-view-filters|search-bar\"\n :is-loading=\"isDataViewLoading\"\n :label=\"t('ll.search')\"\n :model-value=\"currentSearch\"\n v-bind=\"props.searchBarProps\"\n @search=\"(searchTerm) => updateCurrentSearch(searchTerm, { shouldEmit: true })\"\n />\n <div\n v-if=\"slots.default\"\n class=\"tw-col-span-12 tw-row-start-2 md:tw-col-start-7 md:tw-row-start-1 lg:tw-col-span-8 lg:tw-col-start-5\"\n >\n <div class=\"tw-hidden md:tw-block\">\n <slot name=\"filters-label\">\n <Label>{{ props.filtersLabelText }}</Label>\n </slot>\n </div>\n <div class=\"tw-flex tw-gap-4\">\n <FilterChip\n secondary\n class=\"!tw-flex tw-w-full tw-justify-center tw-gap-4 md:!tw-inline-flex md:tw-w-auto\"\n data-test=\"stash-data-view-filters|drawer-toggle-button\"\n :filter-count=\"totalActiveFiltersCount\"\n @click=\"isDrawerOpen = true\"\n >\n <span class=\"tw-inline-flex tw-items-center tw-gap-3\">\n <Icon name=\"filter-line\" class=\"tw-text-ice-700\" />\n <span>{{ t('ll.filters') }}</span>\n </span>\n </FilterChip>\n <slot v-if=\"isDesktop\"></slot>\n <Button v-if=\"totalActiveFiltersCount > 0 && isDesktop\" inline @click=\"handleResetAllClick\">\n {{ t('ll.resetAll') }}\n </Button>\n </div>\n </div>\n <Modal\n v-if=\"slots.drawer\"\n data-test=\"stash-data-view-filters|drawer\"\n disable-body-padding\n position=\"right\"\n :is-open=\"isDrawerOpen\"\n :title=\"t('ll.allFilters')\"\n v-bind=\"props.drawerProps\"\n @dismiss=\"onDismiss\"\n >\n <template #headerAction>\n <Button\n v-if=\"props.showDrawerPreviousButton\"\n icon\n class=\"tw-text-ice-100\"\n data-test=\"stash-data-view-filters|drawer-previous-button\"\n :aria-label=\"t('ll.previous')\"\n :title=\"t('ll.previous')\"\n @click=\"emit('previous')\"\n >\n <Icon name=\"chevron-left\" />\n </Button>\n </template>\n\n <slot name=\"drawer\"></slot>\n\n <template #footer>\n <div class=\"tw-flex tw-flex-col-reverse tw-gap-gutter lg:tw-flex-row lg:tw-justify-end\">\n <Button\n v-if=\"!props.showDrawerPreviousButton && totalActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetAllClick\"\n >\n {{ t('ll.resetAll') }}\n </Button>\n <Button\n v-if=\"\n (props.showDrawerPreviousButton || props.drawerStyle === 'cascade') && activeGroupActiveFiltersCount > 0\n \"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetGroupClick\"\n >\n {{ t('ll.reset') }}\n </Button>\n <Button\n v-if=\"props.showDrawerPreviousButton || props.drawerStyle === 'cascade'\"\n :disabled=\"isDataViewLoading\"\n @click=\"handleApplyClick\"\n >\n {{ t('ll.apply') }}\n </Button>\n </div>\n </template>\n </Modal>\n </Box>\n</template>\n"],"names":["useFilters","schema","dataViewRef","appliedFilters","ref","workingFilters","filterName","dvRef","applyFilters","cloneDeep","resetAllFilters","resetFilterGroup","group","undoWorkingFilters","activeFiltersCounts","computed","counts","config","value","_a","isDefined","totalActiveFiltersCount","count","slots","_useSlots","isDesktop","useMediaQuery","SCREEN_SIZES","density","isDataViewLoading","isWithinModule","currentSearch","updateCurrentSearch","inject","DATA_VIEW_INJECTION","provide","DATA_VIEW_FILTERS_UTILS_INJECTION","props","activeGroupActiveFiltersCount","isDrawerOpen","handleApplyClick","preventDismiss","_b","handleResetGroupClick","emit","handleResetAllClick","onDismiss","watch"],"mappings":"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"}
@@ -11,7 +11,7 @@ import { _ as N } from "./_plugin-vue_export-helper-dad06003.js";
11
11
  import "lodash-es/get";
12
12
  import "./Button.vue_used_vue_type_style_index_0_lang.module-a9290468.js";
13
13
  import "lodash-es/uniqueId";
14
- import "./index-79ce320f.js";
14
+ import "./index-9e1095ef.js";
15
15
  import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
16
16
  import "./constants.js";
17
17
  import "./clickoutside.js";
@@ -12,7 +12,7 @@ import "./_plugin-vue_export-helper-dad06003.js";
12
12
  import "@leaflink/snitch";
13
13
  import "lodash-es/uniqueId";
14
14
  import "./Checkbox.vue_used_vue_type_style_index_0_lang.module-fa8d9c06.js";
15
- import "./index-79ce320f.js";
15
+ import "./index-9e1095ef.js";
16
16
  import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
17
17
  const O = { class: "tw-flex tw-place-items-center" }, q = { class: "tw-flex tw-items-center tw-gap-x-2 lg:tw-gap-x-6" }, G = {
18
18
  key: 0,