adminforth 1.2.95 → 1.2.97

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 (115) hide show
  1. package/dataConnectors/baseConnector.ts +26 -14
  2. package/dataConnectors/clickhouse.ts +57 -37
  3. package/dataConnectors/mongo.ts +45 -14
  4. package/dataConnectors/postgres.ts +53 -36
  5. package/dataConnectors/sqlite.ts +37 -35
  6. package/dist/dataConnectors/baseConnector.js +16 -7
  7. package/dist/dataConnectors/clickhouse.js +58 -48
  8. package/dist/dataConnectors/mongo.js +29 -12
  9. package/dist/dataConnectors/postgres.js +62 -52
  10. package/dist/dataConnectors/sqlite.js +52 -45
  11. package/dist/index.js +5 -1
  12. package/dist/modules/operationalResource.js +88 -0
  13. package/dist/modules/restApi.js +27 -29
  14. package/dist/spa/index.html +4 -4
  15. package/dist/spa/package-lock.json +421 -6
  16. package/dist/spa/package.json +10 -2
  17. package/dist/spa/src/App.vue +236 -94
  18. package/dist/spa/src/assets/base.css +2 -0
  19. package/dist/spa/src/assets/logo.svg +19 -1
  20. package/dist/spa/src/components/AcceptModal.vue +3 -10
  21. package/dist/spa/src/components/Breadcrumbs.vue +3 -2
  22. package/dist/spa/src/components/BreadcrumbsWithButtons.vue +1 -1
  23. package/dist/spa/src/components/CustomDatePicker.vue +25 -10
  24. package/dist/spa/src/components/CustomDateRangePicker.vue +14 -5
  25. package/dist/spa/src/components/Dropdown.vue +19 -5
  26. package/dist/spa/src/components/Filters.vue +103 -38
  27. package/dist/spa/src/components/MenuLink.vue +3 -3
  28. package/dist/spa/src/components/ResourceForm.vue +205 -116
  29. package/dist/spa/{spa/src → src}/components/ResourceListTable.vue +6 -3
  30. package/dist/spa/{spa/src → src}/components/Toast.vue +9 -3
  31. package/dist/spa/src/components/ValueRenderer.vue +30 -8
  32. package/dist/spa/src/index.scss +2 -1
  33. package/dist/spa/src/main.ts +2 -2
  34. package/dist/spa/src/router/index.ts +29 -19
  35. package/dist/spa/src/stores/core.ts +65 -59
  36. package/dist/spa/src/stores/modal.ts +13 -3
  37. package/dist/spa/src/types/AdminForthConfig.ts +1477 -0
  38. package/dist/spa/src/types/FrontendAPI.ts +121 -0
  39. package/dist/spa/src/utils.ts +69 -10
  40. package/dist/spa/src/views/CreateView.vue +69 -16
  41. package/dist/spa/src/views/EditView.vue +68 -14
  42. package/dist/spa/src/views/ListView.vue +100 -371
  43. package/dist/spa/src/views/LoginView.vue +67 -29
  44. package/dist/spa/src/views/ResourceParent.vue +1 -2
  45. package/dist/spa/src/views/ShowView.vue +116 -25
  46. package/dist/spa/tailwind.config.js +8 -3
  47. package/dist/spa/vite.config.ts +13 -0
  48. package/dist/types/AdminForthConfig.js +37 -0
  49. package/index.ts +12 -3
  50. package/modules/operationalResource.ts +97 -0
  51. package/modules/restApi.ts +31 -31
  52. package/package.json +1 -1
  53. package/types/AdminForthConfig.ts +91 -8
  54. package/dist/spa/.vscode/extensions.json +0 -6
  55. package/dist/spa/public/favicon.ico +0 -0
  56. package/dist/spa/spa/.eslintrc.cjs +0 -14
  57. package/dist/spa/spa/.vscode/extensions.json +0 -6
  58. package/dist/spa/spa/README.md +0 -39
  59. package/dist/spa/spa/env.d.ts +0 -1
  60. package/dist/spa/spa/index.html +0 -23
  61. package/dist/spa/spa/package-lock.json +0 -4573
  62. package/dist/spa/spa/package.json +0 -49
  63. package/dist/spa/spa/postcss.config.js +0 -6
  64. package/dist/spa/spa/public/favicon.ico +0 -0
  65. package/dist/spa/spa/src/App.vue +0 -314
  66. package/dist/spa/spa/src/assets/base.css +0 -0
  67. package/dist/spa/spa/src/assets/logo.svg +0 -19
  68. package/dist/spa/spa/src/components/AcceptModal.vue +0 -45
  69. package/dist/spa/spa/src/components/Breadcrumbs.vue +0 -40
  70. package/dist/spa/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
  71. package/dist/spa/spa/src/components/CustomDatePicker.vue +0 -174
  72. package/dist/spa/spa/src/components/CustomDateRangePicker.vue +0 -218
  73. package/dist/spa/spa/src/components/Dropdown.vue +0 -168
  74. package/dist/spa/spa/src/components/Filters.vue +0 -222
  75. package/dist/spa/spa/src/components/HelloWorld.vue +0 -17
  76. package/dist/spa/spa/src/components/MenuLink.vue +0 -24
  77. package/dist/spa/spa/src/components/ResourceForm.vue +0 -289
  78. package/dist/spa/spa/src/components/SingleSkeletLoader.vue +0 -13
  79. package/dist/spa/spa/src/components/ValueRenderer.vue +0 -66
  80. package/dist/spa/spa/src/components/icons/IconCalendar.vue +0 -5
  81. package/dist/spa/spa/src/components/icons/IconCommunity.vue +0 -7
  82. package/dist/spa/spa/src/components/icons/IconDocumentation.vue +0 -7
  83. package/dist/spa/spa/src/components/icons/IconEcosystem.vue +0 -7
  84. package/dist/spa/spa/src/components/icons/IconSupport.vue +0 -7
  85. package/dist/spa/spa/src/components/icons/IconTime.vue +0 -5
  86. package/dist/spa/spa/src/components/icons/IconTooling.vue +0 -19
  87. package/dist/spa/spa/src/index.scss +0 -27
  88. package/dist/spa/spa/src/main.ts +0 -18
  89. package/dist/spa/spa/src/router/index.ts +0 -63
  90. package/dist/spa/spa/src/stores/core.ts +0 -144
  91. package/dist/spa/spa/src/stores/modal.ts +0 -48
  92. package/dist/spa/spa/src/utils.ts +0 -103
  93. package/dist/spa/spa/src/views/CreateView.vue +0 -156
  94. package/dist/spa/spa/src/views/EditView.vue +0 -157
  95. package/dist/spa/spa/src/views/HomeView.vue +0 -8
  96. package/dist/spa/spa/src/views/ListView.vue +0 -258
  97. package/dist/spa/spa/src/views/LoginView.vue +0 -143
  98. package/dist/spa/spa/src/views/ResourceParent.vue +0 -17
  99. package/dist/spa/spa/src/views/ShowView.vue +0 -184
  100. package/dist/spa/spa/tailwind.config.js +0 -17
  101. package/dist/spa/spa/tsconfig.app.json +0 -14
  102. package/dist/spa/spa/tsconfig.json +0 -11
  103. package/dist/spa/spa/tsconfig.node.json +0 -19
  104. package/dist/spa/spa/vite.config.ts +0 -56
  105. package/dist/spa/src/views/HomeView.vue +0 -8
  106. package/dist/types.js +0 -30
  107. /package/dist/spa/{spa/public → public}/assets/favicon.png +0 -0
  108. /package/dist/spa/{spa/src → src}/components/CustomRangePicker.vue +0 -0
  109. /package/dist/spa/{spa/src → src}/components/SkeleteLoader.vue +0 -0
  110. /package/dist/spa/{spa/src → src}/composables/useFrontendApi.ts +0 -0
  111. /package/dist/spa/{spa/src → src}/composables/useStores.ts +0 -0
  112. /package/dist/spa/{spa/src → src}/spa_types/core.ts +0 -0
  113. /package/dist/spa/{spa/src → src}/stores/filters.ts +0 -0
  114. /package/dist/spa/{spa/src → src}/stores/toast.ts +0 -0
  115. /package/dist/spa/{spa/src → src}/stores/user.ts +0 -0
