@hotstaq/admin-panel 0.3.13 → 0.3.14

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.
@@ -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
- searchResultsDiv.append ($(`<li><a class=\"dropdown-item\" href=\"${url}\" data-value = "${value}" onclick = \"this.parentNode.parentNode.parentNode.parentNode.hotComponent.selected (${iIdx});\">${text}</a></li>`));
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
- await hotComponent.refreshList ();
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.addHtml (tbody, rowStr);
475
+ let newObj = HotStaq.addHtmlUnsafe (tbody, rowStr);
458
476
 
459
477
  this.rowElements.push ({
460
478
  fields: fields,
@@ -548,12 +566,48 @@ export class AdminTable extends HotComponent
548
566
  return (null);
549
567
  }
550
568
 
551
- /*for (let iIdx = 0; iIdx < list.data.length; iIdx++)
569
+ for (let iIdx = 0; iIdx < list.data.length; iIdx++)
552
570
  {
553
- let fields = list.data[iIdx];
571
+ let elm = list.data[iIdx];
572
+
573
+ for (let key in elm)
574
+ {
575
+ let value = elm[key];
576
+ let fieldType: string = this.getFieldType (key);
577
+
578
+ if (fieldType == null)
579
+ fieldType = "text";
580
+
581
+ if (fieldType !== "remove")
582
+ {
583
+ const orgField = this.headers.fields[key];
584
+ let defaultOutput: boolean = true;
585
+
586
+ if (orgField != null)
587
+ {
588
+ if (orgField.oninput != null)
589
+ {
590
+ if (typeof (orgField.oninput) === "string")
591
+ this.headers.fields[key].oninput = (<(item: any) => any>new Function (orgField.oninput));
592
+
593
+ value = orgField.oninput (value);
594
+ }
554
595
 
555
- this.addRow (fields);
556
- }*/
596
+ if (orgField.onoutput != null)
597
+ {
598
+ if (typeof (orgField.onoutput) === "string")
599
+ this.headers.fields[key].onoutput = (<(index: number, value: string) => string>new Function (orgField.onoutput));
600
+
601
+ defaultOutput = false;
602
+ const newOutput: string = orgField.onoutput (iIdx, value);
603
+ value = newOutput;
604
+ }
605
+ }
606
+
607
+ list.data[iIdx][key] = value;
608
+ }
609
+ }
610
+ }
557
611
  }
558
612
 
559
613
  let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
@@ -564,7 +618,17 @@ export class AdminTable extends HotComponent
564
618
  const hotComponent: AdminTable = this.parentNode.hotComponent;
565
619
  // @ts-ignore
566
620
  const index = hotComponent.dataTable.row (this).index ();
567
- hotComponent.selectRow (this, index);
621
+
622
+ if (index != null)
623
+ hotComponent.selectRow (this, index);
624
+ else
625
+ {
626
+ if (hotComponent.attachedEdit != null)
627
+ {
628
+ if (hotComponent.attachedEdit.addClicked != null)
629
+ hotComponent.attachedEdit.addClicked ();
630
+ }
631
+ }
568
632
  });
569
633
 
570
634
  this.isListRefreshing = false;
@@ -572,6 +636,62 @@ export class AdminTable extends HotComponent
572
636
  return (list);
573
637
  }
574
638
 
639
+ /**
640
+ * Prepare data.
641
+ */
642
+ prepareData (currentData: any[] | IAPIResponse): {
643
+ draw: any;
644
+ data: any[];
645
+ recordsTotal: number;
646
+ recordsFiltered: number;
647
+ }
648
+ {
649
+ const callbackObj: any = {
650
+ draw: this.tableData,
651
+ data: [],
652
+ recordsTotal: 0,
653
+ recordsFiltered: 0
654
+ };
655
+
656
+ if (currentData != null)
657
+ {
658
+ if (! (currentData instanceof Array))
659
+ {
660
+ if (currentData.length != null)
661
+ {
662
+ callbackObj.recordsTotal = currentData.length;
663
+ callbackObj.recordsFiltered = currentData.length;
664
+ }
665
+
666
+ if (currentData.data != null)
667
+ callbackObj.data = currentData.data;
668
+ }
669
+ else
670
+ {
671
+ callbackObj.data = currentData;
672
+ callbackObj.recordsTotal = currentData.length;
673
+ callbackObj.recordsFiltered = currentData.length;
674
+ }
675
+
676
+ let sanitize = true;
677
+
678
+ if (callbackObj.data.hotSanitize != null)
679
+ sanitize = callbackObj.data.hotSanitize;
680
+
681
+ for (let iIdx = 0; iIdx < callbackObj.data.length; iIdx++)
682
+ {
683
+ const row = callbackObj.data[iIdx];
684
+
685
+ if (sanitize === true)
686
+ callbackObj.data[iIdx] = HotStaq.sanitizeJSON (row);
687
+ else
688
+ callbackObj.data[iIdx] = row;
689
+ }
690
+ }
691
+
692
+ return (callbackObj);
693
+ }
694
+
575
695
  /**
576
696
  * Get the list of data from the server.
577
697
  */
@@ -579,9 +699,10 @@ export class AdminTable extends HotComponent
579
699
  {
580
700
  setTimeout (async () =>
581
701
  {
582
-
583
702
  const table = $(htmlElement).find("table");
584
703
 
704
+ // The data stored in columns should be considered safe as it comes directly from
705
+ // the HTML after load.
585
706
  let columns: ConfigColumns[] = [];
586
707
  $(table).find ("thead th").each (function ()
587
708
  {
@@ -621,48 +742,17 @@ export class AdminTable extends HotComponent
621
742
  if (this.isListRefreshing === true)
622
743
  return;
623
744
 
624
- let currentData = await this.refreshList ();
625
-
626
- const callbackObj: any = {
627
- // @ts-ignore
628
- draw: data.draw,
629
- data: [],
630
- recordsTotal: 0,
631
- recordsFiltered: 0
632
- };
745
+ this.tableCallback = callback;
746
+ // @ts-ignore
747
+ this.tableData = data.draw;
633
748
 
634
- if (currentData != null)
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
- }
749
+ let currentData = await this.refreshList ();
750
+ const preparedData = this.prepareData (currentData);
661
751
 
662
- callback (callbackObj);
752
+ this.tableCallback (preparedData);
663
753
  }
664
754
  });
665
- }, 50);
755
+ }, 50); /// @todo Fix this stupid hack. This should happen slightly after the document has been loaded.
666
756
 
667
757
  return (null);
668
758
  }