Vulture/VApp/node_modules/vuetify/lib/components/VDataTable/composables/headers.mjs

265 lines
7.6 KiB
JavaScript
Raw Normal View History

// Utilities
import { capitalize, inject, provide, ref, watchEffect } from 'vue';
import { consoleError, propsFactory } from "../../../util/index.mjs"; // Types
export const makeDataTableHeaderProps = propsFactory({
headers: Array
}, 'DataTable-header');
export const VDataTableHeadersSymbol = Symbol.for('vuetify:data-table-headers');
const defaultHeader = {
title: '',
sortable: false
};
const defaultActionHeader = {
...defaultHeader,
width: 48
};
function priorityQueue() {
let arr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
const queue = arr.map(element => ({
element,
priority: 0
}));
return {
enqueue: (element, priority) => {
let added = false;
for (let i = 0; i < queue.length; i++) {
const item = queue[i];
if (item.priority > priority) {
queue.splice(i, 0, {
element,
priority
});
added = true;
break;
}
}
if (!added) queue.push({
element,
priority
});
},
size: () => queue.length,
count: () => {
let count = 0;
if (!queue.length) return 0;
const whole = Math.floor(queue[0].priority);
for (let i = 0; i < queue.length; i++) {
if (Math.floor(queue[i].priority) === whole) count += 1;
}
return count;
},
dequeue: () => {
return queue.shift();
}
};
}
function extractLeaves(item) {
let columns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (!item.children) {
columns.push(item);
} else {
for (const child of item.children) {
extractLeaves(child, columns);
}
}
return columns;
}
function extractKeys(headers) {
let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
for (const item of headers) {
if (item.key) keys.add(item.key);
if (item.children) {
extractKeys(item.children, keys);
}
}
return keys;
}
function getDefaultItem(item) {
if (!item.key) return undefined;
if (item.key === 'data-table-group') return defaultHeader;
if (['data-table-expand', 'data-table-select'].includes(item.key)) return defaultActionHeader;
return undefined;
}
function getDepth(item) {
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (!item.children) return depth;
return Math.max(depth, ...item.children.map(child => getDepth(child, depth + 1)));
}
function parseFixedColumns(items) {
let seenFixed = false;
function setFixed(item) {
let parentFixed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (!item) return;
if (parentFixed) {
item.fixed = true;
}
if (item.fixed) {
if (item.children) {
for (let i = item.children.length - 1; i >= 0; i--) {
setFixed(item.children[i], true);
}
} else {
if (!seenFixed) {
item.lastFixed = true;
} else if (isNaN(+item.width)) {
consoleError(`Multiple fixed columns should have a static width (key: ${item.key})`);
}
seenFixed = true;
}
} else {
if (item.children) {
for (let i = item.children.length - 1; i >= 0; i--) {
setFixed(item.children[i]);
}
} else {
seenFixed = false;
}
}
}
for (let i = items.length - 1; i >= 0; i--) {
setFixed(items[i]);
}
function setFixedOffset(item) {
let fixedOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (!item) return fixedOffset;
if (item.children) {
item.fixedOffset = fixedOffset;
for (const child of item.children) {
fixedOffset = setFixedOffset(child, fixedOffset);
}
} else if (item.fixed) {
item.fixedOffset = fixedOffset;
fixedOffset += parseFloat(item.width || '0') || 0;
}
return fixedOffset;
}
let fixedOffset = 0;
for (const item of items) {
fixedOffset = setFixedOffset(item, fixedOffset);
}
}
function parse(items, maxDepth) {
const headers = [];
let currentDepth = 0;
const queue = priorityQueue(items);
while (queue.size() > 0) {
let rowSize = queue.count();
const row = [];
let fraction = 1;
while (rowSize > 0) {
const {
element: item,
priority
} = queue.dequeue();
const diff = maxDepth - currentDepth - getDepth(item);
row.push({
...item,
rowspan: diff ?? 1,
colspan: item.children ? extractLeaves(item).length : 1
});
if (item.children) {
for (const child of item.children) {
// This internally sorts items that are on the same priority "row"
const sort = priority % 1 + fraction / Math.pow(10, currentDepth + 2);
queue.enqueue(child, currentDepth + diff + sort);
}
}
fraction += 1;
rowSize -= 1;
}
currentDepth += 1;
headers.push(row);
}
const columns = items.map(item => extractLeaves(item)).flat();
return {
columns,
headers
};
}
function convertToInternalHeaders(items) {
const internalHeaders = [];
for (const item of items) {
const defaultItem = {
...getDefaultItem(item),
...item
};
const key = defaultItem.key ?? (typeof defaultItem.value === 'string' ? defaultItem.value : null);
const value = defaultItem.value ?? key ?? null;
const internalItem = {
...defaultItem,
key,
value,
sortable: defaultItem.sortable ?? (defaultItem.key != null || !!defaultItem.sort),
children: defaultItem.children ? convertToInternalHeaders(defaultItem.children) : undefined
};
internalHeaders.push(internalItem);
}
return internalHeaders;
}
export function createHeaders(props, options) {
const headers = ref([]);
const columns = ref([]);
const sortFunctions = ref({});
const sortRawFunctions = ref({});
const filterFunctions = ref({});
watchEffect(() => {
const _headers = props.headers || Object.keys(props.items[0] ?? {}).map(key => ({
key,
title: capitalize(key)
}));
const items = _headers.slice();
const keys = extractKeys(items);
if (options?.groupBy?.value.length && !keys.has('data-table-group')) {
items.unshift({
key: 'data-table-group',
title: 'Group'
});
}
if (options?.showSelect?.value && !keys.has('data-table-select')) {
items.unshift({
key: 'data-table-select'
});
}
if (options?.showExpand?.value && !keys.has('data-table-expand')) {
items.push({
key: 'data-table-expand'
});
}
const internalHeaders = convertToInternalHeaders(items);
parseFixedColumns(internalHeaders);
const maxDepth = Math.max(...internalHeaders.map(item => getDepth(item))) + 1;
const parsed = parse(internalHeaders, maxDepth);
headers.value = parsed.headers;
columns.value = parsed.columns;
const flatHeaders = parsed.headers.flat(1);
for (const header of flatHeaders) {
if (!header.key) continue;
if (header.sortable) {
if (header.sort) {
sortFunctions.value[header.key] = header.sort;
}
if (header.sortRaw) {
sortRawFunctions.value[header.key] = header.sortRaw;
}
}
if (header.filter) {
filterFunctions.value[header.key] = header.filter;
}
}
});
const data = {
headers,
columns,
sortFunctions,
sortRawFunctions,
filterFunctions
};
provide(VDataTableHeadersSymbol, data);
return data;
}
export function useHeaders() {
const data = inject(VDataTableHeadersSymbol);
if (!data) throw new Error('Missing headers!');
return data;
}
//# sourceMappingURL=headers.mjs.map