@@ -21,6 +21,32 @@ import { ADMINFORTH_VERSION, listify } from './utils.js';
21
21
 
22
22
  import AdminForthAuth from "../auth.js";
23
23
 
24
+
25
+ export async function interpretResource(adminUser: AdminUser, resource: AdminForthResource, meta: any, source: ActionCheckSource): Promise<{allowedActions: AllowedActionsResolved}> {
26
+ // if (process.env.HEAVY_DEBUG) {
27
+ // console.log('🪲Interpreting resource', resource.resourceId, source, 'adminUser', adminUser);
28
+ // }
29
+ const allowedActions = {};
30
+
31
+ await Promise.all(
32
+ Object.entries(resource.options?.allowedActions || {}).map(
33
+ async ([key, value]: [string, AllowedActionValue]) => {
34
+ if (process.env.HEAVY_DEBUG) {
35
+ console.log('🪲checking for allowed call', key, 'value:', value, 'typeof', typeof value);
36
+ }
37
+
38
+ // if callable then call
39
+ if (typeof value === 'function') {
40
+ allowedActions[key] = await value({ adminUser, resource, meta, source });
41
+ } else {
42
+ allowedActions[key] = value;
43
+ }
44
+ })
45
+ );
46
+
47
+ return { allowedActions };
48
+ }
49
+
24
50
  export default class AdminForthRestAPI {
25
51
 
26
52
  adminforth: IAdminForth;
@@ -188,13 +214,10 @@ export default class AdminForthRestAPI {
188
214
  }
189
215
 
190
216
  async function processMenuItem(menuItem) {
191
- console.log('super hueta')
192
-
193
217
  if (menuItem.badge) {
194
- console.log('hueta')
195
- // if (typeof menuItem.badge !== 'string') {
218
+ if (typeof menuItem.badge === 'function') {
196
219
  menuItem.badge = await menuItem.badge(adminUser);
197
- // }
220
+ }
198
221
  }
199
222
  }
200
223
  let newMenu = []
@@ -214,12 +237,12 @@ export default class AdminForthRestAPI {
214
237
  continue
215
238
  }
216
239
  }
