tablevu 0.1.3 → 0.2.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/src/table.js CHANGED
@@ -1,362 +1,580 @@
1
- /*
2
- * tablevu
3
- * A small, fast, easy-to-use table component.
4
- * Copyright (c) 2020 Ender Boz <ender.boz@gmail.com>
5
- * https://github.com/endb/tablevu/LICENCE
6
- */
7
-
8
- import { h, reactive, watch } from 'vue';
9
-
10
- const tablevuStatuses = { Error: -1, Ready: 0, Loading: 1 };
11
-
12
- const tablevu = {
13
- props: {
14
- data: { type: [Array, Object] },
15
- search: { type: String },
16
- filter: { type: [Array, Object] },
17
- rowid: { type: String },
18
- onRowClick: { type: Function },
19
- onRowDblClick: { type: Function },
20
- class: { type: String, default: 'table' },
21
- buttonclass: { type: String, default: 'btn' }
22
- },
23
-
24
- setup(props) {
25
- let rows = [];
26
-
27
- const spec = reactive({
28
- pageSize: props.data.pageSize || 20,
29
- pageCount: 0,
30
- currPage: 0,
31
- sort: props.data.sort || [],
32
- status: tablevuStatuses.Ready,
33
- timer: null,
34
- time: null,
35
- cols: [],
36
- filter: null,
37
- search: null
38
- });
39
-
40
- // Setup Search Input //
41
- watch(() => props.search, (n,o) => {
42
- if (spec.timer)
43
- clearTimeout(spec.timer);
44
-
45
- if ((o && o.length > (props.data.searchMinChar || 3) && (n == undefined || n == null || n.length <= (props.data.searchMinChar || 3))) || (n && n.length > (props.data.searchMinChar || 3))) {
46
- spec.timer = setTimeout(() => { if (props.search && props.search.length > (props.data.searchMinChar || 3)) spec.search = props.search; else spec.search = null; refresh(); }, 444);
47
- }
48
- });
49
-
50
- watch(() => props.filter, () => {
51
- if (props.filter)
52
- spec.filter = props.filter;
53
- else
54
- spec.filter = null;
55
-
56
- refresh();
57
- }, { deep: true });
58
- /*****************************************************************
59
-
60
- *****************************************************************/
61
- function first() { // Go First Page //
62
- page(1);
63
- }
64
-
65
- function prior() { // Go Previus Page //
66
- if (spec.currPage > 1) {
67
- page(spec.currPage - 1);
68
- } else {
69
- page(spec.currPage);
70
- }
71
- }
72
-
73
- function next() { // Go Next Page //
74
- page(spec.currPage + 1);
75
- }
76
-
77
- function last() { // Go Last Page //
78
- page(spec.pageCount);
79
- }
80
-
81
- function refresh() { // Refresh active page //
82
- page(spec.currPage);
83
- }
84
-
85
- function orderby(ind) { // Sort data //
86
- if (spec.sort && spec.sort.length > 0) {
87
- let l = spec.sort.findIndex(f => f.index == ind);
88
-
89
- if (l == 0) {
90
- spec.sort[l].dir = spec.sort[0].dir ? null : 'desc';
91
- } else if (l > 0) {
92
- spec.sort.splice(l, 1);
93
- }
94
-
95
- if (l != 0) {
96
- spec.sort.unshift({ index: ind, dir: null });
97
- }
98
-
99
- if (spec.sort.length > 2) {
100
- spec.sort.pop();
101
- }
102
- } else {
103
- spec.sort.push({ index: ind, dir: null });
104
- }
105
-
106
- page(spec.currPage);
107
- }
108
-
109
- // Go Custom Page number //
110
- function page(currentPage) {
111
- if (!props.data) {
112
- return;
113
- }
114
-
115
- //const tm = Date.now();
116
-
117
- spec.status = tablevuStatuses.Loading;
118
- //spec.currPage = currentPage;
119
-
120
- if (Array.isArray(props.data)) {
121
- rows = props.data;
122
-
123
- spec.pageCount = (rows.length > 0 && spec.pageSize > 0) ? (rows.length / spec.pageSize) : 0;
124
- spec.status = tablevuStatuses.Ready;
125
- spec.currPage = currentPage;
126
- spec.time = Date.now();
127
- }
128
-
129
- if (props.data.adapter) {
130
- const r = props.data.adapter({ pageSize: spec.pageSize, pageCount: spec.pageCount, currPage: currentPage, sort: spec.sort, cols: spec.cols, filter: spec.filter, search: spec.search });
131
-
132
- fetch(r).then(res => res.json()).then(res => {
133
- let cnt = 0;
134
- if (res && Object.hasOwnProperty.call(res, '@count')) {
135
- cnt = BigInt.parse(res['@count']);
136
- }
137
-
138
- if (res && res.value) {
139
- rows = res.value;
140
-
141
- spec.pageCount = (cnt > 0 && spec.pageSize > 0) ? (cnt / spec.pageSize) : 0;
142
- spec.status = tablevuStatuses.Ready;
143
- spec.currPage = currentPage;
144
- spec.time = Date.now();
145
- }
146
- }).catch(err => {
147
- console.error(err);
148
- // debugger;
149
- spec.status = tablevuStatuses.Error;
150
- alert(err.message);
151
- });
152
- }
153
- }
154
- /*****************************************************************
155
- Render Functions
156
- *****************************************************************/
157
- function renderCell(col, val) {
158
- let v;
159
- const o = { style: {} };
160
-
161
- if (col.align) {
162
- o.style['text-align'] = col.align;
163
- }
164
-
165
- if (col.width) {
166
- o.style['max-width'] = col.width;
167
- }
168
-
169
- if (val) {
170
- if (col.type == 'datetime' || col.type == 'date' || col.type == 'time') {
171
- let t = new Date(val);
172
-
173
- if (col.type == 'date')
174
- v = t.toLocaleDateString();
175
- else
176
- if (col.type == 'time')
177
- v = t.toLocaleTimeString();
178
- else
179
- v = t.toLocaleString();
180
- } else {
181
- if (col.type == 'numeric') {
182
- v = Number.parse(val);
183
- } else {
184
- v = val;
185
- }
186
- }
187
- } else {
188
- v = '';
189
- }
190
-
191
- return h('td', o, v);
192
- }
193
-
194
- function renderCustomCell(col, row) {
195
- const o = { style: {} };
196
-
197
- if (col.align) {
198
- o.style['text-align'] = col.align;
199
- }
200
-
201
- if (col.width) {
202
- o.style['max-width'] = col.width;
203
- }
204
-
205
- let f = col.render(row);
206
-
207
- return h('td', o, f);
208
- }
209
-
210
- function renderRow(index, row) {
211
- const o = {};
212
- const r = [];
213
-
214
- o.key = index;
215
-
216
- if (props.rowid) {
217
- o.rowid = row[props.rowid];
218
- }
219
-
220
- for (let i = 0; i < spec.cols.length; i += 1) {
221
- let v;
222
- const c = spec.cols[i];
223
-
224
- if (c.render) {
225
- v = renderCustomCell(c, row);
226
- r.push(v);
227
- } else {
228
- if (c.depth) {
229
- v = row;
230
- for (let j = 0; j < c.depth.length; j += 1) {
231
- v = v[c.depth[j]];
232
- }
233
- } else {
234
- v = row[c.name];
235
- }
236
-
237
- r.push(renderCell(c, v));
238
- }
239
- }
240
-
241
- if (props.data.onRowDblClick) {
242
- o.ondblclick = (event) => {
243
- const r = rows[event.currentTarget.rowIndex-1];
244
- props.data.onRowDblClick(event, r);
245
- };
246
- } else if (props.onRowDblClick) {
247
- o.ondblclick = (event) => {
248
- const r = rows[event.currentTarget.rowIndex-1];
249
- props.onRowDblClick(event, r);
250
- };
251
- }
252
-
253
-
254
- if (props.onRowClick) {
255
- o.onClick = (event) => {
256
- const r = rows[event.currentTarget.rowIndex-1];
257
- props.onRowClick(event, r);
258
- };
259
- }
260
-
261
- return h('tr', o, r);
262
- }
263
-
264
- function renderHeader() {
265
- const th = [];
266
-
267
- for (let i = 0; i < spec.cols.length; i += 1) {
268
- const s = [];
269
-
270
- if (spec.cols[i].label) {
271
- s.push(h('span', spec.cols[i].label));
272
- } else {
273
- s.push(h('span', spec.cols[i].name));
274
- }
275
-
276
- if (spec.sort && spec.sort.length > 0 && spec.sort[0].index == i) {
277
- if (spec.sort[0].dir == 'desc')
278
- s.push(h('span', { style: { float: 'right' } }, '⯆'))
279
- else
280
- s.push(h('span', { style: { float: 'right' } }, '⯅'))
281
- }
282
-
283
- const a = h('a', { href: '#', onClick(event) { orderby(i); event.preventDefault(); }, style: { display: 'block', 'font-weight': 500, 'text-decoration': 'none', color: 'black' } }, s);
284
-
285
- th.push(h('th', { style: { width: spec.cols[i].width ? spec.cols[i].width : 'auto', 'max-width': spec.cols[i].width ? spec.cols[i].width : 'auto' } }, [a]));
286
- }
287
-
288
- const tr = h('tr', {}, th);
289
-
290
- return [tr];
291
- }
292
-
293
- function renderBody() {
294
- const dr = [];
295
-
296
- if (rows && rows.length > 0) {
297
- for (let i = 0; i < rows.length; i += 1) {
298
- dr.push(renderRow(i, rows[i]));
299
- }
300
- }
301
-
302
- return dr;
303
- }
304
-
305
- function renderFooter() {
306
- const fr = h('button', { class: props.buttonclass, style: 'margin-right: .5rem', onClick: first, disabled: spec.currPage == 1 }, '\u2bc5');
307
- const ls = h('button', { class: props.buttonclass, style: 'margin-right: .5rem', onClick: last, disabled: spec.pageCount > 0 }, '\u2bc6');
308
- const pg = h('button', { class: props.buttonclass, style: 'margin-right: .5rem' }, spec.currPage);
309
- const pr = h('button', { class: props.buttonclass, style: 'margin-right: .5rem', onClick: prior, disabled: spec.currPage == 1 }, '\u2bc7');
310
- const nx = h('button', { class: props.buttonclass, style: 'margin-right: .5rem', onClick: next }, '\u2bc8');
311
- const td = h('td', { colspan: spec.cols.length, align: 'center' }, [fr, pr, pg, nx, ls]);
312
- const tr = h('tr', {}, [td]);
313
-
314
- return [tr];
315
- }
316
- /*****************************************************************
317
- Columns
318
- *****************************************************************/
319
- let cls = [];
320
-
321
- if (props.data.columns) {
322
- cls = props.data.columns;
323
- } else {
324
- alert('not ready !')
325
- //cls = slots.default().map(m => m.props);
326
- }
327
-
328
- for (let i = 0; i < cls.length; i += 1) {
329
- let s = cls[i];
330
-
331
- if (s.name.indexOf('.') > -1) {
332
- s.depth = s.name.split('.');
333
- }
334
-
335
- spec.cols.push(s);
336
- }
337
-
338
- page(1);
339
-
340
- return {
341
- spec, rows,
342
- first, prior, next, last, refresh, orderby,
343
- renderHeader, renderCell, renderCustomCell, renderRow, renderBody, renderFooter
344
- };
345
- },
346
-
347
- render(props) {
348
- const header = h('thead', {}, this.renderHeader());
349
- const body = h('tbody', { 'data-time': this.spec.time}, this.renderBody());
350
- const footer = h('tfoot', {}, this.renderFooter());
351
-
352
- return h('table', {
353
- class: props.class,
354
- }, [
355
- header,
356
- body,
357
- footer
358
- ]);
359
- }
360
- };
361
-
362
- export default tablevu;
1
+ /*
2
+ * tablevu
3
+ * A small, fast, easy-to-use table component.
4
+ * Copyright (c) 2020 Ender Boz <ender.boz@gmail.com>
5
+ * https://github.com/endb/tablevu/LICENCE
6
+ */
7
+
8
+ import { h, onMounted, reactive, ref, watch } from 'vue';
9
+ import adaptarr from './array.js';
10
+
11
+ const tablevuStatuses = { Error: -1, Ready: 0, Loading: 1 };
12
+
13
+ const tablevu = {
14
+ props: {
15
+ settings: { type: Object, default: null },
16
+ data: { type: [Array, Function] },
17
+ //group: { type: Object, default: { value: null, expandAll: true, class: 'table-light' } },
18
+ search: { type: String },
19
+ filter: { type: [Array, Object] },
20
+ command: { type: Array, default: [] },
21
+ rowid: { type: String },
22
+ onRowClick: { type: Function },
23
+ onRowDblClick: { type: Function },
24
+ class: { type: String, default: 'table' },
25
+ style: { type: String, default: null },
26
+ buttonClass: { type: String, default: 'btn' }
27
+ },
28
+
29
+ emits: ['onRowClick', 'onRowDblClick'],
30
+
31
+ setup(props, { attrs, slots, emit, expose }) {
32
+ let grps = [];
33
+ let rows = [];
34
+ let count = 0;
35
+
36
+ const spec = reactive({
37
+ adapter: null,
38
+ group: {
39
+ value: (props.settings && props.settings.group) ? props.settings.group.value : props.group ? props.group: null, // string ise alan adı, int ise index, fonksiyon ise calistirip alacak.
40
+ content: (props.settings && props.settings.group) ? props.settings.group.content : null, // grid de ne gosterilecek
41
+ expandAll: true,
42
+ class: 'table-light'
43
+ },
44
+ page: {
45
+ count: 0,
46
+ size: (props.settings && props.settings.page) ? props.settings.page.size : 0,
47
+ current: 0,
48
+ type: null // incrementral, dynamic
49
+ },
50
+ footer: {
51
+ button: {
52
+ first: { visible: true, content: null },
53
+ prior: { visible: true, content: null },
54
+ next: { visible: true, content: null },
55
+ last: { visible: true, content: null },
56
+ page: { visible: true, content: null },
57
+ size: { visible: true, content: null },
58
+ class: 'btn'
59
+ }
60
+ },
61
+ sort: (props.settings && props.settings.sort) ? props.settings.sort : [],
62
+ columns: (props.settings && props.settings.columns) ? props.settings.columns : [],
63
+ onRowClick: props.settings.onRowClick || props.onRowClick,
64
+ onRowDblClick: props.settings.onRowDblClick || props.onRowDblClick,
65
+ });
66
+
67
+ if (props.data) {
68
+ if (Array.isArray(props.data)) {
69
+ spec.adapter = adaptarr;
70
+ }
71
+ else {
72
+ spec.adapter = props.data;
73
+ }
74
+ };
75
+
76
+ // Setup dynamic filter //
77
+ if (props.filter)
78
+ spec.filter = props.filter;
79
+
80
+ watch(() => props.filter, (n, o) => {
81
+ if (n)
82
+ spec.filter = n;
83
+ else
84
+ spec.filter = null;
85
+
86
+ refresh();
87
+ }, { deep: true });
88
+
89
+ // Setup Search Input //
90
+ watch(() => props.search, (n,o) => {
91
+ if (spec.timer)
92
+ clearTimeout(spec.timer);
93
+
94
+ if ((o && o.length > (props.data.searchMinChar || 3) && (n == undefined || n == null || n.length <= (props.data.searchMinChar || 3))) || (n && n.length > (props.data.searchMinChar || 3))) {
95
+ spec.timer = setTimeout(() => { if (props.search && props.search.length > (props.data.searchMinChar || 3)) spec.search = props.search; else spec.search = null; refresh(); }, 444);
96
+ }
97
+ });
98
+
99
+ // Setup commands //
100
+ watch(() => props.command, (n,o) => {
101
+ if (n && n.length > 0) {
102
+ const c = props.command[n.length-1];
103
+
104
+ if (c && c.name) {
105
+ if (c.name.toLowerCase() == 'refresh') refresh()
106
+ else if (c.name.toLowerCase() == 'first') first()
107
+ else if (c.name.toLowerCase() == 'prior') prior()
108
+ else if (c.name.toLowerCase() == 'next') next()
109
+ else if (c.name.toLowerCase() == 'last') last()
110
+ else console.log('Unknown command');
111
+ }
112
+
113
+ props.command.length = 0;
114
+ }
115
+ }, { deep: true });
116
+
117
+ function prepareGroup(g, r) {
118
+ let s = [];
119
+
120
+ for (let i = 0; i < r.length; i++) {
121
+ let v = null;
122
+ let c = null;
123
+
124
+ const o = r[i];
125
+
126
+ if (g.value) {
127
+ if (typeof g.value == 'function')
128
+ v = g.value(o);
129
+ else
130
+ v = o[g.value];
131
+ } else
132
+ if (typeof g == 'function')
133
+ v = g(o);
134
+ else {
135
+ if (typeof g == 'bigint' || typeof g == 'number') {
136
+ const l = parseInt(g);
137
+
138
+ if (l)
139
+ v = o[l];
140
+ } else
141
+ if (typeof g == 'string')
142
+ v = o[g];
143
+ }
144
+
145
+ if (g.content) {
146
+ if (typeof g.content == 'function')
147
+ c = g.content(o);
148
+ else
149
+ c = o[g.content];
150
+ };
151
+
152
+ const n = s.findIndex(f => f.group == v);
153
+
154
+ if (n > -1)
155
+ s[n].rows.push(o);
156
+ else
157
+ s.push({ group: v, content: c, expand: spec.group.expandAll, rows: [o] });
158
+ };
159
+
160
+ return s;
161
+ }
162
+ /*****************************************************************
163
+
164
+ *****************************************************************/
165
+ function first() { // Go First Page //
166
+ page(1);
167
+ }
168
+
169
+ function prior() { // Go Previus Page //
170
+ if (spec.page.current > 1) {
171
+ page(spec.page.current - 1);
172
+ } else {
173
+ page(spec.page.current);
174
+ }
175
+ }
176
+
177
+ function next() { // Go Next Page //
178
+ page(spec.page.current + 1);
179
+ }
180
+
181
+ function last() { // Go Last Page //
182
+ page(spec.page.count);
183
+ }
184
+
185
+ function refresh() { // Refresh active page //
186
+ page(spec.page.current);
187
+ }
188
+
189
+ function orderby(ind, dir) { // Sort data //
190
+ if (spec.sort && spec.sort.length > 0) {
191
+ let l = spec.sort.findIndex(f => f.index == ind);
192
+
193
+ if (l == 0) {
194
+ spec.sort[l].dir = dir ? dir: (spec.sort[0].dir ? null : 'desc');
195
+ } else if (l > 0) {
196
+ spec.sort.splice(l, 1);
197
+ }
198
+
199
+ if (l != 0) {
200
+ spec.sort.unshift({ index: ind, dir: dir ? dir: null });
201
+ }
202
+
203
+ if (spec.sort.length > 2) {
204
+ spec.sort.pop();
205
+ }
206
+ } else {
207
+ spec.sort.push({ index: ind, dir: dir ? dir: null });
208
+ }
209
+
210
+ page(spec.page.current);
211
+ }
212
+
213
+ function page(currentPage) { // Go Custom Page number //
214
+ let dat = null;
215
+
216
+ if (props.data) {
217
+ if (Array.isArray(props.data))
218
+ dat = props.data;
219
+ } else
220
+ return;
221
+
222
+ spec.status = tablevuStatuses.Loading;
223
+
224
+ if (spec.adapter) {
225
+ spec.adapter({ pageSize: spec.page.size, currPage: currentPage, sort: spec.sort, cols: spec.columns, filter: spec.filter, search: spec.search }, dat).then(ada => {
226
+
227
+ if (spec.onData)
228
+ rows = spec.onData(ada.rows);
229
+ else
230
+ rows = ada.rows;
231
+
232
+ count = ada.count;
233
+
234
+ if (spec.group)
235
+ grps = prepareGroup(spec.group, rows);
236
+
237
+ spec.page.count = (ada.count > 0 && spec.page.size > 0) ? (ada.count / spec.page.size) : 0
238
+ spec.page.current = currentPage;
239
+
240
+ spec.status = tablevuStatuses.Ready;
241
+ spec.time = Date.now();
242
+ });
243
+ }
244
+ }
245
+ /*****************************************************************
246
+ Render Functions
247
+ *****************************************************************/
248
+ function renderValue(col, val) {
249
+ if (val) {
250
+ let v;
251
+
252
+ if (col.type == 'datetime' || col.type == 'date' || col.type == 'time') {
253
+ let t = new Date(val);
254
+
255
+ if (col.type == 'date')
256
+ v = t.toLocaleDateString();
257
+ else
258
+ if (col.type == 'time')
259
+ v = t.toLocaleTimeString();
260
+ else
261
+ v = t.toLocaleString();
262
+ } else {
263
+ if (col.type == 'numeric') {
264
+ v = parseFloat(val);
265
+ } else {
266
+ if (col.type == 'integer') {
267
+ v = parseInt(val);
268
+ } else
269
+ v = val;
270
+ }
271
+ };
272
+
273
+ return v;
274
+ } else
275
+ return '';
276
+ }
277
+
278
+ function renderCell(col, val) {
279
+ const o = { style: {} };
280
+
281
+ if (col.colspan && col.colspan > 1) {
282
+ o.colspan = col.colspan;
283
+ }
284
+
285
+ if (col.align) {
286
+ o.style['text-align'] = col.align;
287
+ }
288
+
289
+ if (col.width) {
290
+ o.style['max-width'] = col.width;
291
+ }
292
+
293
+ if (col.color) {
294
+ o.style['color'] = col.color;
295
+ }
296
+
297
+ if (col.backgroundColor) {
298
+ o.style['background-color'] = col.backgroundColor;
299
+ }
300
+
301
+ const v = renderValue(col, val);
302
+
303
+ return h('td', o, v);
304
+ }
305
+
306
+ function renderCustomCell(col, row) {
307
+ const o = { style: {} };
308
+
309
+ if (col.colspan && col.colspan > 1) {
310
+ o.colspan = col.colspan;
311
+ }
312
+
313
+ if (col.align) {
314
+ o.style['text-align'] = col.align;
315
+ }
316
+
317
+ if (col.width) {
318
+ o.style['max-width'] = col.width;
319
+ }
320
+
321
+ let f = col.render(row);
322
+
323
+ return h('td', o, f);
324
+ }
325
+
326
+ function renderGroup(grp) {
327
+ const b = h('button', { title: grp.expand, onClick: event => { console.log(grp.expand); grp.expand = (grp.expand ? false: true); event.currentTarget.value = grp.expand ? '▼': '►'; spec.time = Date.now(); event.preventDefault() }, style: { padding: 0, margin: '0 6px 0 0', width: '12px', height: '100%', border: 'none', outline: 0, backgroundColor: 'transparent' } }, grp.expand ? '▼': '►');
328
+ const v = grp.content || grp.group;
329
+
330
+
331
+ return h('tr', {}, h('td', { colspan: spec.columns.length, class: spec.group.class }, [b, v]));
332
+ }
333
+
334
+ function renderRow(index, row) {
335
+ const o = {};
336
+ const r = [];
337
+
338
+ o.key = index;
339
+ o.index = index;
340
+
341
+ if (props.rowid) {
342
+ o.rowid = row[props.rowid];
343
+ }
344
+
345
+ for (let i = 0; i < spec.columns.length; i += 1) {
346
+ let v;
347
+ const c = spec.columns[i];
348
+
349
+ if (c.render) {
350
+ v = renderCustomCell(c, row);
351
+ r.push(v);
352
+ } else {
353
+ if (c.depth) {
354
+ v = row;
355
+ for (let j = 0; j < c.depth.length; j += 1) {
356
+ if (v)
357
+ v = v[c.depth[j]];
358
+ }
359
+ } else {
360
+ v = row[c.name];
361
+ }
362
+
363
+ r.push(renderCell(c, v));
364
+ }
365
+ }
366
+
367
+ //if (spec.onRowDblClick)
368
+ o.ondblclick = (event) => {
369
+ const r = rows[event.currentTarget.attributes.index.value];
370
+ emit('onRowDblClick', event, r);
371
+ //props.onRowDblClick(event, r);
372
+ };
373
+
374
+ if (props.onRowClick) {
375
+ o.onClick = (event) => {
376
+ const r = rows[event.currentTarget.attributes.index.value];
377
+ props.onRowClick(event, r);
378
+ };
379
+ }
380
+
381
+ return h('tr', o, r);
382
+ }
383
+
384
+ function renderHeader() {
385
+ let ar = [];
386
+ let sp = 1;
387
+
388
+ for (let i = 0; i < spec.columns.length; i += 1) {
389
+ if (sp > 1) {
390
+ sp--;
391
+ continue;
392
+ };
393
+
394
+ const cl = [];
395
+
396
+ if (spec.columns[i].label) {
397
+ cl.push(h('span', spec.columns[i].label));
398
+ } else {
399
+ cl.push(h('span', spec.columns[i].name));
400
+ }
401
+
402
+ if (spec.sort && spec.sort.length > 0 && spec.sort[0].index == i) {
403
+ if (spec.sort[0].dir == 'desc')
404
+ cl.push(h('span', { style: { float: 'right' } }, '▼'))
405
+ else
406
+ cl.push(h('span', { style: { float: 'right' } }, '▲'))
407
+ }
408
+
409
+ let ch = { position: 'relative' };
410
+
411
+ if (spec.columns[i].width) {
412
+ ch.width = spec.columns[i].width;
413
+ ch.minWidth = spec.columns[i].width;
414
+ ch.maxWidth = spec.columns[i].width;
415
+ }
416
+
417
+ let cy = { display: 'block', 'font-weight': 500, textDecoration: 'none', color: 'black', textAlign: 'center' };
418
+
419
+ if (spec.columns[i].header) {
420
+ if (spec.columns[i].header.colspan)
421
+ sp = parseInt(spec.columns[i].header.colspan) || 1;
422
+
423
+ if (spec.columns[i].header.align)
424
+ cy.textAlign = spec.columns[i].header.align;
425
+
426
+ if (spec.columns[i].header.backgroundColor)
427
+ ch.backgroundColor = spec.columns[i].header.backgroundColor;
428
+
429
+ if (spec.columns[i].header.color)
430
+ cy.color = spec.columns[i].header.color;
431
+ }
432
+
433
+ let a;
434
+ let f;
435
+
436
+ if (spec.columns[i].popup) {
437
+ const r = ref(null);
438
+ let c = [
439
+ h('a', { href: '#', onClick(event) { orderby(i); event.preventDefault(); }, style: { display: 'block', textDecoration: 'none', color: 'black', fontWeight: 'initial', padding: '.25rem' } }, 'Order by Ascending'),
440
+ h('a', { href: '#', onClick(event) { orderby(i, 'desc'); event.preventDefault(); }, style: { display: 'block', textDecoration: 'none', color: 'black', fontWeight: 'initial', padding: '.25rem' } }, 'Order by Descending'),
441
+ ];
442
+
443
+ a = h('a', { href: '#', onClick(event) { if (r.value && r.value.style && r.value.style.display && r.value.style.display == 'block') r.value.style.display = 'none'; else r.value.style.display = 'block'; event.preventDefault(); }, style: cy }, cl);
444
+ f = h('div', { ref: r, style: { position: 'absolute', display: 'none', width: spec.columns[i].width || '12rem', height: 'fit-content', border: '1px solid lightgray', backgroundColor: 'whitesmoke', zIndex: 1, left: 0, top: '2rem', bottom: 0, right: 0, padding: '.25rem' }}, c);
445
+
446
+ } else
447
+ a = h('a', { href: '#', onClick(event) { orderby(i); event.preventDefault(); }, style: cy }, cl);
448
+
449
+ if (spec.columns[i].filter) {
450
+ }
451
+
452
+ ar.push(h('th', { colspan: sp > 1 ? sp: null, style: ch }, [a, f]));
453
+ }
454
+
455
+ const tr = h('tr', {}, ar);
456
+
457
+ return [tr];
458
+ }
459
+
460
+ function renderBody() {
461
+ const dr = [];
462
+
463
+ if (grps && grps.length > 0) {
464
+ let x = 0;
465
+
466
+ for (let g = 0; g < grps.length; g += 1) {
467
+ const r = grps[g];
468
+
469
+ dr.push(renderGroup(r));
470
+
471
+ if (r.expand && r.rows && r.rows.length > 0) {
472
+ for (let i = 0; i < r.rows.length; i += 1) {
473
+ dr.push(renderRow(x, r.rows[i]));
474
+ x++;
475
+ }
476
+ }
477
+ }
478
+ } else
479
+ if (rows && rows.length > 0) {
480
+ for (let i = 0; i < rows.length; i += 1) {
481
+ dr.push(renderRow(i, rows[i]));
482
+ }
483
+ }
484
+
485
+ return dr;
486
+ }
487
+
488
+ function renderFooter() {
489
+ const fr = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem', onClick: first, disabled: spec.page.current == 1 }, '◀◀');
490
+ const ls = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem', onClick: last, disabled: spec.page.count > 0 }, '▶▶');
491
+ const pg = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem' }, spec.page.current);
492
+ const pr = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem', onClick: prior, disabled: spec.page.current == 1 }, '◀');
493
+ const nx = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem', onClick: next, disabled: spec.page.count > 0 && spec.page.current == spec.page.count }, '▶');
494
+ const td = h('td', { colspan: spec.columns.length, align: 'center' }, [fr, pr, pg, nx, ls]);
495
+ const tr = h('tr', {}, [td]);
496
+
497
+ return [tr];
498
+ }
499
+
500
+ function renderCaption() {
501
+ return null; // NOT REMEMBER !!!
502
+ // caption-side
503
+ // text-align
504
+ }
505
+ /*****************************************************************
506
+ Columns
507
+ *****************************************************************/
508
+ if (spec.columns.length == 0) {
509
+ alert('Columns not defined !')
510
+ //cls = slots.default().map(m => m.props);
511
+ }
512
+
513
+ for (let i = 0; i < spec.columns.length; i++)
514
+ if (spec.columns[i].name && spec.columns[i].name.indexOf('.') > -1) {
515
+ spec.columns[i].depth = spec.columns[i].name.split('.');
516
+ }
517
+
518
+ page(1);
519
+
520
+ onMounted(() => {
521
+ console.log('tablevu.mounted');
522
+ });
523
+
524
+ return {
525
+ spec, renderHeader, renderBody, renderFooter, renderCaption
526
+ };
527
+
528
+
529
+ },
530
+
531
+ render(props) {
532
+ console.log('tablevu.render', this.spec.status);
533
+ let prps = { class: 'tablevu' };
534
+ /*
535
+ if (props.id)
536
+ prps.id = props.id;
537
+ */
538
+ if (props.class)
539
+ prps.class = 'tablevu ' + props.class;
540
+
541
+ if (props.style)
542
+ prps.style = props.style;
543
+
544
+ /* if (props.dir)
545
+ prps.dir = props.dir;
546
+
547
+ if (props.hidden)
548
+ prps.hidden = props.hidden;
549
+
550
+
551
+ if (props.title)
552
+ prps.title = props.title;
553
+ */
554
+ // Content //
555
+ let cntn = [];
556
+
557
+ cntn.push(
558
+ h('thead', {}, this.renderHeader())
559
+ );
560
+
561
+ if (this.spec.status == tablevuStatuses.Ready)
562
+ cntn.push(
563
+ h('tbody', { 'data-time': this.spec.time}, this.renderBody())
564
+ );
565
+
566
+ if (this.spec.caption)
567
+ cntn.push(
568
+ h('caption', {}, this.renderCaption())
569
+ );
570
+
571
+ if (this.spec.page.size > 0)
572
+ cntn.push(
573
+ h('tfoot', {}, this.renderFooter())
574
+ );
575
+
576
+ return h('table', prps, cntn);
577
+ }
578
+ };
579
+
580
+ export default tablevu;