@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.
Files changed (46) hide show
  1. package/.env +2 -0
  2. package/HotSite.json +0 -1
  3. package/assets/html/admin-header.hott +7 -3
  4. package/assets/js/dashboard.js +0 -46
  5. package/build/AppAPI.d.ts +21 -2
  6. package/build/AppAPI.d.ts.map +1 -1
  7. package/build/AppAPI.js +38 -43
  8. package/build/AppAPI.js.map +1 -1
  9. package/build/WebExport.d.ts.map +1 -1
  10. package/build/WebExport.js +8 -4
  11. package/build/WebExport.js.map +1 -1
  12. package/build/components/admin-button.js.map +1 -1
  13. package/build/components/admin-dropdown.js.map +1 -1
  14. package/build/components/admin-edit.d.ts +6 -1
  15. package/build/components/admin-edit.d.ts.map +1 -1
  16. package/build/components/admin-edit.js +50 -31
  17. package/build/components/admin-edit.js.map +1 -1
  18. package/build/components/admin-table-field.js +1 -1
  19. package/build/components/admin-table-field.js.map +1 -1
  20. package/build/components/admin-table-row.js.map +1 -1
  21. package/build/components/admin-table.d.ts +48 -2
  22. package/build/components/admin-table.d.ts.map +1 -1
  23. package/build/components/admin-table.js +137 -25
  24. package/build/components/admin-table.js.map +1 -1
  25. package/build/components/admin-text.d.ts.map +1 -1
  26. package/build/components/admin-text.js +2 -1
  27. package/build/components/admin-text.js.map +1 -1
  28. package/build/tsconfig.tsbuildinfo +1 -0
  29. package/build-web/AdminPanelComponents.js +2 -2
  30. package/build-web/AdminPanelComponents.js.LICENSE.txt +14 -0
  31. package/build-web/AdminPanelWeb_AppAPI.js +804 -39
  32. package/docker-compose.yaml +0 -1
  33. package/env-example +4 -2
  34. package/package.json +14 -6
  35. package/src/AppAPI.ts +54 -57
  36. package/src/WebExport.ts +8 -3
  37. package/src/components/admin-edit.ts +59 -30
  38. package/src/components/admin-table-field.ts +1 -1
  39. package/src/components/admin-table.ts +212 -20
  40. package/src/components/admin-text.ts +2 -1
  41. package/start.sh +1 -1
  42. package/stop.sh +1 -1
  43. package/webpack-api.config.js +8 -2
  44. package/webpack.config.cjs +7 -1
  45. package/dbstart.sh +0 -14
  46. package/dbstop.sh +0 -3
@@ -1,4 +1,3 @@
1
- version: "3.8"
2
1
  services:
3
2
  # Used just to make sure the database has started before continuing.
4
3
  init-app-database:
package/env-example CHANGED
@@ -1,7 +1,9 @@
1
1
  HTTP_PORT=3243
2
+ JWT_SECRET_KEY=ja789w5hja9w345h98aw3jh48aw34j898
2
3
  MYSQL_ROOT_PASSWORD=jlka7sw47aSD234
3
- DATABASE_SERVER=127.0.0.1
4
- DATABASE_PORT=3320
4
+ DATABASE_TYPE=mariadb
5
+ DATABASE_SERVER=localhost
6
+ DATABASE_PORT=3322
5
7
  DATABASE_USERNAME=5NKVBAt7OrzrumQyQVs
6
8
  DATABASE_PASSWORD=1BBrZbKYRUM7oiMA5oY
7
9
  DATABASE_SCHEMA=staqapp
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hotstaq/admin-panel",
3
3
  "description": "",
4
- "version": "0.3.6",
4
+ "version": "0.3.9",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
7
7
  "start": "hotstaq --hotsite ./HotSite.json --env-file ./.env run --server-type web-api",
@@ -18,12 +18,18 @@
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
20
  "@hotstaq/dataroute": "^0.2.10",
21
- "@popperjs/core": "^2.11.6",
22
- "bootstrap": "^5.2.3",
23
- "chart.js": "^2.9.4",
21
+ "@hotstaq/userroute": "^0.6.13",
22
+ "@popperjs/core": "^2.11.8",
23
+ "bootstrap": "^5.3.3",
24
+ "datatables.net": "^2.2.2",
25
+ "datatables.net-bs5": "^2.2.2",
26
+ "datatables.net-colreorder-bs5": "^2.0.4",
27
+ "datatables.net-scroller-bs5": "^2.4.3",
28
+ "datatables.net-searchbuilder-bs5": "^1.8.2",
29
+ "datatables.net-select-bs5": "^3.0.0",
24
30
  "dotenv": "^10.0.0",