217
- processMenuItem(newChild)
240
+ await processMenuItem(newChild)
218
241
  newChildren.push(newChild)
219
242
  }
220
243
  newMenuItem = {...newMenuItem, children: newChildren}
221
244
  }
222
- processMenuItem(newMenuItem)
245
+ await processMenuItem(newMenuItem)
223
246
  newMenu.push(newMenuItem)
224
247
  }
225
248
 
@@ -249,30 +272,7 @@ export default class AdminForthRestAPI {
249
272
  },
250
273
  });
251
274
 
252
- async function interpretResource(adminUser: AdminUser, resource: AdminForthResource, meta: any, source: ActionCheckSource): Promise<{allowedActions: AllowedActionsResolved}> {
253
- // if (process.env.HEAVY_DEBUG) {
254
- // console.log('🪲Interpreting resource', resource.resourceId, source, 'adminUser', adminUser);
255
- // }
256
- const allowedActions = {};
257
-
258
- await Promise.all(
259
- Object.entries(resource.options?.allowedActions || {}).map(
260
- async ([key, value]: [string, AllowedActionValue]) => {
261
- if (process.env.HEAVY_DEBUG) {
262
- console.log('🪲checking for allowed call', key, 'value:', value, 'typeof', typeof value);
263
- }
264
-
265
- // if callable then call
266
- if (typeof value === 'function') {
267
- allowedActions[key] = await value({ adminUser, resource, meta, source });
268
- } else {
269
- allowedActions[key] = value;
270
- }
271
- })
272
- );
273
-
274
- return { allowedActions };
275
- }
275
+
276
276
 
