tablevu 0.3.0-beta.4 → 0.3.0
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.
- package/dist/table copy.d.ts +174 -0
- package/dist/tablevu.cjs +113 -9
- package/dist/tablevu.esm.js +113 -9
- package/package.json +1 -1
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { TablevuStatus } from './types';
|
|
2
|
+
import type { TablevuSettings, AdapterFunction } from './types';
|
|
3
|
+
export interface TableVuExpose {
|
|
4
|
+
first: () => Promise<void>;
|
|
5
|
+
prior: () => void | Promise<void>;
|
|
6
|
+
next: () => void | Promise<void>;
|
|
7
|
+
last: () => void | Promise<void>;
|
|
8
|
+
go: (pageNumber: number) => void | Promise<void>;
|
|
9
|
+
page: (pageNumber: number) => Promise<void>;
|
|
10
|
+
refresh: () => Promise<void>;
|
|
11
|
+
sortBy: (columnIndex: number, direction?: string) => void | Promise<void>;
|
|
12
|
+
getRows: () => any[];
|
|
13
|
+
setRows: (rows: any[]) => void;
|
|
14
|
+
}
|
|
15
|
+
declare const tablevu: import("vue").DefineComponent<{
|
|
16
|
+
settings?: (TablevuSettings | null) | undefined;
|
|
17
|
+
data?: (any[] | AdapterFunction) | undefined;
|
|
18
|
+
group?: (string | import("./types").TablevuGroup) | undefined;
|
|
19
|
+
search?: string | undefined;
|
|
20
|
+
filter?: any;
|
|
21
|
+
command?: Array<{
|
|
22
|
+
name: "refresh" | "first" | "prior" | "next" | "last" | "go" | string;
|
|
23
|
+
page?: number;
|
|
24
|
+
}> | undefined;
|
|
25
|
+
rowid?: string | undefined;
|
|
26
|
+
onRowClick?: ((event: MouseEvent, row: any) => void) | undefined;
|
|
27
|
+
onRowDblClick?: ((event: MouseEvent, row: any) => void) | undefined;
|
|
28
|
+
class?: string | undefined;
|
|
29
|
+
style?: (string | Record<string, string> | null) | undefined;
|
|
30
|
+
}, {
|
|
31
|
+
renderHeader: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
32
|
+
[key: string]: any;
|
|
33
|
+
}>[];
|
|
34
|
+
renderBody: () => any[];
|
|
35
|
+
renderFooter: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
36
|
+
[key: string]: any;
|
|
37
|
+
}>[];
|
|
38
|
+
renderCaption: () => string;
|
|
39
|
+
first: () => Promise<void>;
|
|
40
|
+
prior: () => Promise<void> | undefined;
|
|
41
|
+
next: () => Promise<void> | undefined;
|
|
42
|
+
last: () => Promise<void> | undefined;
|
|
43
|
+
go: (pageNumber: number) => Promise<void> | undefined;
|
|
44
|
+
page: (pageNumber: number) => Promise<void>;
|
|
45
|
+
refresh: () => Promise<void>;
|
|
46
|
+
sortBy: (columnIndex: number, direction?: string) => Promise<void>;
|
|
47
|
+
getRows: () => any[];
|
|
48
|
+
setRows: (newRows: any[]) => void;
|
|
49
|
+
state: {
|
|
50
|
+
caption: any;
|
|
51
|
+
group: {
|
|
52
|
+
value: any;
|
|
53
|
+
content: any;
|
|
54
|
+
expandAll: boolean;
|
|
55
|
+
class: string;
|
|
56
|
+
};
|
|
57
|
+
page: {
|
|
58
|
+
count: number;
|
|
59
|
+
size: number;
|
|
60
|
+
current: number;
|
|
61
|
+
type: string | null;
|
|
62
|
+
};
|
|
63
|
+
sort: {
|
|
64
|
+
index?: number | undefined;
|
|
65
|
+
name?: string | undefined;
|
|
66
|
+
dir?: "asc" | "desc" | null | string | undefined;
|
|
67
|
+
}[];
|
|
68
|
+
columns: {
|
|
69
|
+
name: string;
|
|
70
|
+
label?: string | undefined;
|
|
71
|
+
type?: "string" | "number" | "numeric" | "integer" | "date" | "time" | "datetime" | "boolean" | undefined;
|
|
72
|
+
align?: "left" | "center" | "right" | undefined;
|
|
73
|
+
width?: string | undefined;
|
|
74
|
+
style?: Record<string, string> | undefined;
|
|
75
|
+
render?: ((row: any) => any) | undefined;
|
|
76
|
+
colspan?: number | undefined;
|
|
77
|
+
depth?: string[] | undefined;
|
|
78
|
+
header?: {
|
|
79
|
+
colspan?: number | undefined;
|
|
80
|
+
style?: Record<string, string> | undefined;
|
|
81
|
+
align?: string | undefined;
|
|
82
|
+
} | undefined;
|
|
83
|
+
popup?: boolean | undefined;
|
|
84
|
+
filter?: any;
|
|
85
|
+
searchable?: boolean | undefined;
|
|
86
|
+
resizable?: boolean | undefined;
|
|
87
|
+
draggable?: boolean | undefined;
|
|
88
|
+
visible?: boolean | undefined;
|
|
89
|
+
}[];
|
|
90
|
+
footer: {
|
|
91
|
+
button: {
|
|
92
|
+
class: string;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
status: TablevuStatus;
|
|
96
|
+
time: number | null;
|
|
97
|
+
search: string | null;
|
|
98
|
+
filter: any;
|
|
99
|
+
onData?: ((rows: any[]) => any[]) | undefined;
|
|
100
|
+
settings?: {
|
|
101
|
+
group?: {
|
|
102
|
+
value?: string | number | bigint | ((row: any) => any) | undefined;
|
|
103
|
+
content?: string | number | ((row: any) => any) | undefined;
|
|
104
|
+
expandAll?: boolean | undefined;
|
|
105
|
+
class?: string | undefined;
|
|
106
|
+
} | undefined;
|
|
107
|
+
page?: {
|
|
108
|
+
size?: number | undefined;
|
|
109
|
+
type?: "incremental" | "dynamic" | undefined;
|
|
110
|
+
} | undefined;
|
|
111
|
+
sort?: {
|
|
112
|
+
index?: number | undefined;
|
|
113
|
+
name?: string | undefined;
|
|
114
|
+
dir?: "asc" | "desc" | null | string | undefined;
|
|
115
|
+
}[] | undefined;
|
|
116
|
+
columns?: {
|
|
117
|
+
name: string;
|
|
118
|
+
label?: string | undefined;
|
|
119
|
+
type?: "string" | "number" | "numeric" | "integer" | "date" | "time" | "datetime" | "boolean" | undefined;
|
|
120
|
+
align?: "left" | "center" | "right" | undefined;
|
|
121
|
+
width?: string | undefined;
|
|
122
|
+
style?: Record<string, string> | undefined;
|
|
123
|
+
render?: ((row: any) => any) | undefined;
|
|
124
|
+
colspan?: number | undefined;
|
|
125
|
+
depth?: string[] | undefined;
|
|
126
|
+
header?: {
|
|
127
|
+
colspan?: number | undefined;
|
|
128
|
+
style?: Record<string, string> | undefined;
|
|
129
|
+
align?: string | undefined;
|
|
130
|
+
} | undefined;
|
|
131
|
+
popup?: boolean | undefined;
|
|
132
|
+
filter?: any;
|
|
133
|
+
searchable?: boolean | undefined;
|
|
134
|
+
resizable?: boolean | undefined;
|
|
135
|
+
draggable?: boolean | undefined;
|
|
136
|
+
visible?: boolean | undefined;
|
|
137
|
+
}[] | undefined;
|
|
138
|
+
searchMinChar?: number | undefined;
|
|
139
|
+
footer?: {
|
|
140
|
+
button?: {
|
|
141
|
+
class?: string | undefined;
|
|
142
|
+
} | undefined;
|
|
143
|
+
} | undefined;
|
|
144
|
+
onData?: ((rows: any[]) => any[]) | undefined;
|
|
145
|
+
emptyMessage?: string | undefined;
|
|
146
|
+
} | undefined;
|
|
147
|
+
};
|
|
148
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("row-click" | "row-dbl-click")[], "row-click" | "row-dbl-click", import("vue").PublicProps, Readonly<{
|
|
149
|
+
settings?: (TablevuSettings | null) | undefined;
|
|
150
|
+
data?: (any[] | AdapterFunction) | undefined;
|
|
151
|
+
group?: (string | import("./types").TablevuGroup) | undefined;
|
|
152
|
+
search?: string | undefined;
|
|
153
|
+
filter?: any;
|
|
154
|
+
command?: Array<{
|
|
155
|
+
name: "refresh" | "first" | "prior" | "next" | "last" | "go" | string;
|
|
156
|
+
page?: number;
|
|
157
|
+
}> | undefined;
|
|
158
|
+
rowid?: string | undefined;
|
|
159
|
+
onRowClick?: ((event: MouseEvent, row: any) => void) | undefined;
|
|
160
|
+
onRowDblClick?: ((event: MouseEvent, row: any) => void) | undefined;
|
|
161
|
+
class?: string | undefined;
|
|
162
|
+
style?: (string | Record<string, string> | null) | undefined;
|
|
163
|
+
}> & Readonly<{
|
|
164
|
+
"onRow-click"?: ((...args: any[]) => any) | undefined;
|
|
165
|
+
"onRow-dbl-click"?: ((...args: any[]) => any) | undefined;
|
|
166
|
+
}>, {
|
|
167
|
+
readonly settings: TablevuSettings | null;
|
|
168
|
+
readonly command: {
|
|
169
|
+
name: string;
|
|
170
|
+
}[];
|
|
171
|
+
readonly class: string;
|
|
172
|
+
readonly style: string | Record<string, string>;
|
|
173
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
174
|
+
export default tablevu;
|
package/dist/tablevu.cjs
CHANGED
|
@@ -107,6 +107,8 @@ const tablevu = vue.defineComponent({
|
|
|
107
107
|
let groups = [];
|
|
108
108
|
let adapter = null;
|
|
109
109
|
let searchTimer = null;
|
|
110
|
+
let draggedColumnName = null;
|
|
111
|
+
let resizeCleanup = null;
|
|
110
112
|
const state = vue.reactive({
|
|
111
113
|
caption: null,
|
|
112
114
|
group: {
|
|
@@ -121,8 +123,12 @@ const tablevu = vue.defineComponent({
|
|
|
121
123
|
current: 0,
|
|
122
124
|
type: null
|
|
123
125
|
},
|
|
124
|
-
sort: (props.settings
|
|
125
|
-
columns: (props.settings
|
|
126
|
+
sort: (props.settings?.sort ?? []).map(sort => ({ ...sort })),
|
|
127
|
+
columns: (props.settings?.columns ?? []).map(column => ({
|
|
128
|
+
...column,
|
|
129
|
+
style: column.style ? { ...column.style } : undefined,
|
|
130
|
+
depth: column.depth ? [...column.depth] : undefined
|
|
131
|
+
})),
|
|
126
132
|
footer: {
|
|
127
133
|
button: {
|
|
128
134
|
class: (props.settings && props.settings.footer && props.settings.footer.button && props.settings.footer.button.class) || 'btn'
|
|
@@ -163,7 +169,62 @@ const tablevu = vue.defineComponent({
|
|
|
163
169
|
vue.onBeforeUnmount(() => {
|
|
164
170
|
if (searchTimer)
|
|
165
171
|
clearTimeout(searchTimer);
|
|
172
|
+
resizeCleanup?.();
|
|
166
173
|
});
|
|
174
|
+
function remapSortColumns(previousNames) {
|
|
175
|
+
state.sort.forEach((sort, index) => {
|
|
176
|
+
const name = previousNames[index] ?? sort.name;
|
|
177
|
+
if (!name)
|
|
178
|
+
return;
|
|
179
|
+
const columnIndex = state.columns.findIndex(column => column.name === name);
|
|
180
|
+
if (columnIndex >= 0)
|
|
181
|
+
sort.index = columnIndex;
|
|
182
|
+
else {
|
|
183
|
+
sort.name = name;
|
|
184
|
+
delete sort.index;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function reorderColumn(sourceName, targetName) {
|
|
189
|
+
const sourceIndex = state.columns.findIndex(column => column.name === sourceName);
|
|
190
|
+
const targetIndex = state.columns.findIndex(column => column.name === targetName);
|
|
191
|
+
if (sourceIndex < 0 || targetIndex < 0 || sourceIndex === targetIndex)
|
|
192
|
+
return;
|
|
193
|
+
const sortNames = state.sort.map(sort => sort.index !== undefined
|
|
194
|
+
? state.columns[sort.index]?.name
|
|
195
|
+
: sort.name);
|
|
196
|
+
const [column] = state.columns.splice(sourceIndex, 1);
|
|
197
|
+
state.columns.splice(targetIndex, 0, column);
|
|
198
|
+
remapSortColumns(sortNames);
|
|
199
|
+
}
|
|
200
|
+
function hideColumn(name) {
|
|
201
|
+
const sortNames = state.sort.map(sort => sort.index !== undefined
|
|
202
|
+
? state.columns[sort.index]?.name
|
|
203
|
+
: sort.name);
|
|
204
|
+
const index = state.columns.findIndex(column => column.name === name);
|
|
205
|
+
if (index < 0)
|
|
206
|
+
return;
|
|
207
|
+
state.columns.splice(index, 1);
|
|
208
|
+
remapSortColumns(sortNames);
|
|
209
|
+
}
|
|
210
|
+
function startColumnResize(event, column, header) {
|
|
211
|
+
event.preventDefault();
|
|
212
|
+
event.stopPropagation();
|
|
213
|
+
resizeCleanup?.();
|
|
214
|
+
const startX = event.clientX;
|
|
215
|
+
const startWidth = header.getBoundingClientRect().width;
|
|
216
|
+
const move = (moveEvent) => {
|
|
217
|
+
column.width = `${Math.max(40, startWidth + moveEvent.clientX - startX)}px`;
|
|
218
|
+
};
|
|
219
|
+
const up = () => {
|
|
220
|
+
document.removeEventListener('pointermove', move);
|
|
221
|
+
document.removeEventListener('pointerup', up);
|
|
222
|
+
resizeCleanup = null;
|
|
223
|
+
};
|
|
224
|
+
resizeCleanup = up;
|
|
225
|
+
document.addEventListener('pointermove', move);
|
|
226
|
+
document.addEventListener('pointerup', up);
|
|
227
|
+
}
|
|
167
228
|
if (props.filter)
|
|
168
229
|
state.filter = props.filter;
|
|
169
230
|
vue.watch(() => props.filter, () => {
|
|
@@ -456,11 +517,12 @@ const tablevu = vue.defineComponent({
|
|
|
456
517
|
else
|
|
457
518
|
labelContent.push(vue.h('span', { style: { float: 'right' } }, '▲'));
|
|
458
519
|
}
|
|
520
|
+
const column = state.columns[i];
|
|
459
521
|
const headerStyle = { position: 'relative' };
|
|
460
|
-
if (
|
|
461
|
-
headerStyle.width =
|
|
462
|
-
headerStyle.minWidth =
|
|
463
|
-
headerStyle.maxWidth =
|
|
522
|
+
if (column.width) {
|
|
523
|
+
headerStyle.width = column.width;
|
|
524
|
+
headerStyle.minWidth = column.width;
|
|
525
|
+
headerStyle.maxWidth = column.width;
|
|
464
526
|
}
|
|
465
527
|
let headerLink;
|
|
466
528
|
let popupContent;
|
|
@@ -489,7 +551,47 @@ const tablevu = vue.defineComponent({
|
|
|
489
551
|
else
|
|
490
552
|
headerLink = vue.h('a', { href: '#', onClick: (event) => { sortBy(i); event.preventDefault(); }, style: { display: 'block', 'font-weight': 500, textDecoration: 'none', textAlign: 'center' } }, labelContent);
|
|
491
553
|
if (state.columns[i].filter) ;
|
|
492
|
-
|
|
554
|
+
const resizeHandle = column.resizable === false ? null : vue.h('div', {
|
|
555
|
+
'aria-hidden': 'true',
|
|
556
|
+
'onPointerdown': (event) => startColumnResize(event, column, event.currentTarget.parentElement),
|
|
557
|
+
style: { position: 'absolute', top: 0, right: '-3px', width: '6px', height: '100%', cursor: 'col-resize', touchAction: 'none', zIndex: 2 }
|
|
558
|
+
});
|
|
559
|
+
headers.push(vue.h('th', {
|
|
560
|
+
colspan: null,
|
|
561
|
+
style: headerStyle,
|
|
562
|
+
draggable: column.draggable !== false,
|
|
563
|
+
onDragstart: (event) => {
|
|
564
|
+
if (event.target.closest('[aria-hidden="true"]')) {
|
|
565
|
+
event.preventDefault();
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
draggedColumnName = column.name;
|
|
569
|
+
if (event.dataTransfer) {
|
|
570
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
571
|
+
event.dataTransfer.setData('text/plain', column.name);
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
onDragover: (event) => {
|
|
575
|
+
if (draggedColumnName) {
|
|
576
|
+
event.preventDefault();
|
|
577
|
+
if (event.dataTransfer)
|
|
578
|
+
event.dataTransfer.dropEffect = 'move';
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
onDrop: (event) => {
|
|
582
|
+
if (!draggedColumnName)
|
|
583
|
+
return;
|
|
584
|
+
event.preventDefault();
|
|
585
|
+
reorderColumn(draggedColumnName, column.name);
|
|
586
|
+
},
|
|
587
|
+
onDragend: (event) => {
|
|
588
|
+
const name = draggedColumnName;
|
|
589
|
+
draggedColumnName = null;
|
|
590
|
+
const rect = event.currentTarget.closest('table')?.getBoundingClientRect();
|
|
591
|
+
if (name && rect && (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom))
|
|
592
|
+
hideColumn(name);
|
|
593
|
+
}
|
|
594
|
+
}, [headerLink, popupContent, resizeHandle]));
|
|
493
595
|
}
|
|
494
596
|
return [vue.h('tr', {}, headers)];
|
|
495
597
|
}
|
|
@@ -632,8 +734,10 @@ function buildExpression(expression, lambdaVariable) {
|
|
|
632
734
|
throw new TypeError('OData "not" requires exactly one child filter.');
|
|
633
735
|
return `not (${buildExpression(children[0], lambdaVariable)})`;
|
|
634
736
|
}
|
|
635
|
-
if (children.length
|
|
636
|
-
throw new TypeError(`OData "${operator}" requires at least
|
|
737
|
+
if (children.length === 0)
|
|
738
|
+
throw new TypeError(`OData "${operator}" requires at least one child filter.`);
|
|
739
|
+
if (children.length === 1)
|
|
740
|
+
return buildExpression(children[0], lambdaVariable);
|
|
637
741
|
return `(${children.map(child => buildExpression(child, lambdaVariable)).join(` ${operator} `)})`;
|
|
638
742
|
}
|
|
639
743
|
if (operator === 'any' || operator === 'all') {
|
package/dist/tablevu.esm.js
CHANGED
|
@@ -105,6 +105,8 @@ const tablevu = defineComponent({
|
|
|
105
105
|
let groups = [];
|
|
106
106
|
let adapter = null;
|
|
107
107
|
let searchTimer = null;
|
|
108
|
+
let draggedColumnName = null;
|
|
109
|
+
let resizeCleanup = null;
|
|
108
110
|
const state = reactive({
|
|
109
111
|
caption: null,
|
|
110
112
|
group: {
|
|
@@ -119,8 +121,12 @@ const tablevu = defineComponent({
|
|
|
119
121
|
current: 0,
|
|
120
122
|
type: null
|
|
121
123
|
},
|
|
122
|
-
sort: (props.settings
|
|
123
|
-
columns: (props.settings
|
|
124
|
+
sort: (props.settings?.sort ?? []).map(sort => ({ ...sort })),
|
|
125
|
+
columns: (props.settings?.columns ?? []).map(column => ({
|
|
126
|
+
...column,
|
|
127
|
+
style: column.style ? { ...column.style } : undefined,
|
|
128
|
+
depth: column.depth ? [...column.depth] : undefined
|
|
129
|
+
})),
|
|
124
130
|
footer: {
|
|
125
131
|
button: {
|
|
126
132
|
class: (props.settings && props.settings.footer && props.settings.footer.button && props.settings.footer.button.class) || 'btn'
|
|
@@ -161,7 +167,62 @@ const tablevu = defineComponent({
|
|
|
161
167
|
onBeforeUnmount(() => {
|
|
162
168
|
if (searchTimer)
|
|
163
169
|
clearTimeout(searchTimer);
|
|
170
|
+
resizeCleanup?.();
|
|
164
171
|
});
|
|
172
|
+
function remapSortColumns(previousNames) {
|
|
173
|
+
state.sort.forEach((sort, index) => {
|
|
174
|
+
const name = previousNames[index] ?? sort.name;
|
|
175
|
+
if (!name)
|
|
176
|
+
return;
|
|
177
|
+
const columnIndex = state.columns.findIndex(column => column.name === name);
|
|
178
|
+
if (columnIndex >= 0)
|
|
179
|
+
sort.index = columnIndex;
|
|
180
|
+
else {
|
|
181
|
+
sort.name = name;
|
|
182
|
+
delete sort.index;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
function reorderColumn(sourceName, targetName) {
|
|
187
|
+
const sourceIndex = state.columns.findIndex(column => column.name === sourceName);
|
|
188
|
+
const targetIndex = state.columns.findIndex(column => column.name === targetName);
|
|
189
|
+
if (sourceIndex < 0 || targetIndex < 0 || sourceIndex === targetIndex)
|
|
190
|
+
return;
|
|
191
|
+
const sortNames = state.sort.map(sort => sort.index !== undefined
|
|
192
|
+
? state.columns[sort.index]?.name
|
|
193
|
+
: sort.name);
|
|
194
|
+
const [column] = state.columns.splice(sourceIndex, 1);
|
|
195
|
+
state.columns.splice(targetIndex, 0, column);
|
|
196
|
+
remapSortColumns(sortNames);
|
|
197
|
+
}
|
|
198
|
+
function hideColumn(name) {
|
|
199
|
+
const sortNames = state.sort.map(sort => sort.index !== undefined
|
|
200
|
+
? state.columns[sort.index]?.name
|
|
201
|
+
: sort.name);
|
|
202
|
+
const index = state.columns.findIndex(column => column.name === name);
|
|
203
|
+
if (index < 0)
|
|
204
|
+
return;
|
|
205
|
+
state.columns.splice(index, 1);
|
|
206
|
+
remapSortColumns(sortNames);
|
|
207
|
+
}
|
|
208
|
+
function startColumnResize(event, column, header) {
|
|
209
|
+
event.preventDefault();
|
|
210
|
+
event.stopPropagation();
|
|
211
|
+
resizeCleanup?.();
|
|
212
|
+
const startX = event.clientX;
|
|
213
|
+
const startWidth = header.getBoundingClientRect().width;
|
|
214
|
+
const move = (moveEvent) => {
|
|
215
|
+
column.width = `${Math.max(40, startWidth + moveEvent.clientX - startX)}px`;
|
|
216
|
+
};
|
|
217
|
+
const up = () => {
|
|
218
|
+
document.removeEventListener('pointermove', move);
|
|
219
|
+
document.removeEventListener('pointerup', up);
|
|
220
|
+
resizeCleanup = null;
|
|
221
|
+
};
|
|
222
|
+
resizeCleanup = up;
|
|
223
|
+
document.addEventListener('pointermove', move);
|
|
224
|
+
document.addEventListener('pointerup', up);
|
|
225
|
+
}
|
|
165
226
|
if (props.filter)
|
|
166
227
|
state.filter = props.filter;
|
|
167
228
|
watch(() => props.filter, () => {
|
|
@@ -454,11 +515,12 @@ const tablevu = defineComponent({
|
|
|
454
515
|
else
|
|
455
516
|
labelContent.push(h('span', { style: { float: 'right' } }, '▲'));
|
|
456
517
|
}
|
|
518
|
+
const column = state.columns[i];
|
|
457
519
|
const headerStyle = { position: 'relative' };
|
|
458
|
-
if (
|
|
459
|
-
headerStyle.width =
|
|
460
|
-
headerStyle.minWidth =
|
|
461
|
-
headerStyle.maxWidth =
|
|
520
|
+
if (column.width) {
|
|
521
|
+
headerStyle.width = column.width;
|
|
522
|
+
headerStyle.minWidth = column.width;
|
|
523
|
+
headerStyle.maxWidth = column.width;
|
|
462
524
|
}
|
|
463
525
|
let headerLink;
|
|
464
526
|
let popupContent;
|
|
@@ -487,7 +549,47 @@ const tablevu = defineComponent({
|
|
|
487
549
|
else
|
|
488
550
|
headerLink = h('a', { href: '#', onClick: (event) => { sortBy(i); event.preventDefault(); }, style: { display: 'block', 'font-weight': 500, textDecoration: 'none', textAlign: 'center' } }, labelContent);
|
|
489
551
|
if (state.columns[i].filter) ;
|
|
490
|
-
|
|
552
|
+
const resizeHandle = column.resizable === false ? null : h('div', {
|
|
553
|
+
'aria-hidden': 'true',
|
|
554
|
+
'onPointerdown': (event) => startColumnResize(event, column, event.currentTarget.parentElement),
|
|
555
|
+
style: { position: 'absolute', top: 0, right: '-3px', width: '6px', height: '100%', cursor: 'col-resize', touchAction: 'none', zIndex: 2 }
|
|
556
|
+
});
|
|
557
|
+
headers.push(h('th', {
|
|
558
|
+
colspan: null,
|
|
559
|
+
style: headerStyle,
|
|
560
|
+
draggable: column.draggable !== false,
|
|
561
|
+
onDragstart: (event) => {
|
|
562
|
+
if (event.target.closest('[aria-hidden="true"]')) {
|
|
563
|
+
event.preventDefault();
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
draggedColumnName = column.name;
|
|
567
|
+
if (event.dataTransfer) {
|
|
568
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
569
|
+
event.dataTransfer.setData('text/plain', column.name);
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
onDragover: (event) => {
|
|
573
|
+
if (draggedColumnName) {
|
|
574
|
+
event.preventDefault();
|
|
575
|
+
if (event.dataTransfer)
|
|
576
|
+
event.dataTransfer.dropEffect = 'move';
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
onDrop: (event) => {
|
|
580
|
+
if (!draggedColumnName)
|
|
581
|
+
return;
|
|
582
|
+
event.preventDefault();
|
|
583
|
+
reorderColumn(draggedColumnName, column.name);
|
|
584
|
+
},
|
|
585
|
+
onDragend: (event) => {
|
|
586
|
+
const name = draggedColumnName;
|
|
587
|
+
draggedColumnName = null;
|
|
588
|
+
const rect = event.currentTarget.closest('table')?.getBoundingClientRect();
|
|
589
|
+
if (name && rect && (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom))
|
|
590
|
+
hideColumn(name);
|
|
591
|
+
}
|
|
592
|
+
}, [headerLink, popupContent, resizeHandle]));
|
|
491
593
|
}
|
|
492
594
|
return [h('tr', {}, headers)];
|
|
493
595
|
}
|
|
@@ -630,8 +732,10 @@ function buildExpression(expression, lambdaVariable) {
|
|
|
630
732
|
throw new TypeError('OData "not" requires exactly one child filter.');
|
|
631
733
|
return `not (${buildExpression(children[0], lambdaVariable)})`;
|
|
632
734
|
}
|
|
633
|
-
if (children.length
|
|
634
|
-
throw new TypeError(`OData "${operator}" requires at least
|
|
735
|
+
if (children.length === 0)
|
|
736
|
+
throw new TypeError(`OData "${operator}" requires at least one child filter.`);
|
|
737
|
+
if (children.length === 1)
|
|
738
|
+
return buildExpression(children[0], lambdaVariable);
|
|
635
739
|
return `(${children.map(child => buildExpression(child, lambdaVariable)).join(` ${operator} `)})`;
|
|
636
740
|
}
|
|
637
741
|
if (operator === 'any' || operator === 'all') {
|