25
31
  "feather-icons": "^4.29.0",
26
- "jquery": "^3.6.3"
32
+ "jquery": "^3.7.1"
27
33
  },
28
34
  "devDependencies": {
29
35
  "@types/bootstrap": "^5.2.6",
@@ -36,14 +42,16 @@
36
42
  "@types/mocha": "^10.0.1",
37
43
  "@types/node": "^20.14.10",
38
44
  "@types/node-fetch": "^2.6.1",
45
+ "@types/pg": "^8.11.11",
39
46
  "@types/selenium-webdriver": "^4.1.5",
40
47
  "@types/uuid": "^8.3.4",
41
48
  "chokidar": "^3.5.3",
42
49
  "ts-loader": "^7.0.5",
43
50
  "webpack": "^5.75.0",
51
+ "webpack-bundle-analyzer": "^4.10.2",
44
52
  "webpack-cli": "^5.0.1"
45
53
  },
46
54
  "peerDependencies": {
47
- "hotstaq": "^0.8.95"
55
+ "hotstaq": "^0.8.118"
48
56
  }
49
57
  }
package/src/AppAPI.ts CHANGED
@@ -1,17 +1,44 @@
1
- import { HotAPI, HotServer, HotClient, HotRoute,
2
- HotRouteMethod, MySQLSchema,
3
- ServerAuthorizationFunction, HotStaq, HotServerType, DeveloperMode, HotDBMySQL } from "hotstaq";
4
- import { DataRoute } from "@hotstaq/dataroute";
1
+ import { HotAPI, HotServer, HotClient, MySQLSchema, HotServerType, HotDBMySQL, HotLog, ServerRequest} from "hotstaq";
2
+ import { AdminRoute, User, UserRoute } from "@hotstaq/userroute";
3
+
4
+ /**
5
+ * An admin route that can be used for any user.
6
+ */
7
+ export class FriendlyAdminRoute extends AdminRoute
8
+ {
9
+ constructor (api: HotAPI, routeName: string = "admins")
10
+ {
11
+ super (api, routeName);
12
+ }
13
+
14
+ /**
15
+ * This disables the need to check for authentication.
16
+ */
17
+ protected async checkAuth (req: ServerRequest): Promise<void>
18
+ {
19
+ }
20
+ }
5
21
 
6
22
  /**
7
23
  * The App's API and routes.
8
24
  */
9
25
  export class AppAPI extends HotAPI