277
277
  function checkAccess(action: AllowedActionsEnum, allowedActions: AllowedActions): { allowed: boolean, error?: string } {
278
278
  const allowed = (allowedActions[action] as boolean | string | undefined);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "1.2.95",
3
+ "version": "1.2.97",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,6 @@
1
1
  import type { Express } from 'express';
2
+ import AdminForth from '../index.js';
3
+ import exp from 'constants';
2
4
 
3
5
  export interface ICodeInjector {
4
6
  srcFoldersToSync: Object;
@@ -90,6 +92,17 @@ export interface IExpressHttpServer extends IHttpServer {
90
92
  authorize(callable: Function): void;
91
93
  }
92
94
 
95
+ export interface IAdminForthFilter {
96
+ field: string;
97
+ operator: AdminForthFilterOperators;
98
+ value: any;
99
+ }
100
+
101
+ export interface IAdminForthSort {
102
+ field: string,
103
+ direction: AdminForthSortDirections
104
+ }
105
+
93
106
  export interface IAdminForthDataSourceConnector {
94
107
 
95
108
  /**
@@ -145,15 +158,21 @@ export interface IAdminForthDataSourceConnector {
145
158
  *
146
159
  * Fields are returned from db "as is" then {@link AdminForthBaseConnector.getData} will transform each field using {@link IAdminForthDataSourceConnector.getFieldValue}
147
160
  */
148
- getDataWithOriginalTypes({ resource, limit, offset, sort, filters, getTotals }: {
161
+ getDataWithOriginalTypes({ resource, limit, offset, sort, filters }: {
149
162
  resource: AdminForthResource,
150
163
  limit: number,
151
164
  offset: number,
152
- sort: { field: string, direction: AdminForthSortDirections }[],
153
- filters: { field: string, operator: AdminForthFilterOperators, value: any }[],
154
- getTotals?: boolean
155
- }): Promise<{data: Array<any>, total: number}>;
165
+ sort: IAdminForthSort[],
166
+ filters: IAdminForthFilter[],
167
+ }): Promise<Array<any>>;
156
168
 
169
+ /**
170
+ * Used to get count of records in database.
171
+ */
172
+ getCount({ resource, filters }: {
173
+ resource: AdminForthResource,
174
+ filters: IAdminForthFilter[],
175
+ }): Promise<number>;
157
176
 
158
177
  /**
159
178
  * Optional method which used to get min and max values for columns in resource.
@@ -181,7 +200,7 @@ export interface IAdminForthDataSourceConnector {
181
200
  /**
182
201
  * Used to delete record in database.
183
202
  */
184
- deleteRecord({ resource, recordId }: { resource: AdminForthResource, recordId: any }): Promise<void>;
203
+ deleteRecord({ resource, recordId }: { resource: AdminForthResource, recordId: any }): Promise<boolean>;
185
204
  }
186
205
 
187
206
 
@@ -196,12 +215,15 @@ export interface IAdminForthDataSourceConnectorBase extends IAdminForthDataSourc
196
215
  resource: AdminForthResource,
197
216
  limit: number,
198
217
  offset: number,
199
- sort: { field: string, direction: AdminForthSortDirections }[],
200
- filters: { field: string, operator: AdminForthFilterOperators, value: any }[]
218
+ sort: IAdminForthSort[],
219
+ filters: IAdminForthFilter[],
220
+ getTotals?: boolean,
201
221
  }): Promise<{ data: Array<any>, total: number }>;
202
222
 
203
223
  getRecordByPrimaryKey(resource: AdminForthResource, recordId: string): Promise<any>;
204
224
 
225
+ createRecord({ resource, record }: { resource: AdminForthResource, record: any }): Promise<void>;
226
+
205
227
  getMinMaxForColumns({ resource, columns }: { resource: AdminForthResource, columns: AdminForthResourceColumn[] }): Promise<{ [key: string]: { min: any, max: any } }>;
206
228
  }
207
229
 
@@ -1306,6 +1328,67 @@ export type AdminForthConfig = {
1306
1328
 
1307
1329
 
1308
1330
  }
