@hotstaq/admin-panel 0.3.6 → 0.3.9
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/.env +2 -0
- package/HotSite.json +0 -1
- package/assets/html/admin-header.hott +7 -3
- package/assets/js/dashboard.js +0 -46
- package/build/AppAPI.d.ts +21 -2
- package/build/AppAPI.d.ts.map +1 -1
- package/build/AppAPI.js +38 -43
- package/build/AppAPI.js.map +1 -1
- package/build/WebExport.d.ts.map +1 -1
- package/build/WebExport.js +8 -4
- package/build/WebExport.js.map +1 -1
- package/build/components/admin-button.js.map +1 -1
- package/build/components/admin-dropdown.js.map +1 -1
- package/build/components/admin-edit.d.ts +6 -1
- package/build/components/admin-edit.d.ts.map +1 -1
- package/build/components/admin-edit.js +50 -31
- package/build/components/admin-edit.js.map +1 -1
- package/build/components/admin-table-field.js +1 -1
- package/build/components/admin-table-field.js.map +1 -1
- package/build/components/admin-table-row.js.map +1 -1
- package/build/components/admin-table.d.ts +48 -2
- package/build/components/admin-table.d.ts.map +1 -1
- package/build/components/admin-table.js +137 -25
- package/build/components/admin-table.js.map +1 -1
- package/build/components/admin-text.d.ts.map +1 -1
- package/build/components/admin-text.js +2 -1
- package/build/components/admin-text.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -0
- package/build-web/AdminPanelComponents.js +2 -2
- package/build-web/AdminPanelComponents.js.LICENSE.txt +14 -0
- package/build-web/AdminPanelWeb_AppAPI.js +804 -39
- package/docker-compose.yaml +0 -1
- package/env-example +4 -2
- package/package.json +14 -6
- package/src/AppAPI.ts +54 -57
- package/src/WebExport.ts +8 -3
- package/src/components/admin-edit.ts +59 -30
- package/src/components/admin-table-field.ts +1 -1
- package/src/components/admin-table.ts +212 -20
- package/src/components/admin-text.ts +2 -1
- package/start.sh +1 -1
- package/stop.sh +1 -1
- package/webpack-api.config.js +8 -2
- package/webpack.config.cjs +7 -1
- package/dbstart.sh +0 -14
- package/dbstop.sh +0 -3
|
@@ -2,6 +2,51 @@ import { HotStaq, Hot, HotAPI, HotComponent, HotComponentOutput } from "hotstaq"
|
|
|
2
2
|
import { AdminTableField } from "./admin-table-field";
|
|
3
3
|
import { AdminEdit } from "./admin-edit";
|
|
4
4
|
|
|
5
|
+
import DataTable, { Api, ConfigColumns } from "datatables.net";
|
|
6
|
+
import dt5 from 'datatables.net-bs5';
|
|
7
|
+
import dtc from 'datatables.net-colreorder-bs5';
|
|
8
|
+
import dts from 'datatables.net-scroller-bs5';
|
|
9
|
+
import dtsb from 'datatables.net-searchbuilder-bs5';
|
|
10
|
+
import dtsel from 'datatables.net-select-bs5';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The properties for the list search.
|
|
14
|
+
*/
|
|
15
|
+
export interface IListSearchProperties
|
|
16
|
+
{
|
|
17
|
+
/**
|
|
18
|
+
* The search.
|
|
19
|
+
*/
|
|
20
|
+
search?: string;
|
|
21
|
+
/**
|
|
22
|
+
* The start index.
|
|
23
|
+
*/
|
|
24
|
+
offset?: number;
|
|
25
|
+
/**
|
|
26
|
+
* The length.
|
|
27
|
+
*/
|
|
28
|
+
limit?: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The API response that is expected to be returned.
|
|
33
|
+
*/
|
|
34
|
+
export interface IAPIResponse
|
|
35
|
+
{
|
|
36
|
+
/**
|
|
37
|
+
* The length of the data.
|
|
38
|
+
*/
|
|
39
|
+
length: number;
|
|
40
|
+
/**
|
|
41
|
+
* The data to return.
|
|
42
|
+
*/
|
|
43
|
+
data: any[];
|
|
44
|
+
/**
|
|
45
|
+
* The error message, if any.
|
|
46
|
+
*/
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
5
50
|
export class AdminTable extends HotComponent
|
|
6
51
|
{
|
|
7
52
|
/**
|
|
@@ -58,7 +103,7 @@ export class AdminTable extends HotComponent
|
|
|
58
103
|
/**
|
|
59
104
|
* The list function to execute to retrieve data.
|
|
60
105
|
*/
|
|
61
|
-
onlist: () => Promise<
|
|
106
|
+
onlist: (search: IListSearchProperties) => Promise<IAPIResponse>;
|
|
62
107
|
/**
|
|
63
108
|
* The list url to use for this table. Hot.Data.AdminPanel.listUrl will not be used in this case.
|
|
64
109
|
*/
|
|
@@ -81,6 +126,14 @@ export class AdminTable extends HotComponent
|
|
|
81
126
|
* The attached edit form, if any.
|
|
82
127
|
*/
|
|
83
128
|
attachedEdit: AdminEdit;
|
|
129
|
+
/**
|
|
130
|
+
* The associated DataTable.
|
|
131
|
+
*/
|
|
132
|
+
dataTable: DataTable<Api>;
|
|
133
|
+
/**
|
|
134
|
+
* Indicates if the list is refreshing.
|
|
135
|
+
*/
|
|
136
|
+
isListRefreshing: boolean;
|
|
84
137
|
|
|
85
138
|
constructor (copy: HotComponent | HotStaq, api: HotAPI)
|
|
86
139
|
{
|
|
@@ -103,6 +156,8 @@ export class AdminTable extends HotComponent
|
|
|
103
156
|
this.onselectedrow = null;
|
|
104
157
|
this.attachedEdit = null;
|
|
105
158
|
this.selected = -1;
|
|
159
|
+
this.dataTable = null;
|
|
160
|
+
this.isListRefreshing = false;
|
|
106
161
|
}
|
|
107
162
|
|
|
108
163
|
/**
|
|
@@ -195,7 +250,7 @@ export class AdminTable extends HotComponent
|
|
|
195
250
|
if (this.singleclickedit === true)
|
|
196
251
|
{
|
|
197
252
|
if (this.attachedEdit != null)
|
|
198
|
-
await this.attachedEdit.editClicked ();
|
|
253
|
+
await this.attachedEdit.editClicked (this);
|
|
199
254
|
}
|
|
200
255
|
|
|
201
256
|
/*this.selectedRows = [];
|
|
@@ -232,7 +287,10 @@ export class AdminTable extends HotComponent
|
|
|
232
287
|
if (index < 0)
|
|
233
288
|
return (null);
|
|
234
289
|
|
|
235
|
-
|
|
290
|
+
// @ts-ignore
|
|
291
|
+
const result = this.dataTable.row(index).data();
|
|
292
|
+
|
|
293
|
+
return (result);
|
|
236
294
|
}
|
|
237
295
|
|
|
238
296
|
/**
|
|
@@ -305,15 +363,16 @@ export class AdminTable extends HotComponent
|
|
|
305
363
|
|
|
306
364
|
let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
307
365
|
let index: number = this.rowElements.length;
|
|
308
|
-
let rowStr = `<tr onclick = "this.parentNode.parentNode.parentNode.parentNode.hotComponent.selectRow (this, ${index});">`;
|
|
366
|
+
//let rowStr = `<tr onclick = "this.parentNode.parentNode.parentNode.parentNode.hotComponent.selectRow (this, ${index});">`;
|
|
309
367
|
|
|
310
368
|
if (typeof (this.checkbox) === "string")
|
|
311
369
|
this.checkbox = HotStaq.parseBoolean (this.checkbox);
|
|
312
370
|
|
|
313
|
-
if (this.checkbox === true)
|
|
371
|
+
/*if (this.checkbox === true)
|
|
314
372
|
rowStr += `<td><input type = "checkbox" /></td>`;
|
|
315
373
|
else
|
|
316
|
-
rowStr += `<td></td
|
|
374
|
+
rowStr += `<td></td>`;*/
|
|
375
|
+
let rowsFields: any[] = [];
|
|
317
376
|
|
|
318
377
|
for (let iIdx = 0; iIdx < this.headers.indicies.length; iIdx++)
|
|
319
378
|
{
|
|
@@ -343,6 +402,8 @@ export class AdminTable extends HotComponent
|
|
|
343
402
|
value = tempValue;
|
|
344
403
|
}
|
|
345
404
|
|
|
405
|
+
let rowObj = null;
|
|
406
|
+
|
|
346
407
|
if (this.headers.elements[key] != null)
|
|
347
408
|
{
|
|
348
409
|
// @ts-ignore - @fixme I messed this up, will fix.
|
|
@@ -373,26 +434,40 @@ export class AdminTable extends HotComponent
|
|
|
373
434
|
|
|
374
435
|
defaultOutput = false;
|
|
375
436
|
const newOutput: string = orgField.onoutput (index, value);
|
|
376
|
-
rowStr += newOutput;
|
|
437
|
+
//rowStr += newOutput;
|
|
438
|
+
rowObj = { index: index, value: newOutput };
|
|
377
439
|
}
|
|
378
440
|
}
|
|
379
441
|
|
|
380
442
|
if (defaultOutput === true)
|
|
381
|
-
|
|
443
|
+
{
|
|
444
|
+
//rowStr += `<td data-index = "${index}">${value}</td>`;
|
|
445
|
+
rowObj = value;
|
|
446
|
+
}
|
|
382
447
|
}
|
|
383
448
|
}
|
|
449
|
+
|
|
450
|
+
rowsFields.push (rowObj);
|
|
384
451
|
}
|
|
385
452
|
|
|
386
|
-
|
|
453
|
+
if (this.rows == null)
|
|
454
|
+
this.rows = [];
|
|
455
|
+
|
|
456
|
+
// @ts-ignore
|
|
457
|
+
//this.dataTable.row.add (rowsFields);
|
|
458
|
+
//this.rows.push (rowsFields);
|
|
459
|
+
/*rowStr += "</tr>";
|
|
387
460
|
|
|
388
461
|
let newObj = HotStaq.addHtml (tbody, rowStr);
|
|
389
462
|
|
|
390
463
|
this.rowElements.push ({
|
|
391
464
|
fields: fields,
|
|
392
465
|
element: (<HTMLElement>newObj)
|
|
393
|
-
})
|
|
466
|
+
});*/
|
|
394
467
|
}
|
|
395
468
|
|
|
469
|
+
rows: any[];
|
|
470
|
+
|
|
396
471
|
/**
|
|
397
472
|
* Clear the list of rows.
|
|
398
473
|
*/
|
|
@@ -400,22 +475,50 @@ export class AdminTable extends HotComponent
|
|
|
400
475
|
{
|
|
401
476
|
this.rowElements = [];
|
|
402
477
|
|
|
403
|
-
let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
478
|
+
/*let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
404
479
|
|
|
405
|
-
tbody.innerHTML = ""
|
|
480
|
+
tbody.innerHTML = "";*/
|
|
481
|
+
// @ts-ignore
|
|
482
|
+
this.dataTable.clear ();
|
|
406
483
|
}
|
|
407
484
|
|
|
408
485
|
/**
|
|
409
486
|
* Refresh the list.
|
|
487
|
+
*
|
|
488
|
+
* @returns The total number of rows available in the list.
|
|
410
489
|
*/
|
|
411
|
-
async refreshList (list:
|
|
490
|
+
async refreshList (list: IAPIResponse = null): Promise<IAPIResponse>
|
|
412
491
|
{
|
|
492
|
+
this.isListRefreshing = true;
|
|
493
|
+
|
|
494
|
+
let search: IListSearchProperties = {
|
|
495
|
+
search: "",
|
|
496
|
+
offset: 0,
|
|
497
|
+
limit: 10
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
if (this.dataTable != null)
|
|
501
|
+
{
|
|
502
|
+
// @ts-ignore
|
|
503
|
+
const searchStr: string = this.dataTable.search ();
|
|
504
|
+
// @ts-ignore
|
|
505
|
+
const info = this.dataTable.page.info ();
|
|
506
|
+
|
|
507
|
+
search = {
|
|
508
|
+
search: searchStr || "",
|
|
509
|
+
// @ts-ignore
|
|
510
|
+
offset: info.start || 0,
|
|
511
|
+
// @ts-ignore
|
|
512
|
+
limit: info.length || 10
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
|
|
413
516
|
if (this.onlist != null)
|
|
414
517
|
{
|
|
415
518
|
if (typeof (this.onlist) === "string")
|
|
416
|
-
this.onlist = (<() => Promise<
|
|
519
|
+
this.onlist = (<(search: IListSearchProperties) => Promise<IAPIResponse>>new Function (this.onlist));
|
|
417
520
|
|
|
418
|
-
list = await this.onlist ();
|
|
521
|
+
list = await this.onlist (search);
|
|
419
522
|
}
|
|
420
523
|
else
|
|
421
524
|
{
|
|
@@ -427,7 +530,8 @@ export class AdminTable extends HotComponent
|
|
|
427
530
|
if (listUrl !== "")
|
|
428
531
|
{
|
|
429
532
|
list = await Hot.jsonRequest (listUrl, {
|
|
430
|
-
schema: this.schema
|
|
533
|
+
schema: this.schema,
|
|
534
|
+
search: search
|
|
431
535
|
});
|
|
432
536
|
}
|
|
433
537
|
}
|
|
@@ -436,13 +540,36 @@ export class AdminTable extends HotComponent
|
|
|
436
540
|
|
|
437
541
|
if (list != null)
|
|
438
542
|
{
|
|
439
|
-
|
|
543
|
+
if (list.error != null)
|
|
440
544
|
{
|
|
441
|
-
|
|
545
|
+
console.error (`List error: ${list.error}`);
|
|
546
|
+
this.isListRefreshing = false;
|
|
442
547
|
|
|
443
|
-
|
|
548
|
+
return (null);
|
|
444
549
|
}
|
|
550
|
+
|
|
551
|
+
/*for (let iIdx = 0; iIdx < list.data.length; iIdx++)
|
|
552
|
+
{
|
|
553
|
+
let fields = list.data[iIdx];
|
|
554
|
+
|
|
555
|
+
this.addRow (fields);
|
|
556
|
+
}*/
|
|
445
557
|
}
|
|
558
|
+
|
|
559
|
+
let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
560
|
+
// @ts-ignore
|
|
561
|
+
tbody.hotComponent = this;
|
|
562
|
+
$(tbody).on ('click', 'tr', function ()
|
|
563
|
+
{
|
|
564
|
+
const hotComponent: AdminTable = this.parentNode.hotComponent;
|
|
565
|
+
// @ts-ignore
|
|
566
|
+
const index = hotComponent.dataTable.row (this).index ();
|
|
567
|
+
hotComponent.selectRow (this, index);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
this.isListRefreshing = false;
|
|
571
|
+
|
|
572
|
+
return (list);
|
|
446
573
|
}
|
|
447
574
|
|
|
448
575
|
/**
|
|
@@ -452,7 +579,72 @@ export class AdminTable extends HotComponent
|
|
|
452
579
|
{
|
|
453
580
|
setTimeout (async () =>
|
|
454
581
|
{
|
|
455
|
-
|
|
582
|
+
|
|
583
|
+
const table = $(htmlElement).find("table");
|
|
584
|
+
|
|
585
|
+
let columns: ConfigColumns[] = [];
|
|
586
|
+
$(table).find ("thead th").each (function ()
|
|
587
|
+
{
|
|
588
|
+
const text = $(this).text ();
|
|
589
|
+
const data = $(this).data ("field");
|
|
590
|
+
let dataType = $(this).data ("field-type");
|
|
591
|
+
|
|
592
|
+
if ((text == null) || (text === ""))
|
|
593
|
+
return;
|
|
594
|
+
|
|
595
|
+
if ((data == null) || (data === ""))
|
|
596
|
+
return;
|
|
597
|
+
|
|
598
|
+
if (dataType === "text")
|
|
599
|
+
dataType = "string";
|
|
600
|
+
|
|
601
|
+
columns.push({
|
|
602
|
+
title: text,
|
|
603
|
+
data: data
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
$(table).find ("thead").remove ();
|
|
608
|
+
|
|
609
|
+
// @ts-ignore
|
|
610
|
+
this.dataTable = new DataTable (table[0], {
|
|
611
|
+
processing: true,
|
|
612
|
+
serverSide: true,
|
|
613
|
+
colReorder: true,
|
|
614
|
+
scroller: true,
|
|
615
|
+
select: true,
|
|
616
|
+
dom: 'Qlfrtip',
|
|
617
|
+
columns: columns,
|
|
618
|
+
data: [],
|
|
619
|
+
ajax: async (data, callback, settings) =>
|
|
620
|
+
{
|
|
621
|
+
if (this.isListRefreshing === true)
|
|
622
|
+
return;
|
|
623
|
+
|
|
624
|
+
const currentData = await this.refreshList ();
|
|
625
|
+
const callbackObj: any = {
|
|
626
|
+
data: [],
|
|
627
|
+
recordsTotal: 0,
|
|
628
|
+
recordsFiltered: 0
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
if (! (currentData instanceof Array))
|
|
632
|
+
{
|
|
633
|
+
if (currentData.length != null)
|
|
634
|
+
{
|
|
635
|
+
callbackObj.recordsTotal = currentData.length;
|
|
636
|
+
callbackObj.recordsFiltered = currentData.length;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (currentData.data != null)
|
|
640
|
+
callbackObj.data = currentData.data;
|
|
641
|
+
}
|
|
642
|
+
else
|
|
643
|
+
callbackObj.data = currentData;
|
|
644
|
+
|
|
645
|
+
callback (callbackObj);
|
|
646
|
+
}
|
|
647
|
+
});
|
|
456
648
|
}, 50);
|
|
457
649
|
|
|
458
650
|
return (null);
|
|
@@ -50,13 +50,14 @@ export class AdminText extends HotComponent
|
|
|
50
50
|
|
|
51
51
|
const field = this.htmlElements[0].getAttribute ("hot-field");
|
|
52
52
|
let field_type = this.htmlElements[0].getAttribute ("hot-field-type");
|
|
53
|
+
let htmlType = this.htmlElements[0].getAttribute ("type") || "text";
|
|
53
54
|
|
|
54
55
|
if (field_type == null)
|
|
55
56
|
field_type = "text";
|
|
56
57
|
|
|
57
58
|
return (`<div>
|
|
58
59
|
<label class="form-label">${this.inner}</label>
|
|
59
|
-
<input class="${this.css_class}" type = "
|
|
60
|
+
<input class="${this.css_class}" type = "${htmlType}" hot-field = "${field}" hot-field-type = "${field_type}" value = "${value}" />
|
|
60
61
|
</div>`);
|
|
61
62
|
}
|
|
62
63
|
}
|
package/start.sh
CHANGED
package/stop.sh
CHANGED
package/webpack-api.config.js
CHANGED
|
@@ -46,7 +46,13 @@ module.exports = {
|
|
|
46
46
|
Utils: "empty"
|
|
47
47
|
},
|
|
48
48
|
externals: {
|
|
49
|
-
hotstaq: "HotStaqWeb"
|
|
49
|
+
hotstaq: "HotStaqWeb",
|
|
50
|
+
'datatables.net': 'DataTable',
|
|
51
|
+
'datatables.net-bs5': 'dt5',
|
|
52
|
+
'datatables.net-colreorder-bs5': 'dtc',
|
|
53
|
+
'datatables.net-scroller-bs5': 'dts',
|
|
54
|
+
'datatables.net-searchbuilder-bs5': 'dtsb',
|
|
55
|
+
'datatables.net-select-bs5': 'dtsel'
|
|
50
56
|
},
|
|
51
57
|
output: {
|
|
52
58
|
filename: "admin-panel.js",
|
|
@@ -54,4 +60,4 @@ module.exports = {
|
|
|
54
60
|
library: "admin-panelWeb",
|
|
55
61
|
libraryTarget: "umd"
|
|
56
62
|
}
|
|
57
|
-
};
|
|
63
|
+
};
|
package/webpack.config.cjs
CHANGED
|
@@ -75,7 +75,13 @@ module.exports = {
|
|
|
75
75
|
"node:stream": "{}",
|
|
76
76
|
"node:url": "{}",
|
|
77
77
|
"node:util": "{}",
|
|
78
|
-
"node:zlib": "{}"
|
|
78
|
+
"node:zlib": "{}",
|
|
79
|
+
'datatables.net': 'DataTable',
|
|
80
|
+
'datatables.net-bs5': 'dt5',
|
|
81
|
+
'datatables.net-colreorder-bs5': 'dtc',
|
|
82
|
+
'datatables.net-scroller-bs5': 'dts',
|
|
83
|
+
'datatables.net-searchbuilder-bs5': 'dtsb',
|
|
84
|
+
'datatables.net-select-bs5': 'dtsel'
|
|
79
85
|
},
|
|
80
86
|
output: {
|
|
81
87
|
filename: "AdminPanelComponents.js",
|
package/dbstart.sh
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
RUN_DAEMON="-d"
|
|
4
|
-
MARIADB_DB_PORT=3320
|
|
5
|
-
|
|
6
|
-
RUN_DAEMON_OPT=$1
|
|
7
|
-
|
|
8
|
-
if [ "$RUN_DAEMON_OPT" == "no-daemon" ]; then
|
|
9
|
-
RUN_DAEMON=""
|
|
10
|
-
fi
|
|
11
|
-
|
|
12
|
-
docker rm -f mariadb-staqapp-tests 2>/dev/null || true
|
|
13
|
-
|
|
14
|
-
docker run ${RUN_DAEMON} --name="mariadb-staqapp-tests" -p ${MARIADB_DB_PORT}:3306 -e MYSQL_ROOT_PASSWORD=cdO1KjwiC8ksOqCV1s0 -e MYSQL_DATABASE=staqapp -e MYSQL_USER=5NKVBAt7OrzrumQyQVs -e MYSQL_PASSWORD=1BBrZbKYRUM7oiMA5oY mariadb:10.6
|
package/dbstop.sh
DELETED