10
26
  {
11
- constructor (baseUrl: string, connection: HotServer | HotClient, db: any = null)
27
+ /**
28
+ * The logger.
29
+ */
30
+ logger: HotLog;
31
+ /**
32
+ * The database connection.
33
+ */
34
+ db: HotDBMySQL;
35
+
36
+ constructor (baseUrl: string, connection: HotServer | HotClient, db: HotDBMySQL = null)
12
37
  {
13
38
  super(baseUrl, connection, db);
14
39
 
40
+ this.logger = connection.logger;
41
+
15
42
  this.onPreRegister = async (): Promise<boolean> =>
16
43
  {
17
44
  if (connection.type !== HotServerType.Generate)
@@ -23,64 +50,34 @@ export class AppAPI extends HotAPI
23
50
  };
24
51
  this.onPostRegister = async (): Promise<boolean> =>
25
52
  {
26
- // Sync database tables here.
53
+ await User.syncTables (this.db, true);
27
54
 
28
- return (true);
29
- };
55
+ const maxUsers: number = 53;
30
56
 
31
- this.addRoute (new DataRoute (this, async (db: HotDBMySQL) =>
32
- {
33
- if (this.connection.processor.mode === DeveloperMode.Development)
57
+ for (let iIdx = 0; iIdx < maxUsers; iIdx++)
34
58
  {
35
- await db.query (
36
- `create table if not exists users (
37
- id INT(10) NOT NULL AUTO_INCREMENT,
38
- name VARCHAR(256) DEFAULT '',
39
- email VARCHAR(256) DEFAULT '',
40
- password VARCHAR(256) DEFAULT '',
41
- verified INT(1) DEFAULT '0',
42
- registered DATETIME DEFAULT NOW(),
43
- enabled INT(1) DEFAULT '1',
44
- PRIMARY KEY (id)
45
- )`);
46
-
47
- let results: any = await db.queryOne (`select COUNT(*) from users;`);
48
-
49
- if (results.results["COUNT(*)"] < 1)
59
+ try
50
60
  {
51
- let testUsers = [{
52
- name: "John",
53
- email: "test1@freelight.org",
54
- password: "a867h398jdg",
55
- verified: true
56
- },
57
- {
58
- name: "Jane",
59
- email: "test2@freelight.org",
60
- password: "ai97w3a98w3498",
61
- verified: true
62
- }
63
- ];
64
-
65
- for (let iIdx = 0; iIdx < testUsers.length; iIdx++)
66
- {
67
- let testUser = testUsers[iIdx];
68
- let verified: number = 0;
69
-
70
- if (testUser.verified === true)
71
- verified = 1;
72
-
73
- let result: any = await db.query (
74
- `INSERT INTO users (name, email, password, verified) VALUES (?, ?, ?, ?);`,
75
- [testUser.name, testUser.email, testUser.password, verified]);
76
-
77
- if (result.error != null)
78
- throw new Error (result.error);
61
+ let testUser = new User ({
62
+ displayName: `John${iIdx}`,
63
+ email: `test${iIdx}@freelight.org`,
64
+ password: "a867h398jdg",
65
+ verified: ((iIdx % 2) === 0) ? true : false
66
+ });
79
67
 
80
- let id: number = result.results["insertId"];
81
- }
68
+ await testUser.register (this.db);
69
+ this.logger.info (`Registered user: ${testUser.displayName}`);
70
+ }
71
+ catch (ex)
72
+ {
73
+ this.logger.error (`Error registering user: ${ex}`);
82
74
  }
83
75
  }
84
- }));
76
+
77
+ return (true);
78
+ };
79
+
80
+ this.addRoute (new UserRoute (this, "users"));
81
+ this.addRoute (new FriendlyAdminRoute (this, "admins"));
85
82
  }
86
83
  }
