// Composables import { useProxiedModel } from "../../../composables/proxiedModel.mjs"; // Utilities import { computed, inject, provide, ref } from 'vue'; import { getObjectValueByPath, propsFactory } from "../../../util/index.mjs"; // Types export const makeDataTableGroupProps = propsFactory({ groupBy: { type: Array, default: () => [] } }, 'DataTable-group'); const VDataTableGroupSymbol = Symbol.for('vuetify:data-table-group'); export function createGroupBy(props) { const groupBy = useProxiedModel(props, 'groupBy'); return { groupBy }; } export function provideGroupBy(options) { const { groupBy, sortBy } = options; const opened = ref(new Set()); const sortByWithGroups = computed(() => { return groupBy.value.map(val => ({ ...val, order: val.order ?? false })).concat(sortBy.value); }); function isGroupOpen(group) { return opened.value.has(group.id); } function toggleGroup(group) { const newOpened = new Set(opened.value); if (!isGroupOpen(group)) newOpened.add(group.id);else newOpened.delete(group.id); opened.value = newOpened; } function extractRows(items) { function dive(group) { const arr = []; for (const item of group.items) { if ('type' in item && item.type === 'group') { arr.push(...dive(item)); } else { arr.push(item); } } return arr; } return dive({ type: 'group', items, id: 'dummy', key: 'dummy', value: 'dummy', depth: 0 }); } // onBeforeMount(() => { // for (const key of groupedItems.value.keys()) { // opened.value.add(key) // } // }) const data = { sortByWithGroups, toggleGroup, opened, groupBy, extractRows, isGroupOpen }; provide(VDataTableGroupSymbol, data); return data; } export function useGroupBy() { const data = inject(VDataTableGroupSymbol); if (!data) throw new Error('Missing group!'); return data; } function groupItemsByProperty(items, groupBy) { if (!items.length) return []; const groups = new Map(); for (const item of items) { const value = getObjectValueByPath(item.raw, groupBy); if (!groups.has(value)) { groups.set(value, []); } groups.get(value).push(item); } return groups; } function groupItems(items, groupBy) { let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; let prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'root'; if (!groupBy.length) return []; const groupedItems = groupItemsByProperty(items, groupBy[0]); const groups = []; const rest = groupBy.slice(1); groupedItems.forEach((items, value) => { const key = groupBy[0]; const id = `${prefix}_${key}_${value}`; groups.push({ depth, id, key, value, items: rest.length ? groupItems(items, rest, depth + 1, id) : items, type: 'group' }); }); return groups; } function flattenItems(items, opened) { const flatItems = []; for (const item of items) { // TODO: make this better if ('type' in item && item.type === 'group') { if (item.value != null) { flatItems.push(item); } if (opened.has(item.id) || item.value == null) { flatItems.push(...flattenItems(item.items, opened)); } } else { flatItems.push(item); } } return flatItems; } export function useGroupedItems(items, groupBy, opened) { const flatItems = computed(() => { if (!groupBy.value.length) return items.value; const groupedItems = groupItems(items.value, groupBy.value.map(item => item.key)); return flattenItems(groupedItems, opened.value); }); return { flatItems }; } //# sourceMappingURL=group.mjs.map