tablevu 0.2.22 → 0.3.0-beta.1

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