package/src/WebExport.ts CHANGED
@@ -3,9 +3,14 @@ async function buildAssets (): Promise<any>
3
3
  return ({
4
4
  import: ["@popperjs/core",
5
5
  { name: "jquery", files: ["jquery.min.js"] },
6
- "chart.js",
7
- "feather-icons",
8
- { name: "bootstrap", files: ["bootstrap.min.js", "bootstrap.min.css"] }],
6
+ "feather-icons",
7
+ { name: "bootstrap", files: ["bootstrap.min.js", "bootstrap.min.css"] },
8
+ "datatables.net",
9
+ "datatables.net-bs5",
10
+ "datatables.net-colreorder-bs5",
11
+ "datatables.net-scroller-bs5",
12
+ "datatables.net-searchbuilder-bs5",
13
+ "datatables.net-select-bs5"],
9
14
  html: ["./assets/html/*.*"],
10
15
  css: ["./assets/css/*.*"],
11
16
  js: ["./assets/js/*.*", "./build-web/AdminPanelComponents.js"],
@@ -195,10 +195,28 @@ export class AdminEdit extends HotComponent
195
195
  */
196
196
  onEditClicked: () => Promise<boolean> = null;
197
197
 
198
+ /**
199
+ * Get the attached lists.
200
+ */
201
+ getAttachedLists (): HTMLElement[]
202
+ {
203
+ const strs = this.attached_list.split (",");
204
+ const attachedLists: HTMLElement[] = [];
205
+
206
+ for (let i = 0; i < strs.length; i++)
207
+ {
208
+ const attachedList = strs[i];
209
+ let attachedListObj = document.getElementById (attachedList);
210
+ attachedLists.push (attachedListObj);
211
+ }
212
+
213
+ return (attachedLists);
214
+ }
215
+
198
216
  /**
199
217
  * Executes when the edit button is clicked.
200
218
  */
201
- async editClicked (selectedFields: any[] = []): Promise<void>
219
+ async editClicked (attachedList: AdminTable, selectedFields: any[] = []): Promise<void>
202
220
  {
203
221
  if (this.onEditClicked != null)
204
222
  {
@@ -214,12 +232,8 @@ export class AdminEdit extends HotComponent
214
232
 
215
233
  if (this.attached_list !== "")
216
234
  {
217
- let attachedList = document.getElementById (this.attached_list);
218
-
219
- // @ts-ignore
220
- let hotComponent: AdminTable = attachedList.hotComponent;
221
- hotComponent.attachedEdit = this;
222
- let selectedField = hotComponent.getSelected ();
235
+ attachedList.attachedEdit = this;
236
+ let selectedField = attachedList.getSelected ();
223
237
 
224
238
  if (selectedField != null)
225
239
  {
@@ -289,25 +303,30 @@ export class AdminEdit extends HotComponent
289
303
 
290
304
  if (this.attached_list !== "")
291
305
  {
292
- let attachedList = document.getElementById (this.attached_list);
293
- // @ts-ignore
294
- hotComponent = attachedList.hotComponent;
295
- hotComponent.attachedEdit = this;
296
- let checkedRows = hotComponent.getCheckedRows ();
306
+ const attachedLists = this.getAttachedLists ();
297
307
 
298
- if (checkedRows.length > 0)
308
+ for (let iIdx = 0; iIdx < attachedLists.length; iIdx++)
299
309
  {
300
- for (let i = 0; i < checkedRows.length; i++)
310
+ let attachedList = attachedLists[iIdx];
311
+ // @ts-ignore
312
+ hotComponent = attachedList.hotComponent;
313
+ hotComponent.attachedEdit = this;
314
+ let checkedRows = hotComponent.getCheckedRows ();
315
+
316
+ if (checkedRows.length > 0)
301
317
  {
302
- let checkedRow = checkedRows[i];
303
- whereFields.push (checkedRow);
318
+ for (let i = 0; i < checkedRows.length; i++)
319
+ {
320
+ let checkedRow = checkedRows[i];
321
+ whereFields.push (checkedRow);
322
+ }
304
323
  }
305
- }
306
324
 
307
- let selectedField = hotComponent.getSelected ();
325
+ let selectedField = hotComponent.getSelected ();
308
326
 
309
- if (selectedField != null)
310
- whereFields = [selectedField];
327
+ if (selectedField != null)
328
+ whereFields = [selectedField];
329
+ }
311
330
  }
312
331
 
313
332
  const confirmed: boolean = confirm ("Are you sure you want to remove this item?");
@@ -488,13 +507,18 @@ export class AdminEdit extends HotComponent
488
507
 
489
508
  if (this.attached_list !== "")
490
509
  {
491
- let attachedList = document.getElementById (this.attached_list);
492
- // @ts-ignore
493
- let table: AdminTable = attachedList.hotComponent;
510
+ const attachedLists = this.getAttachedLists ();
494
511
 
495
- table.attachedEdit = this;
512
+ for (let iIdx = 0; iIdx < attachedLists.length; iIdx++)
513
+ {
514
+ let attachedList = attachedLists[iIdx];
515
+ // @ts-ignore
516
+ let table: AdminTable = attachedList.hotComponent;
496
517
 
497
- await table.refreshList ();
518
+ table.attachedEdit = this;
519
+
520
+ await table.refreshList ();
521
+ }
498
522
  }
499
523
 
500
524
  if (this.closeOnSave === true)
@@ -519,12 +543,17 @@ export class AdminEdit extends HotComponent
519
543
  {
520
544
  if (this.attached_list !== "")
521
545
  {
522
- let attachedList = document.getElementById (this.attached_list);
523
- // @ts-ignore
524
- let table: AdminTable = attachedList.hotComponent;
546
+ const attachedLists = this.getAttachedLists ();
547
+
548
+ for (let iIdx = 0; iIdx < attachedLists.length; iIdx++)
549
+ {
550
+ let attachedList = attachedLists[iIdx];
551
+ // @ts-ignore
552
+ let table: AdminTable = attachedList.hotComponent;
525
553
 
526
- if (table != null)
527
- table.attachedEdit = this;
554
+ if (table != null)
555
+ table.attachedEdit = this;
556
+ }
528
557
  }
529
558
  }, 50);
530
559
 
@@ -76,7 +76,7 @@ export class AdminTableField extends HotComponent
76
76
  }
77
77
 
78
78
  return ([{
79
- html: `<th>${this.inner}</th>`,
79
+ html: `<th data-field = "${this.field}" data-field-type = "${this.field_type}">${this.inner}</th>`,
80
80
  placeHereParent: "header"
81
81
  }]);
82
82
  }