1331
+
1332
+ // define typescript objects which I can instantiate as Filters.EQ(field, value) and they woudl
1333
+ // return { field: field, operator: 'eq', value: value }. They should be exported with Filters namespace so I can import Filters from this file
1334
+ // and use Filters.EQ(field, value) in my code
1335
+
1336
+ export type FDataFilter = (field: string, value: any) => IAdminForthFilter;
1337
+
1338
+ export class Filters {
1339
+ static EQ(field: string, value: any): IAdminForthFilter {
1340
+ return { field, operator: AdminForthFilterOperators.EQ, value };
1341
+ }
1342
+ static NEQ(field: string, value: any): IAdminForthFilter {
1343
+ return { field, operator: AdminForthFilterOperators.NE, value };
1344
+ }
1345
+ static GT(field: string, value: any): IAdminForthFilter {
1346
+ return { field, operator: AdminForthFilterOperators.GT, value };
1347
+ }
1348
+ static GTE(field: string, value: any): IAdminForthFilter {
1349
+ return { field, operator: AdminForthFilterOperators.GTE, value };
1350
+ }
1351
+ static LT(field: string, value: any): IAdminForthFilter {
1352
+ return { field, operator: AdminForthFilterOperators.LT, value };
1353
+ }
1354
+ static LTE(field: string, value: any): IAdminForthFilter {
1355
+ return { field, operator: AdminForthFilterOperators.LTE, value };
1356
+ }
1357
+ static IN(field: string, value: any): IAdminForthFilter {
1358
+ return { field, operator: AdminForthFilterOperators.IN, value };
1359
+ }
1360
+ static NOT_IN(field: string, value: any): IAdminForthFilter {
1361
+ return { field, operator: AdminForthFilterOperators.NIN, value };
1362
+ }
1363
+ static LIKE(field: string, value: any): IAdminForthFilter {
1364
+ return { field, operator: AdminForthFilterOperators.LIKE, value };
1365
+ }
1366
+ }
1367
+
1368
+ export type FDataSort = (field: string, direction: AdminForthSortDirections) => IAdminForthSort;
1369
+
1370
+ export class Sorts {
1371
+ static ASC(field: string): IAdminForthSort {
1372
+ return { field, direction: AdminForthSortDirections.asc };
1373
+ }
1374
+ static DESC(field: string): IAdminForthSort {
1375
+ return { field, direction: AdminForthSortDirections.desc };
1376
+ }
1377
+ }
1378
+
1379
+ export interface IOperationalResource {
1380
+ get: (filter: IAdminForthFilter | IAdminForthFilter[]) => Promise<any[]>;
1381
+
1382
+ list: (filter: IAdminForthFilter | IAdminForthFilter[], limit: number, offset: number, sort: IAdminForthSort | IAdminForthSort[]) => Promise<any[]>;
1383
+
1384
+ count: (filter: IAdminForthFilter | IAdminForthFilter[]) => Promise<number>;
1385
+
1386
+ create: (record: any) => Promise<any>;
1387
+
1388
+ update: (primaryKey: any, record: any) => Promise<any>;
1389
+
1390
+ delete: (primaryKey: any) => Promise<boolean>;
1391
+ }
1309
1392
 
1310
1393
 
1311
1394
  export enum AllowedActionsEnum {
@@ -1,6 +0,0 @@
1
- {
2
- "recommendations": [
3
- "Vue.volar",
4
- "dbaeumer.vscode-eslint"
5
- ]
6
- }
Binary file
@@ -1,14 +0,0 @@
1
- /* eslint-env node */
2
- require('@rushstack/eslint-patch/modern-module-resolution')
3
-
4
- module.exports = {
5
- root: true,
6
- 'extends': [
7
- 'plugin:vue/vue3-essential',
8
- 'eslint:recommended',
9
- '@vue/eslint-config-typescript'
10
- ],
11
- parserOptions: {
12
- ecmaVersion: 'latest'
13
- }
14
- }
@@ -1,6 +0,0 @@
1
- {
2
- "recommendations": [
3
- "Vue.volar",
4
- "dbaeumer.vscode-eslint"
5
- ]
6
- }
@@ -1,39 +0,0 @@
1
- # spa
2
-
3
- This template should help get you started developing with Vue 3 in Vite.
4
-
5
- ## Recommended IDE Setup
6
-
7
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
8
-
9
- ## Type Support for `.vue` Imports in TS
10
-
11
- TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
12
-
13
- ## Customize configuration
14
-
15
- See [Vite Configuration Reference](https://vitejs.dev/config/).
16
-
17
- ## Project Setup
18
-
19
- ```sh
20
- npm install
21
- ```
22
-
23
- ### Compile and Hot-Reload for Development
24
-
25
- ```sh
26
- npm run dev
27
- ```
28
-
29
- ### Type-Check, Compile and Minify for Production
30
-
31
- ```sh
32
- npm run build
33
- ```
34
-
35
- ### Lint with [ESLint](https://eslint.org/)
36
-
37
- ```sh
38
- npm run lint
39
- ```
@@ -1 +0,0 @@
1
- /// <reference types="vite/client" />
@@ -1,23 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <link rel="icon" href="/* IMPORTANT:ADMINFORTH FAVICON */">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>/* IMPORTANT:ADMINFORTH TITLE */</title>
8
- <!--
9
- <script>
10
- // On page load or when changing themes, best to add inline in `head` to avoid FOUC
11
- if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
12
- document.documentElement.classList.add('dark');
13
- } else {
14
- document.documentElement.classList.remove('dark')
15
- }
16
- </script> -->
17
-
18
- </head>
19
- <body class=" ">
20
- <div id="app" class="min-h-screen bg-lightHtml dark:bg-darkHtml"></div>
21
- <script type="module" src="/src/main.ts"></script>
22
- </body>
23
- </html>