@hotstaq/admin-panel 0.2.6 → 0.2.8
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/.vscode/launch.json +5 -4
- package/HotSite.json +2 -2
- package/build/{src/AppAPI.d.ts → AppAPI.d.ts} +0 -0
- package/build/AppAPI.d.ts.map +1 -0
- package/build/{src/AppAPI.js → AppAPI.js} +0 -0
- package/build/AppAPI.js.map +1 -0
- package/build/WebExport.d.ts +3 -0
- package/build/WebExport.d.ts.map +1 -0
- package/build/{src/WebExport.js → WebExport.js} +8 -22
- package/build/WebExport.js.map +1 -0
- package/build/{src/cli.d.ts → cli.d.ts} +0 -0
- package/build/cli.d.ts.map +1 -0
- package/build/{src/cli.js → cli.js} +0 -0
- package/build/cli.js.map +1 -0
- package/build/{src/components → components}/admin-button.d.ts +0 -0
- package/build/components/admin-button.d.ts.map +1 -0
- package/build/{src/components → components}/admin-button.js +0 -0
- package/build/components/admin-button.js.map +1 -0
- package/build/components/admin-checkbox.d.ts +1 -0
- package/build/components/admin-checkbox.d.ts.map +1 -0
- package/build/components/admin-checkbox.js +43 -0
- package/build/components/admin-checkbox.js.map +1 -0
- package/build/{src/components → components}/admin-dashboard.d.ts +0 -0
- package/build/components/admin-dashboard.d.ts.map +1 -0
- package/build/{src/components → components}/admin-dashboard.js +0 -0
- package/build/components/admin-dashboard.js.map +1 -0
- package/build/components/admin-edit.d.ts +87 -0
- package/build/components/admin-edit.d.ts.map +1 -0
- package/build/components/admin-edit.js +328 -0
- package/build/components/admin-edit.js.map +1 -0
- package/build/{src/components → components}/admin-table-field.d.ts +12 -0
- package/build/components/admin-table-field.d.ts.map +1 -0
- package/build/{src/components → components}/admin-table-field.js +17 -1
- package/build/components/admin-table-field.js.map +1 -0
- package/build/{src/components → components}/admin-table-row.d.ts +0 -0
- package/build/components/admin-table-row.d.ts.map +1 -0
- package/build/{src/components → components}/admin-table-row.js +2 -0
- package/build/components/admin-table-row.js.map +1 -0
- package/build/{src/components → components}/admin-table.d.ts +37 -1
- package/build/components/admin-table.d.ts.map +1 -0
- package/build/{src/components → components}/admin-table.js +125 -5
- package/build/components/admin-table.js.map +1 -0
- package/build/{src/components → components}/admin-text.d.ts +12 -0
- package/build/components/admin-text.d.ts.map +1 -0
- package/build/{src/components → components}/admin-text.js +6 -0
- package/build/components/admin-text.js.map +1 -0
- package/build/{src/WebExport.d.ts → index.d.ts} +2 -3
- package/build/index.d.ts.map +1 -0
- package/build/index.js +18 -0
- package/build/index.js.map +1 -0
- package/build-web/AdminPanelComponents.js +2 -2
- package/build-web/AdminPanelWeb_AppAPI.js +86 -0
- package/package.json +7 -6
- package/src/WebExport.ts +9 -24
- package/src/components/admin-checkbox.ts +52 -0
- package/src/components/admin-edit.ts +264 -12
- package/src/components/admin-table-field.ts +35 -1
- package/src/components/admin-table-row.ts +3 -0
- package/src/components/admin-table.ts +190 -5
- package/src/components/admin-text.ts +19 -0
- package/src/index.ts +17 -0
- package/tsconfig.json +1 -0
- package/webpack.config.cjs +2 -1
- package/build/scripts/watch.d.ts +0 -2
- package/build/scripts/watch.d.ts.map +0 -1
- package/build/scripts/watch.js +0 -127
- package/build/scripts/watch.js.map +0 -1
- package/build/src/AppAPI.d.ts.map +0 -1
- package/build/src/AppAPI.js.map +0 -1
- package/build/src/WebExport.d.ts.map +0 -1
- package/build/src/WebExport.js.map +0 -1
- package/build/src/cli.d.ts.map +0 -1
- package/build/src/cli.js.map +0 -1
- package/build/src/components/admin-button.d.ts.map +0 -1
- package/build/src/components/admin-button.js.map +0 -1
- package/build/src/components/admin-dashboard.d.ts.map +0 -1
- package/build/src/components/admin-dashboard.js.map +0 -1
- package/build/src/components/admin-edit.d.ts +0 -36
- package/build/src/components/admin-edit.d.ts.map +0 -1
- package/build/src/components/admin-edit.js +0 -120
- package/build/src/components/admin-edit.js.map +0 -1
- package/build/src/components/admin-table-field.d.ts.map +0 -1
- package/build/src/components/admin-table-field.js.map +0 -1
- package/build/src/components/admin-table-row.d.ts.map +0 -1
- package/build/src/components/admin-table-row.js.map +0 -1
- package/build/src/components/admin-table.d.ts.map +0 -1
- package/build/src/components/admin-table.js.map +0 -1
- package/build/src/components/admin-text.d.ts.map +0 -1
- package/build/src/components/admin-text.js.map +0 -1
- package/scripts/watch.ts +0 -59
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { HotStaq, Hot, HotAPI, HotComponent, HotComponentOutput } from "hotstaq";
|
|
2
2
|
|
|
3
|
+
import bootstrap from "bootstrap";
|
|
4
|
+
|
|
5
|
+
import { AdminTable } from "./admin-table";
|
|
6
|
+
|
|
3
7
|
export class AdminEdit extends HotComponent
|
|
4
8
|
{
|
|
5
9
|
/**
|
|
@@ -26,6 +30,25 @@ export class AdminEdit extends HotComponent
|
|
|
26
30
|
* The modal id.
|
|
27
31
|
*/
|
|
28
32
|
modalId: string;
|
|
33
|
+
/**
|
|
34
|
+
* The bootstrap modal instance.
|
|
35
|
+
*/
|
|
36
|
+
modal: bootstrap.Modal;
|
|
37
|
+
/**
|
|
38
|
+
* If set to true, this will close the modal when save is clicked.
|
|
39
|
+
*/
|
|
40
|
+
closeOnSave: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* The type of modal to open. Can be:
|
|
43
|
+
* * add
|
|
44
|
+
* * edit
|
|
45
|
+
* * remove
|
|
46
|
+
*/
|
|
47
|
+
protected modalType: string;
|
|
48
|
+
/**
|
|
49
|
+
* The selected fields.
|
|
50
|
+
*/
|
|
51
|
+
protected selectedFields: any[];
|
|
29
52
|
|
|
30
53
|
constructor (copy: HotComponent | HotStaq, api: HotAPI)
|
|
31
54
|
{
|
|
@@ -40,6 +63,165 @@ export class AdminEdit extends HotComponent
|
|
|
40
63
|
this.fieldElements = {};
|
|
41
64
|
|
|
42
65
|
this.modalId = "";
|
|
66
|
+
this.modal = null;
|
|
67
|
+
this.modalType = "add";
|
|
68
|
+
this.closeOnSave = true;
|
|
69
|
+
this.selectedFields = [];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The event that can be called when the add button is clicked.
|
|
74
|
+
* This is called before the add modal opens.
|
|
75
|
+
*/
|
|
76
|
+
onAddClicked: () => Promise<boolean> = null;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Executes when the add button is clicked.
|
|
80
|
+
*/
|
|
81
|
+
async addClicked (): Promise<void>
|
|
82
|
+
{
|
|
83
|
+
if (this.onAddClicked != null)
|
|
84
|
+
{
|
|
85
|
+
let result = await this.onAddClicked ();
|
|
86
|
+
|
|
87
|
+
if (result === false)
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
this.modalType = "add";
|
|
92
|
+
|
|
93
|
+
// Clear the values in each field.
|
|
94
|
+
for (let key in this.fieldElements)
|
|
95
|
+
{
|
|
96
|
+
let fieldElement = this.fieldElements[key];
|
|
97
|
+
|
|
98
|
+
fieldElement.value = "";
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.selectedFields = [];
|
|
102
|
+
|
|
103
|
+
bootstrap.Modal.getInstance (`#${this.modalId}`).show ();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The event that can be called when the edit button is clicked.
|
|
108
|
+
* This is called before the edit modal opens.
|
|
109
|
+
*/
|
|
110
|
+
onEditClicked: () => Promise<boolean> = null;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Executes when the edit button is clicked.
|
|
114
|
+
*/
|
|
115
|
+
async editClicked (): Promise<void>
|
|
116
|
+
{
|
|
117
|
+
if (this.onEditClicked != null)
|
|
118
|
+
{
|
|
119
|
+
let result = await this.onEditClicked ();
|
|
120
|
+
|
|
121
|
+
if (result === false)
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.modalType = "edit";
|
|
126
|
+
let attachedList = document.getElementById (this.attached_list);
|
|
127
|
+
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
let hotComponent: AdminTable = attachedList.hotComponent;
|
|
130
|
+
let selectedField = hotComponent.getSelected ();
|
|
131
|
+
|
|
132
|
+
if (selectedField != null)
|
|
133
|
+
{
|
|
134
|
+
for (let key in this.fieldElements)
|
|
135
|
+
{
|
|
136
|
+
let fieldElement = this.fieldElements[key];
|
|
137
|
+
|
|
138
|
+
if (fieldElement != null)
|
|
139
|
+
{
|
|
140
|
+
// @ts-ignore
|
|
141
|
+
let value = selectedField[key];
|
|
142
|
+
|
|
143
|
+
fieldElement.value = value;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.selectedFields = [selectedField];
|
|
148
|
+
|
|
149
|
+
bootstrap.Modal.getInstance (`#${this.modalId}`).show ();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The event that can be called when the remove button is clicked.
|
|
155
|
+
* This is called before the remove modal opens.
|
|
156
|
+
*/
|
|
157
|
+
onRemoveClicked: () => Promise<boolean> = null;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Executes when the remove button is clicked.
|
|
161
|
+
*/
|
|
162
|
+
async removeClicked (): Promise<void>
|
|
163
|
+
{
|
|
164
|
+
if (this.onRemoveClicked != null)
|
|
165
|
+
{
|
|
166
|
+
let result = await this.onRemoveClicked ();
|
|
167
|
+
|
|
168
|
+
if (result === false)
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this.modalType = "remove";
|
|
173
|
+
|
|
174
|
+
let attachedList = document.getElementById (this.attached_list);
|
|
175
|
+
// @ts-ignore
|
|
176
|
+
let hotComponent: AdminTable = attachedList.hotComponent;
|
|
177
|
+
let checkedRows = hotComponent.getCheckedRows ();
|
|
178
|
+
let whereFields: any[] = [];
|
|
179
|
+
|
|
180
|
+
if (checkedRows.length > 0)
|
|
181
|
+
{
|
|
182
|
+
for (let i = 0; i < checkedRows.length; i++)
|
|
183
|
+
{
|
|
184
|
+
let checkedRow = checkedRows[i];
|
|
185
|
+
whereFields.push (checkedRow);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let selectedField = hotComponent.getSelected ();
|
|
190
|
+
|
|
191
|
+
if (selectedField != null)
|
|
192
|
+
whereFields = [selectedField];
|
|
193
|
+
|
|
194
|
+
if (whereFields.length > 0)
|
|
195
|
+
{
|
|
196
|
+
const confirmed: boolean = confirm ("Are you sure you want to remove this item?");
|
|
197
|
+
|
|
198
|
+
if (confirmed === true)
|
|
199
|
+
{
|
|
200
|
+
for (let i = 0; i < whereFields.length; i++)
|
|
201
|
+
{
|
|
202
|
+
let whereField = whereFields[i];
|
|
203
|
+
|
|
204
|
+
// Remove any fields that are marked as remove.
|
|
205
|
+
for (let key in whereField)
|
|
206
|
+
{
|
|
207
|
+
let fieldType = hotComponent.getFieldType (key);
|
|
208
|
+
|
|
209
|
+
if (fieldType != null)
|
|
210
|
+
{
|
|
211
|
+
if (fieldType === "remove")
|
|
212
|
+
delete whereField[key];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
await Hot.jsonRequest (`${Hot.Data.baseUrl}/v1/data/remove`, {
|
|
217
|
+
schema: this.schema,
|
|
218
|
+
whereFields: whereField
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await hotComponent.refreshList ();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
43
225
|
}
|
|
44
226
|
|
|
45
227
|
/**
|
|
@@ -52,23 +234,86 @@ export class AdminEdit extends HotComponent
|
|
|
52
234
|
for (let key in this.fieldElements)
|
|
53
235
|
{
|
|
54
236
|
let fieldElement = this.fieldElements[key];
|
|
55
|
-
let value = fieldElement.value;
|
|
56
237
|
|
|
57
|
-
|
|
238
|
+
if (fieldElement != null)
|
|
239
|
+
{
|
|
240
|
+
let value = fieldElement.value;
|
|
241
|
+
let fieldType: string = fieldElement.parentNode.hotComponent.field_type;
|
|
242
|
+
|
|
243
|
+
if (fieldType === "remove")
|
|
244
|
+
continue;
|
|
245
|
+
|
|
246
|
+
values[key] = value;
|
|
247
|
+
}
|
|
58
248
|
}
|
|
59
249
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
250
|
+
if (this.modalType === "add")
|
|
251
|
+
{
|
|
252
|
+
await Hot.jsonRequest (`${Hot.Data.baseUrl}/v1/data/add`, {
|
|
253
|
+
schema: this.schema,
|
|
254
|
+
fields: values
|
|
255
|
+
});
|
|
256
|
+
}
|
|
64
257
|
|
|
65
|
-
|
|
258
|
+
if (this.modalType === "edit")
|
|
259
|
+
{
|
|
260
|
+
if (this.selectedFields.length === 0)
|
|
261
|
+
{
|
|
262
|
+
alert ("No item(s) selected!");
|
|
66
263
|
|
|
67
|
-
|
|
68
|
-
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
let selectedField = this.selectedFields[0];
|
|
268
|
+
let whereFields: any = {};
|
|
269
|
+
|
|
270
|
+
for (let key in selectedField)
|
|
271
|
+
{
|
|
272
|
+
let fieldElement = this.fieldElements[key];
|
|
273
|
+
let value = selectedField[key];
|
|
274
|
+
|
|
275
|
+
if (fieldElement != null)
|
|
276
|
+
{
|
|
277
|
+
let fieldType: string = fieldElement.parentNode.hotComponent.field_type;
|
|
278
|
+
|
|
279
|
+
if (fieldType === "remove")
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
69
282
|
|
|
283
|
+
whereFields[key] = value;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
await Hot.jsonRequest (`${Hot.Data.baseUrl}/v1/data/edit`, {
|
|
287
|
+
schema: this.schema,
|
|
288
|
+
whereFields: whereFields,
|
|
289
|
+
fields: values
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
let attachedList = document.getElementById (this.attached_list);
|
|
70
294
|
// @ts-ignore
|
|
71
|
-
|
|
295
|
+
let table: AdminTable = attachedList.hotComponent;
|
|
296
|
+
|
|
297
|
+
await table.refreshList ();
|
|
298
|
+
|
|
299
|
+
if (this.closeOnSave === true)
|
|
300
|
+
{
|
|
301
|
+
bootstrap.Modal.getInstance (`#${this.modalId}`).hide ();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Get the list of data from the server.
|
|
307
|
+
*/
|
|
308
|
+
onPostPlace (parentHtmlElement: HTMLElement, htmlElement: HTMLElement): HTMLElement
|
|
309
|
+
{
|
|
310
|
+
this.modal = new bootstrap.Modal ($(`#${this.modalId}`)[0], {
|
|
311
|
+
"backdrop": true,
|
|
312
|
+
"keyboard": true,
|
|
313
|
+
"focus": true
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
return (null);
|
|
72
317
|
}
|
|
73
318
|
|
|
74
319
|
output (): string | HotComponentOutput[]
|
|
@@ -102,8 +347,15 @@ export class AdminEdit extends HotComponent
|
|
|
102
347
|
documentSelector: "body"
|
|
103
348
|
},
|
|
104
349
|
{
|
|
105
|
-
html: `<button id = "${this.modalId}-add-btn" type="button" class="btn btn-sm btn-outline-secondary"
|
|
106
|
-
|
|
350
|
+
html: `<button id = "${this.modalId}-add-btn" type="button" class="btn btn-sm btn-outline-secondary" onclick = "this.addClicked ();">Add</button>`,
|
|
351
|
+
documentSelector: `hot-place-here[name="buttons"]`
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
html: `<button id = "${this.modalId}-edit-btn" type="button" class="btn btn-sm btn-outline-secondary" onclick = "this.editClicked ();">Edit</button>`,
|
|
355
|
+
documentSelector: `hot-place-here[name="buttons"]`
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
html: `<button id = "${this.modalId}-edit-btn" type="button" class="btn btn-sm btn-outline-secondary" onclick = "this.removeClicked ();">Remove</button>`,
|
|
107
359
|
documentSelector: `hot-place-here[name="buttons"]`
|
|
108
360
|
}]);
|
|
109
361
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HotStaq, Hot, HotAPI, HotComponent, HotComponentOutput } from "hotstaq";
|
|
2
|
+
import { AdminTable } from "./admin-table";
|
|
2
3
|
|
|
3
4
|
export class AdminTableField extends HotComponent
|
|
4
5
|
{
|
|
@@ -6,6 +7,18 @@ export class AdminTableField extends HotComponent
|
|
|
6
7
|
* The table field.
|
|
7
8
|
*/
|
|
8
9
|
field: number;
|
|
10
|
+
/**
|
|
11
|
+
* The type of field. Can be:
|
|
12
|
+
* * text
|
|
13
|
+
* * remove
|
|
14
|
+
*
|
|
15
|
+
* Default: text
|
|
16
|
+
*/
|
|
17
|
+
field_type: string;
|
|
18
|
+
/**
|
|
19
|
+
* If set to 1, this will not output the field.
|
|
20
|
+
*/
|
|
21
|
+
no_output: string;
|
|
9
22
|
|
|
10
23
|
constructor (copy: HotComponent | HotStaq, api: HotAPI)
|
|
11
24
|
{
|
|
@@ -13,6 +26,8 @@ export class AdminTableField extends HotComponent
|
|
|
13
26
|
|
|
14
27
|
this.tag = "admin-table-field";
|
|
15
28
|
this.field = 0;
|
|
29
|
+
this.field_type = "text";
|
|
30
|
+
this.no_output = "0";
|
|
16
31
|
}
|
|
17
32
|
|
|
18
33
|
/**
|
|
@@ -20,8 +35,19 @@ export class AdminTableField extends HotComponent
|
|
|
20
35
|
*/
|
|
21
36
|
onPostPlace (parentHtmlElement: HTMLElement, htmlElement: HTMLElement): HTMLElement
|
|
22
37
|
{
|
|
38
|
+
let hotComponent: AdminTable = null;
|
|
39
|
+
|
|
23
40
|
// @ts-ignore
|
|
24
|
-
|
|
41
|
+
if (parentHtmlElement.parentNode.parentNode.hotComponent != null)
|
|
42
|
+
{
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
hotComponent = parentHtmlElement.parentNode.parentNode.hotComponent;
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
{
|
|
48
|
+
// @ts-ignore - looool. Add a better way to get the parent HotComponent.
|
|
49
|
+
hotComponent = parentHtmlElement.parentNode.parentNode.parentNode.parentNode.hotComponent;
|
|
50
|
+
}
|
|
25
51
|
|
|
26
52
|
if (hotComponent != null)
|
|
27
53
|
hotComponent.addHeaderDataOnly (this, htmlElement);
|
|
@@ -31,6 +57,14 @@ export class AdminTableField extends HotComponent
|
|
|
31
57
|
|
|
32
58
|
output (): string | HotComponentOutput[]
|
|
33
59
|
{
|
|
60
|
+
if (this.no_output === "1")
|
|
61
|
+
{
|
|
62
|
+
return ([{
|
|
63
|
+
html: `<div></div>`,
|
|
64
|
+
placeHereParent: "afterTable"
|
|
65
|
+
}]);
|
|
66
|
+
}
|
|
67
|
+
|
|
34
68
|
return ([{
|
|
35
69
|
html: `<th>${this.inner}</th>`,
|
|
36
70
|
documentSelector: "[hot-place-here='header']"
|
|
@@ -32,6 +32,9 @@ export class AdminTableRow extends HotComponent
|
|
|
32
32
|
{
|
|
33
33
|
let rowHtml = "";
|
|
34
34
|
|
|
35
|
+
if (this.fields.length > 0)
|
|
36
|
+
rowHtml += `<td><input type = "checkbox" /></td>`;
|
|
37
|
+
|
|
35
38
|
for (let iIdx = 0; iIdx < this.fields.length; iIdx++)
|
|
36
39
|
{
|
|
37
40
|
let fieldObj = this.fields[iIdx];
|
|
@@ -37,7 +37,17 @@ export class AdminTable extends HotComponent
|
|
|
37
37
|
* "html": "<tr><td>John Smith</td><td>john.smith@test.com</td></tr>"
|
|
38
38
|
* }
|
|
39
39
|
*/
|
|
40
|
-
rowElements: { fields: any[];
|
|
40
|
+
rowElements: { fields: any[]; element: HTMLElement; }[] = [];
|
|
41
|
+
/**
|
|
42
|
+
* The selected row indicies. Each index maps to the rowElements array.
|
|
43
|
+
*
|
|
44
|
+
* @fixme Add support for this in the future.
|
|
45
|
+
*/
|
|
46
|
+
//protected selectedRows: number[];
|
|
47
|
+
/**
|
|
48
|
+
* The most recently selected row index. The index maps to the rowElements array.
|
|
49
|
+
*/
|
|
50
|
+
protected selected: number;
|
|
41
51
|
|
|
42
52
|
constructor (copy: HotComponent | HotStaq, api: HotAPI)
|
|
43
53
|
{
|
|
@@ -49,6 +59,8 @@ export class AdminTable extends HotComponent
|
|
|
49
59
|
this.headerElements = {};
|
|
50
60
|
this.headerIndicies = [];
|
|
51
61
|
this.rowElements = [];
|
|
62
|
+
//this.selectedRows = [];
|
|
63
|
+
this.selected = -1;
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
/**
|
|
@@ -58,6 +70,9 @@ export class AdminTable extends HotComponent
|
|
|
58
70
|
{
|
|
59
71
|
let header = this.htmlElements[0].getElementsByTagName ("thead")[0];
|
|
60
72
|
|
|
73
|
+
if (this.headerIndicies.length < 1)
|
|
74
|
+
this.headerIndicies.push (null);
|
|
75
|
+
|
|
61
76
|
// @ts-ignore
|
|
62
77
|
this.headerIndicies.push (tableFieldElement.hotComponent.field);
|
|
63
78
|
header.appendChild (tableFieldElement);
|
|
@@ -68,10 +83,158 @@ export class AdminTable extends HotComponent
|
|
|
68
83
|
*/
|
|
69
84
|
addHeaderDataOnly (tableField: AdminTableField, htmlElement: HTMLElement)
|
|
70
85
|
{
|
|
86
|
+
if (this.headerIndicies.length < 1)
|
|
87
|
+
this.headerIndicies.push (null);
|
|
88
|
+
|
|
71
89
|
this.headerIndicies.push (tableField.field);
|
|
72
90
|
this.headerElements[tableField.field] = htmlElement;
|
|
73
91
|
}
|
|
74
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Get the field type of a field.
|
|
95
|
+
*/
|
|
96
|
+
getFieldType (fieldName: string): string
|
|
97
|
+
{
|
|
98
|
+
if (this.headerElements[fieldName] != null)
|
|
99
|
+
{
|
|
100
|
+
let hotComponent: AdminTableField = this.headerElements[fieldName].hotComponent;
|
|
101
|
+
|
|
102
|
+
if (hotComponent != null)
|
|
103
|
+
return (hotComponent.field_type);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return (null);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Executes this event when a row is selected. If this returns false, the row will not be selected.
|
|
111
|
+
*/
|
|
112
|
+
onSelectedRow: (rowIndex: number) => Promise<boolean> = null;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Executes when a row is selected.
|
|
116
|
+
*/
|
|
117
|
+
async selectRow (htmlElement: HTMLElement, rowIndex: number): Promise<void>
|
|
118
|
+
{
|
|
119
|
+
if (this.onSelectedRow != null)
|
|
120
|
+
{
|
|
121
|
+
let result = await this.onSelectedRow (rowIndex);
|
|
122
|
+
|
|
123
|
+
if (result === false)
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// In the future, we will support multiple rows being selected. For now
|
|
128
|
+
// this will ensure that only one row is selected at a time.
|
|
129
|
+
{
|
|
130
|
+
let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
131
|
+
let rows = tbody.getElementsByTagName ("tr");
|
|
132
|
+
|
|
133
|
+
for (let iIdx = 0; iIdx < rows.length; iIdx++)
|
|
134
|
+
{
|
|
135
|
+
let row: HTMLTableRowElement = rows[iIdx];
|
|
136
|
+
|
|
137
|
+
if (row.classList.contains ("table-primary") === true)
|
|
138
|
+
row.classList.remove ("table-primary");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
htmlElement.classList.add ("table-primary");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
this.selected = rowIndex;
|
|
145
|
+
|
|
146
|
+
/*this.selectedRows = [];
|
|
147
|
+
let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
148
|
+
|
|
149
|
+
// Find all the checkboxes in tbody.
|
|
150
|
+
let checkboxes = tbody.getElementsByTagName ("input");
|
|
151
|
+
|
|
152
|
+
for (let iIdx = 0; iIdx < checkboxes.length; iIdx++)
|
|
153
|
+
{
|
|
154
|
+
let checkbox: HTMLInputElement = checkboxes[iIdx];
|
|
155
|
+
|
|
156
|
+
if (checkbox.checked != null)
|
|
157
|
+
{
|
|
158
|
+
if (checkbox.checked === true)
|
|
159
|
+
{
|
|
160
|
+
// Get the data-index attribute.
|
|
161
|
+
let dataIndexStr: string = checkbox.parentElement.parentElement.getAttribute ("data-index");
|
|
162
|
+
let dataIndex: number = parseInt (dataIndexStr);
|
|
163
|
+
|
|
164
|
+
this.selectedRows.push (dataIndex);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}*/
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Get the selected data.
|
|
172
|
+
*/
|
|
173
|
+
getSelected (): any[]
|
|
174
|
+
{
|
|
175
|
+
let index: number = this.selected;
|
|
176
|
+
|
|
177
|
+
if (index < 0)
|
|
178
|
+
return (null);
|
|
179
|
+
|
|
180
|
+
return (this.rowElements[index].fields);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get the selected data.
|
|
185
|
+
*/
|
|
186
|
+
/*getSelectedRows (): any[]
|
|
187
|
+
{
|
|
188
|
+
let rows: any[] = [];
|
|
189
|
+
|
|
190
|
+
for (let iIdx = 0; iIdx < this.selectedRows.length; iIdx++)
|
|
191
|
+
{
|
|
192
|
+
let index: number = this.selectedRows[iIdx];
|
|
193
|
+
rows.push (this.rowElements[index].fields);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return (rows);
|
|
197
|
+
}*/
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Get the data for each row that has been checked.
|
|
201
|
+
*/
|
|
202
|
+
getCheckedRows (): any[]
|
|
203
|
+
{
|
|
204
|
+
let rows: any[] = [];
|
|
205
|
+
let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
206
|
+
|
|
207
|
+
// Find all the checkboxes in tbody.
|
|
208
|
+
let checkboxes = tbody.getElementsByTagName ("input");
|
|
209
|
+
|
|
210
|
+
for (let iIdx = 0; iIdx < checkboxes.length; iIdx++)
|
|
211
|
+
{
|
|
212
|
+
let checkbox: HTMLInputElement = checkboxes[iIdx];
|
|
213
|
+
|
|
214
|
+
if (checkbox.checked != null)
|
|
215
|
+
{
|
|
216
|
+
if (checkbox.checked === true)
|
|
217
|
+
{
|
|
218
|
+
// Get the data-index attribute.
|
|
219
|
+
let dataIndexStr: string = checkbox.parentElement.parentElement.getAttribute ("data-index");
|
|
220
|
+
let dataIndex: number = parseInt (dataIndexStr);
|
|
221
|
+
|
|
222
|
+
rows.push (this.rowElements[dataIndex].fields);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return (rows);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Get a row's data.
|
|
232
|
+
*/
|
|
233
|
+
getRow (index: number): any[]
|
|
234
|
+
{
|
|
235
|
+
return (this.rowElements[index].fields);
|
|
236
|
+
}
|
|
237
|
+
|
|
75
238
|
/**
|
|
76
239
|
* Add a row to the table.
|
|
77
240
|
*
|
|
@@ -80,20 +243,38 @@ export class AdminTable extends HotComponent
|
|
|
80
243
|
addRow (fields: { [name: string]: any }[])
|
|
81
244
|
{
|
|
82
245
|
let tbody = this.htmlElements[1].getElementsByTagName ("tbody")[0];
|
|
83
|
-
let
|
|
246
|
+
let index: number = this.rowElements.length;
|
|
247
|
+
let rowStr = `<tr onclick = "this.parentNode.parentNode.parentNode.parentNode.hotComponent.selectRow (this, ${index});">`;
|
|
248
|
+
|
|
249
|
+
rowStr += `<td><input type = "checkbox" /></td>`;
|
|
84
250
|
|
|
85
251
|
for (let iIdx = 0; iIdx < this.headerIndicies.length; iIdx++)
|
|
86
252
|
{
|
|
253
|
+
// @ts-ignore - @fixme I messed this up, will fix.
|
|
87
254
|
let key = this.headerIndicies[iIdx];
|
|
88
255
|
let value = fields[key];
|
|
89
256
|
|
|
90
257
|
if (this.headerElements[key] != null)
|
|
91
|
-
|
|
258
|
+
{
|
|
259
|
+
// @ts-ignore - @fixme I messed this up, will fix.
|
|
260
|
+
let fieldType: string = this.getFieldType (key);
|
|
261
|
+
|
|
262
|
+
if (fieldType == null)
|
|
263
|
+
fieldType = "text";
|
|
264
|
+
|
|
265
|
+
if (fieldType !== "remove")
|
|
266
|
+
rowStr += `<td data-index = "${index}">${value}</td>`;
|
|
267
|
+
}
|
|
92
268
|
}
|
|
93
269
|
|
|
94
270
|
rowStr += "</tr>";
|
|
95
271
|
|
|
96
|
-
HotStaq.addHtml (tbody, rowStr);
|
|
272
|
+
let newObj = HotStaq.addHtml (tbody, rowStr);
|
|
273
|
+
|
|
274
|
+
this.rowElements.push ({
|
|
275
|
+
fields: fields,
|
|
276
|
+
element: (<HTMLElement>newObj)
|
|
277
|
+
});
|
|
97
278
|
}
|
|
98
279
|
|
|
99
280
|
/**
|
|
@@ -145,11 +326,15 @@ export class AdminTable extends HotComponent
|
|
|
145
326
|
<h2>${this.title}</h2>
|
|
146
327
|
<div class="table-responsive">
|
|
147
328
|
<table id = "${this.htmlElements[0].id}Table" class="table table-striped table-sm">
|
|
148
|
-
<thead
|
|
329
|
+
<thead>
|
|
330
|
+
<tr hot-place-here = "header">
|
|
331
|
+
<th></th>
|
|
332
|
+
</tr>
|
|
149
333
|
</thead>
|
|
150
334
|
<tbody hot-place-here = "results">
|
|
151
335
|
</tbody>
|
|
152
336
|
</table>
|
|
337
|
+
<hot-place-here name = "afterTable"></hot-place-here>
|
|
153
338
|
</div>
|
|
154
339
|
</div>`);
|
|
155
340
|
}
|
|
@@ -6,6 +6,18 @@ export class AdminText extends HotComponent
|
|
|
6
6
|
* The associated database field.
|
|
7
7
|
*/
|
|
8
8
|
field: string;
|
|
9
|
+
/**
|
|
10
|
+
* The type of field. Can be:
|
|
11
|
+
* * text
|
|
12
|
+
* * remove
|
|
13
|
+
*
|
|
14
|
+
* Default: text
|
|
15
|
+
*/
|
|
16
|
+
field_type: string;
|
|
17
|
+
/**
|
|
18
|
+
* If set to 1, this will not output the field.
|
|
19
|
+
*/
|
|
20
|
+
no_output: string;
|
|
9
21
|
|
|
10
22
|
constructor (copy: HotComponent | HotStaq, api: HotAPI)
|
|
11
23
|
{
|
|
@@ -13,6 +25,8 @@ export class AdminText extends HotComponent
|
|
|
13
25
|
|
|
14
26
|
this.tag = "admin-text";
|
|
15
27
|
this.field = "";
|
|
28
|
+
this.field_type = "text";
|
|
29
|
+
this.no_output = "0";
|
|
16
30
|
}
|
|
17
31
|
|
|
18
32
|
/**
|
|
@@ -22,6 +36,8 @@ export class AdminText extends HotComponent
|
|
|
22
36
|
{
|
|
23
37
|
let placeHereArray = parentHtmlElement.querySelectorAll (`hot-place-here[type="modal"]`);
|
|
24
38
|
|
|
39
|
+
// Search for the input box in the modal we attached to, then store the
|
|
40
|
+
// found input box into the fieldElements array.
|
|
25
41
|
if (placeHereArray.length > 0)
|
|
26
42
|
{
|
|
27
43
|
let placeHere = placeHereArray[0];
|
|
@@ -42,6 +58,9 @@ export class AdminText extends HotComponent
|
|
|
42
58
|
if (this.value != null)
|
|
43
59
|
value = this.value;
|
|
44
60
|
|
|
61
|
+
if (this.no_output === "1")
|
|
62
|
+
return (`<div><input class="form-control" type = "hidden" value = "${value}" /></div>`);
|
|
63
|
+
|
|
45
64
|
return (`<div>
|
|
46
65
|
<label class="form-label">${this.inner}</label><input class="form-control" type = "text" value = "${value}" />
|
|
47
66
|
</div>`);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AdminButton } from "./components/admin-button";
|
|
2
|
+
import { AdminDashboard } from "./components/admin-dashboard";
|
|
3
|
+
import { AdminEdit } from "./components/admin-edit";
|
|
4
|
+
import { AdminTable } from "./components/admin-table";
|
|
5
|
+
import { AdminTableField } from "./components/admin-table-field";
|
|
6
|
+
import { AdminTableRow } from "./components/admin-table-row";
|
|
7
|
+
import { AdminText } from "./components/admin-text";
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
AdminButton,
|
|
11
|
+
AdminDashboard,
|
|
12
|
+
AdminEdit,
|
|
13
|
+
AdminTable,
|
|
14
|
+
AdminTableField,
|
|
15
|
+
AdminTableRow,
|
|
16
|
+
AdminText
|
|
17
|
+
};
|