@hotstaq/admin-panel 0.3.13 → 0.3.15
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/build/components/admin-dropdown.d.ts.map +1 -1
- package/build/components/admin-dropdown.js +9 -1
- package/build/components/admin-dropdown.js.map +1 -1
- package/build/components/admin-edit.d.ts +2 -2
- package/build/components/admin-edit.d.ts.map +1 -1
- package/build/components/admin-edit.js +15 -6
- package/build/components/admin-edit.js.map +1 -1
- package/build/components/admin-table.d.ts +21 -0
- package/build/components/admin-table.d.ts.map +1 -1
- package/build/components/admin-table.js +89 -37
- package/build/components/admin-table.js.map +1 -1
- package/build-web/AdminPanelComponents.js +2 -2
- package/package.json +1 -1
- package/src/components/admin-dropdown.ts +12 -1
- package/src/components/admin-edit.ts +20 -6
- package/src/components/admin-table.ts +139 -46
|
@@ -63,7 +63,18 @@ export class AdminDropdown extends HotComponent
|
|
|
63
63
|
let value: string = result.value;
|
|
64
64
|
let text: string = result.text;
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
const $template = $(`<li><a class="dropdown-item" href="" data-value="" onclick=""></a></li>`);
|
|
67
|
+
|
|
68
|
+
const $a = $template.find("a");
|
|
69
|
+
$a.attr("href", url);
|
|
70
|
+
$a.attr("data-value", value);
|
|
71
|
+
$a.text(text);
|
|
72
|
+
|
|
73
|
+
$a.removeAttr("onclick").on("click", () => {
|
|
74
|
+
this.selected(iIdx);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
searchResultsDiv.append($template);
|
|
67
78
|
}
|
|
68
79
|
});
|
|
69
80
|
}
|
|
@@ -193,7 +193,7 @@ export class AdminEdit extends HotComponent
|
|
|
193
193
|
* The event that can be called when the edit button is clicked.
|
|
194
194
|
* This is called before the edit modal opens.
|
|
195
195
|
*/
|
|
196
|
-
onEditClicked: () => Promise<boolean> = null;
|
|
196
|
+
onEditClicked: (clickedTable?: string, selectedFields?: any[]) => Promise<boolean> = null;
|
|
197
197
|
|
|
198
198
|
/**
|
|
199
199
|
* Get the attached lists.
|
|
@@ -236,11 +236,11 @@ export class AdminEdit extends HotComponent
|
|
|
236
236
|
/**
|
|
237
237
|
* Executes when the edit button is clicked.
|
|
238
238
|
*/
|
|
239
|
-
async editClicked (selectedFields: any[] = []): Promise<void>
|
|
239
|
+
async editClicked (clickedTable: string = null, selectedFields: any[] = []): Promise<void>
|
|
240
240
|
{
|
|
241
241
|
if (this.onEditClicked != null)
|
|
242
242
|
{
|
|
243
|
-
let result = await this.onEditClicked ();
|
|
243
|
+
let result = await this.onEditClicked (clickedTable, selectedFields);
|
|
244
244
|
|
|
245
245
|
if (result === false)
|
|
246
246
|
return;
|
|
@@ -259,6 +259,12 @@ export class AdminEdit extends HotComponent
|
|
|
259
259
|
let attachedList = attachedLists[iIdx];
|
|
260
260
|
let table: AdminTable = (<AdminTable>attachedList);
|
|
261
261
|
|
|
262
|
+
if (clickedTable != null)
|
|
263
|
+
{
|
|
264
|
+
if (table.name !== clickedTable)
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
|
|
262
268
|
table.attachedEdit = this;
|
|
263
269
|
let selectedField = table.getSelected ();
|
|
264
270
|
|
|
@@ -419,7 +425,12 @@ export class AdminEdit extends HotComponent
|
|
|
419
425
|
}
|
|
420
426
|
|
|
421
427
|
if (hotComponent != null)
|
|
422
|
-
|
|
428
|
+
{
|
|
429
|
+
const currentData = await hotComponent.refreshList ();
|
|
430
|
+
const preparedData = hotComponent.prepareData (currentData);
|
|
431
|
+
|
|
432
|
+
hotComponent.tableCallback (preparedData);
|
|
433
|
+
}
|
|
423
434
|
}
|
|
424
435
|
}
|
|
425
436
|
|
|
@@ -544,7 +555,10 @@ export class AdminEdit extends HotComponent
|
|
|
544
555
|
|
|
545
556
|
table.attachedEdit = this;
|
|
546
557
|
|
|
547
|
-
await table.refreshList ();
|
|
558
|
+
const currentData = await table.refreshList ();
|
|
559
|
+
const preparedData = table.prepareData (currentData);
|
|
560
|
+
|
|
561
|
+
table.tableCallback (preparedData);
|
|
548
562
|
}
|
|
549
563
|
}
|
|
550
564
|
|
|
@@ -628,7 +642,7 @@ export class AdminEdit extends HotComponent
|
|
|
628
642
|
if (this.edit_place_here !== "")
|
|
629
643
|
{
|
|
630
644
|
outputObj.push ({
|
|
631
|
-
html: `<button id = "${this.modalId}-edit-btn" type="button" class="btn btn-sm btn-outline-secondary" onclick = "this.editClicked ();">${this.edit_text}</button>`,
|
|
645
|
+
html: `<button id = "${this.modalId}-edit-btn" type="button" class="btn btn-sm btn-outline-secondary" onclick = "this.editClicked ('${this.modalId}');">${this.edit_text}</button>`,
|
|
632
646
|
documentSelector: `hot-place-here[name="${this.edit_place_here}"]`
|
|
633
647
|
});
|
|
634
648
|
}
|
|
@@ -45,6 +45,10 @@ export interface IAPIResponse
|
|
|
45
45
|
* The error message, if any.
|
|
46
46
|
*/
|
|
47
47
|
error?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Can enable/disable sanitization of the returning data.
|
|
50
|
+
*/
|
|
51
|
+
hotSanitize?: boolean;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
export class AdminTable extends HotComponent
|
|
@@ -90,6 +94,14 @@ export class AdminTable extends HotComponent
|
|
|
90
94
|
* }
|
|
91
95
|
*/
|
|
92
96
|
rowElements: { fields: any[]; element: HTMLElement; }[] = [];
|
|
97
|
+
/**
|
|
98
|
+
* The table callback for when updating data.
|
|
99
|
+
*/
|
|
100
|
+
tableCallback: ((data: any) => void);
|
|
101
|
+
/**
|
|
102
|
+
* The table data for when updating data.
|
|
103
|
+
*/
|
|
104
|
+
protected tableData: any;
|
|
93
105
|
/**
|
|
94
106
|
* The selected row indicies. Each index maps to the rowElements array.
|
|
95
107
|
*
|
|
@@ -148,6 +160,8 @@ export class AdminTable extends HotComponent
|
|
|
148
160
|
indicies: []
|
|
149
161
|
};
|
|
150
162
|
this.rowElements = [];
|
|
163
|
+
this.tableCallback = null;
|
|
164
|
+
this.tableData = null;
|
|
151
165
|
//this.selectedRows = [];
|
|
152
166
|
this.onlist = null;
|
|
153
167
|
this.listurl = "";
|
|
@@ -234,7 +248,7 @@ export class AdminTable extends HotComponent
|
|
|
234
248
|
if (this.singleclickedit === true)
|
|
235
249
|
{
|
|
236
250
|
if (this.attachedEdit != null)
|
|
237
|
-
await this.attachedEdit.editClicked ();
|
|
251
|
+
await this.attachedEdit.editClicked (this.name);
|
|
238
252
|
}
|
|
239
253
|
|
|
240
254
|
if (this.onselectedrow != null)
|
|
@@ -243,6 +257,10 @@ export class AdminTable extends HotComponent
|
|
|
243
257
|
this.onselectedrow = (<(rowIndex: number, item: any[]) => Promise<boolean>>new Function (this.onselectedrow));
|
|
244
258
|
|
|
245
259
|
let item: any[] = this.getSelected ();
|
|
260
|
+
|
|
261
|
+
if (item == null)
|
|
262
|
+
return;
|
|
263
|
+
|
|
246
264
|
let result = await this.onselectedrow (rowIndex, item);
|
|
247
265
|
|
|
248
266
|
if (result === false)
|
|
@@ -454,7 +472,7 @@ export class AdminTable extends HotComponent
|
|
|
454
472
|
//this.rows.push (rowsFields);
|
|
455
473
|
/*rowStr += "</tr>";
|
|
456
474
|
|
|
457
|
-
let newObj = HotStaq.
|
|
475
|
+
let newObj = HotStaq.addHtmlUnsafe (tbody, rowStr);
|
|
458
476
|
|
|
459
477
|
this.rowElements.push ({
|
|
460
478
|
fields: fields,
|
|
@@ -548,12 +566,51 @@ export class AdminTable extends HotComponent
|
|
|
548
566
|
return (null);
|
|
549
567
|
}
|
|
550
568
|
|
|
551
|
-
|
|
569
|
+
if (list.data == null)
|
|
570
|
+
throw new Error (`Returning list data to "${this.name}" component has a null data field. API response does not match the "IAPIResponse" schema.`);
|
|
571
|
+
|
|
572
|
+
for (let iIdx = 0; iIdx < list.data.length; iIdx++)
|
|
552
573
|
{
|
|
553
|
-
let
|
|
574
|
+
let elm = list.data[iIdx];
|
|
575
|
+
|
|
576
|
+
for (let key in elm)
|
|
577
|
+
{
|
|
578
|
+
let value = elm[key];
|
|
579
|
+
let fieldType: string = this.getFieldType (key);
|
|
554
580
|
|
|
555
|
-
|
|
556
|
-
|
|
581
|
+
if (fieldType == null)
|
|
582
|
+
fieldType = "text";
|
|
583
|
+
|
|
584
|
+
if (fieldType !== "remove")
|
|
585
|
+
{
|
|
586
|
+
const orgField = this.headers.fields[key];
|
|
587
|
+
let defaultOutput: boolean = true;
|
|
588
|
+
|
|
589
|
+
if (orgField != null)
|
|
590
|
+
{
|
|
591
|
+
if (orgField.oninput != null)
|
|
592
|
+
{
|
|
593
|
+
if (typeof (orgField.oninput) === "string")
|
|
594
|
+
this.headers.fields[key].oninput = (<(item: any) => any>new Function (orgField.oninput));
|
|
595
|
+
|
|
596
|
+
value = orgField.oninput (value);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (orgField.onoutput != null)
|
|
600
|
+
{
|
|
601
|
+
if (typeof (orgField.onoutput) === "string")
|
|
602
|
+
this.headers.fields[key].onoutput = (<(index: number, value: string) => string>new Function (orgField.onoutput));
|
|
603
|
+
|
|
604
|
+
defaultOutput = false;
|
|
605
|
+
const newOutput: string = orgField.onoutput (iIdx, value);
|
|
606
|
+
value = newOutput;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
list.data[iIdx][key] = value;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
557
614
|
}
|
|
558
615
|
|
|
559
616
|
let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
@@ -564,7 +621,17 @@ export class AdminTable extends HotComponent
|
|
|
564
621
|
const hotComponent: AdminTable = this.parentNode.hotComponent;
|
|
565
622
|
// @ts-ignore
|
|
566
623
|
const index = hotComponent.dataTable.row (this).index ();
|
|
567
|
-
|
|
624
|
+
|
|
625
|
+
if (index != null)
|
|
626
|
+
hotComponent.selectRow (this, index);
|
|
627
|
+
else
|
|
628
|
+
{
|
|
629
|
+
if (hotComponent.attachedEdit != null)
|
|
630
|
+
{
|
|
631
|
+
if (hotComponent.attachedEdit.addClicked != null)
|
|
632
|
+
hotComponent.attachedEdit.addClicked ();
|
|
633
|
+
}
|
|
634
|
+
}
|
|
568
635
|
});
|
|
569
636
|
|
|
570
637
|
this.isListRefreshing = false;
|
|
@@ -572,6 +639,62 @@ export class AdminTable extends HotComponent
|
|
|
572
639
|
return (list);
|
|
573
640
|
}
|
|
574
641
|
|
|
642
|
+
/**
|
|
643
|
+
* Prepare data.
|
|
644
|
+
*/
|
|
645
|
+
prepareData (currentData: any[] | IAPIResponse): {
|
|
646
|
+
draw: any;
|
|
647
|
+
data: any[];
|
|
648
|
+
recordsTotal: number;
|
|
649
|
+
recordsFiltered: number;
|
|
650
|
+
}
|
|
651
|
+
{
|
|
652
|
+
const callbackObj: any = {
|
|
653
|
+
draw: this.tableData,
|
|
654
|
+
data: [],
|
|
655
|
+
recordsTotal: 0,
|
|
656
|
+
recordsFiltered: 0
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
if (currentData != null)
|
|
660
|
+
{
|
|
661
|
+
if (! (currentData instanceof Array))
|
|
662
|
+
{
|
|
663
|
+
if (currentData.length != null)
|
|
664
|
+
{
|
|
665
|
+
callbackObj.recordsTotal = currentData.length;
|
|
666
|
+
callbackObj.recordsFiltered = currentData.length;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (currentData.data != null)
|
|
670
|
+
callbackObj.data = currentData.data;
|
|
671
|
+
}
|
|
672
|
+
else
|
|
673
|
+
{
|
|
674
|
+
callbackObj.data = currentData;
|
|
675
|
+
callbackObj.recordsTotal = currentData.length;
|
|
676
|
+
callbackObj.recordsFiltered = currentData.length;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
let sanitize = true;
|
|
680
|
+
|
|
681
|
+
if (callbackObj.data.hotSanitize != null)
|
|
682
|
+
sanitize = callbackObj.data.hotSanitize;
|
|
683
|
+
|
|
684
|
+
for (let iIdx = 0; iIdx < callbackObj.data.length; iIdx++)
|
|
685
|
+
{
|
|
686
|
+
const row = callbackObj.data[iIdx];
|
|
687
|
+
|
|
688
|
+
if (sanitize === true)
|
|
689
|
+
callbackObj.data[iIdx] = HotStaq.sanitizeJSON (row);
|
|
690
|
+
else
|
|
691
|
+
callbackObj.data[iIdx] = row;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
return (callbackObj);
|
|
696
|
+
}
|
|
697
|
+
|
|
575
698
|
/**
|
|
576
699
|
* Get the list of data from the server.
|
|
577
700
|
*/
|
|
@@ -579,9 +702,10 @@ export class AdminTable extends HotComponent
|
|
|
579
702
|
{
|
|
580
703
|
setTimeout (async () =>
|
|
581
704
|
{
|
|
582
|
-
|
|
583
705
|
const table = $(htmlElement).find("table");
|
|
584
706
|
|
|
707
|
+
// The data stored in columns should be considered safe as it comes directly from
|
|
708
|
+
// the HTML after load.
|
|
585
709
|
let columns: ConfigColumns[] = [];
|
|
586
710
|
$(table).find ("thead th").each (function ()
|
|
587
711
|
{
|
|
@@ -621,48 +745,17 @@ export class AdminTable extends HotComponent
|
|
|
621
745
|
if (this.isListRefreshing === true)
|
|
622
746
|
return;
|
|
623
747
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
// @ts-ignore
|
|
628
|
-
draw: data.draw,
|
|
629
|
-
data: [],
|
|
630
|
-
recordsTotal: 0,
|
|
631
|
-
recordsFiltered: 0
|
|
632
|
-
};
|
|
748
|
+
this.tableCallback = callback;
|
|
749
|
+
// @ts-ignore
|
|
750
|
+
this.tableData = data.draw;
|
|
633
751
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
if (! (currentData instanceof Array))
|
|
637
|
-
{
|
|
638
|
-
if (currentData.length != null)
|
|
639
|
-
{
|
|
640
|
-
callbackObj.recordsTotal = currentData.length;
|
|
641
|
-
callbackObj.recordsFiltered = currentData.length;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
if (currentData.data != null)
|
|
645
|
-
callbackObj.data = currentData.data;
|
|
646
|
-
}
|
|
647
|
-
else
|
|
648
|
-
{
|
|
649
|
-
callbackObj.data = currentData;
|
|
650
|
-
callbackObj.recordsTotal = currentData.length;
|
|
651
|
-
callbackObj.recordsFiltered = currentData.length;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
for (let iIdx = 0; iIdx < currentData.data.length; iIdx++)
|
|
655
|
-
{
|
|
656
|
-
const row = currentData.data[iIdx];
|
|
657
|
-
|
|
658
|
-
currentData.data[iIdx] = HotStaq.sanitizeJSON (row);
|
|
659
|
-
}
|
|
660
|
-
}
|
|
752
|
+
let currentData = await this.refreshList ();
|
|
753
|
+
const preparedData = this.prepareData (currentData);
|
|
661
754
|
|
|
662
|
-
|
|
755
|
+
this.tableCallback (preparedData);
|
|
663
756
|
}
|
|
664
757
|
});
|
|
665
|
-
}, 50);
|
|
758
|
+
}, 50); /// @todo Fix this stupid hack. This should happen slightly after the document has been loaded.
|
|
666
759
|
|
|
667
760
|
return (null);
|
|
668
761
|
}
|