mirror of
https://github.com/speatzle/nfsense.git
synced 2025-05-10 18:38:22 +00:00
Improve NiceTable component support
- Also vastly improved row selection logic
This commit is contained in:
parent
3b0d4fcdaf
commit
fdcc48f8be
1 changed files with 29 additions and 59 deletions
|
@ -8,15 +8,15 @@ const props = defineModels<{
|
||||||
columns?: {
|
columns?: {
|
||||||
heading: string,
|
heading: string,
|
||||||
path: string,
|
path: string,
|
||||||
component?: Component,
|
component?: string,
|
||||||
}[],
|
}[], // -
|
||||||
data?: Record<string, any>[],
|
data?: Record<string, any>[],
|
||||||
sort?: boolean,
|
sort?: boolean,
|
||||||
sortSelf?: boolean,
|
sortSelf?: boolean, // -
|
||||||
sortBy?: string,
|
sortBy?: string,
|
||||||
sortDesc?: boolean,
|
sortDesc?: boolean,
|
||||||
selection?: number[],
|
selection?: number[],
|
||||||
draggable?: boolean,
|
draggable?: boolean, // -
|
||||||
}>();
|
}>();
|
||||||
let { columns, data, sort, sortSelf, sortBy, sortDesc, selection, draggable } = $(props);
|
let { columns, data, sort, sortSelf, sortBy, sortDesc, selection, draggable } = $(props);
|
||||||
|
|
||||||
|
@ -26,7 +26,10 @@ const emit = defineEmits<{
|
||||||
(event: 'draggedRow', draggedRow: number, draggedOverRow: number): void,
|
(event: 'draggedRow', draggedRow: number, draggedOverRow: number): void,
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
if (!selection) selection = [];
|
const componentProp: Record<string, string> = {
|
||||||
|
"EnumDisplay": "data",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const displayData = $computed(() => (sortSelf && sortBy !== '')
|
const displayData = $computed(() => (sortSelf && sortBy !== '')
|
||||||
? data?.sort((a, b) => {
|
? data?.sort((a, b) => {
|
||||||
|
@ -44,52 +47,26 @@ const displayData = $computed(() => (sortSelf && sortBy !== '')
|
||||||
function toggleSorting(columnName: string) {
|
function toggleSorting(columnName: string) {
|
||||||
if (!sort) return;
|
if (!sort) return;
|
||||||
if (columnName === sortBy) sortDesc = !sortDesc;
|
if (columnName === sortBy) sortDesc = !sortDesc;
|
||||||
else {
|
else [sortDesc, sortBy] = [false, columnName];
|
||||||
sortDesc = false;
|
|
||||||
sortBy = columnName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function rowSelection(index: number) {
|
function toggleRowSelection(index: number) {
|
||||||
if (!selection) selection = [];
|
if (!selection || !selection.length) selection = [index];
|
||||||
if (shiftState) {
|
else if (shiftState) { // Selection becomes a range including the highest, lowest and clicked row
|
||||||
if (!selection?.length) {
|
const points = [Math.max(...selection), Math.min(...selection), index];
|
||||||
selection = [index];
|
const [max, min] = [Math.max(...points), Math.min(...points)];
|
||||||
} else {
|
selection = Array.from({length: max - min + 1}, (_, i) => i + min);
|
||||||
let last = selection[selection.length-1];
|
} else if (ctrlState) // Toggle the presence of the row in the selection
|
||||||
let start = index;
|
selection = selection.includes(index)
|
||||||
let end = last;
|
? selection.filter(i => i !== index)
|
||||||
if (last < start) {
|
: selection = [...selection, index];
|
||||||
start = last;
|
else selection = selection.includes(index) ? [] : [index]; // Toggle between selection of none and this row
|
||||||
end = index;
|
|
||||||
}
|
|
||||||
for (let i = start; i <= end; i++ ) {
|
|
||||||
if (!selection.includes(i)) {
|
|
||||||
selection = [...selection, i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ctrlState) {
|
|
||||||
if (selection.includes(index)) {
|
|
||||||
// remove if already exists
|
|
||||||
selection.splice(selection.indexOf(index), 1);
|
|
||||||
} else {
|
|
||||||
selection = [...selection, index];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (selection.includes(index)) {
|
|
||||||
selection = [];
|
|
||||||
} else {
|
|
||||||
selection = [index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit('selectionChanged');
|
emit('selectionChanged');
|
||||||
}
|
}
|
||||||
|
|
||||||
function atPath(value: any, path: string): any {
|
function atPath(value: any, path: string): any {
|
||||||
for (const segment of path.split('.')) {
|
for (const segment of path.split('.'))
|
||||||
value = value[segment];
|
value = (value ?? {} as any)[segment];
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,10 +81,9 @@ function dragDropRow() {
|
||||||
emit('draggedRow', draggedRow, draggedOverRow);
|
emit('draggedRow', draggedRow, draggedOverRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset drag data
|
// Reset Drag & Remove Selection
|
||||||
draggedRow = 0;
|
draggedRow = 0;
|
||||||
draggedOverRow = 0;
|
draggedOverRow = 0;
|
||||||
// Kill selection
|
|
||||||
selection = [];
|
selection = [];
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -130,7 +106,7 @@ function dragDropRow() {
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(row, index) in displayData" :key="index"
|
<tr v-for="(row, index) in displayData" :key="index"
|
||||||
:draggable="draggable"
|
:draggable="draggable"
|
||||||
@click="() => rowSelection(index)"
|
@click="() => toggleRowSelection(index)"
|
||||||
@dblclick="() => emit('rowAction', index)"
|
@dblclick="() => emit('rowAction', index)"
|
||||||
@dragstart="() => draggedRow = index"
|
@dragstart="() => draggedRow = index"
|
||||||
@dragenter="() => draggedOverRow = index"
|
@dragenter="() => draggedOverRow = index"
|
||||||
|
@ -141,8 +117,8 @@ function dragDropRow() {
|
||||||
'dragged-over-after': index === draggedOverRow && draggedOverRow > draggedRow,
|
'dragged-over-after': index === draggedOverRow && draggedOverRow > draggedRow,
|
||||||
}">
|
}">
|
||||||
<td v-for="{path, component} of columns" :key="path">
|
<td v-for="{path, component} of columns" :key="path">
|
||||||
{{ component ? "" : atPath(row, path) }}
|
<component v-if="component" :is="component" v-bind="{[componentProp[component]]: atPath(row, path)}"/>
|
||||||
<component v-if="component" :is="component"/>
|
<template v-else>{{ atPath(row, path) }}</template>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -150,14 +126,8 @@ function dragDropRow() {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.dragged-over-before {
|
.dragged-over-before { border-top: 0.25rem solid var(--cl-fg); }
|
||||||
border-top: 0.25rem solid var(--cl-fg);
|
.dragged-over-after { border-bottom: 0.25rem solid var(--cl-fg); }
|
||||||
}
|
|
||||||
.dragged-over-after {
|
|
||||||
border-bottom: 0.25rem solid var(--cl-fg);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr {
|
tr { cursor: grab; }
|
||||||
cursor: grab;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
Loading…
Add table
Reference in a new issue