adminforth 1.3.54-next.9 → 1.3.55-next.2

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 (224) hide show
  1. package/dist/auth.d.ts +31 -0
  2. package/dist/auth.d.ts.map +1 -0
  3. package/dist/auth.js +42 -56
  4. package/dist/auth.js.map +1 -0
  5. package/dist/basePlugin.d.ts +18 -0
  6. package/dist/basePlugin.d.ts.map +1 -0
  7. package/dist/basePlugin.js +1 -0
  8. package/dist/basePlugin.js.map +1 -0
  9. package/dist/dataConnectors/baseConnector.d.ts +94 -0
  10. package/dist/dataConnectors/baseConnector.d.ts.map +1 -0
  11. package/dist/dataConnectors/baseConnector.js +108 -122
  12. package/dist/dataConnectors/baseConnector.js.map +1 -0
  13. package/dist/dataConnectors/clickhouse.d.ts +92 -0
  14. package/dist/dataConnectors/clickhouse.d.ts.map +1 -0
  15. package/dist/dataConnectors/clickhouse.js +132 -149
  16. package/dist/dataConnectors/clickhouse.js.map +1 -0
  17. package/dist/dataConnectors/mongo.d.ts +93 -0
  18. package/dist/dataConnectors/mongo.d.ts.map +1 -0
  19. package/dist/dataConnectors/mongo.js +75 -101
  20. package/dist/dataConnectors/mongo.js.map +1 -0
  21. package/dist/dataConnectors/postgres.d.ts +71 -0
  22. package/dist/dataConnectors/postgres.d.ts.map +1 -0
  23. package/dist/dataConnectors/postgres.js +124 -143
  24. package/dist/dataConnectors/postgres.js.map +1 -0
  25. package/dist/dataConnectors/sqlite.d.ts +67 -0
  26. package/dist/dataConnectors/sqlite.d.ts.map +1 -0
  27. package/dist/dataConnectors/sqlite.js +113 -130
  28. package/dist/dataConnectors/sqlite.js.map +1 -0
  29. package/dist/index.d.ts +92 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +197 -217
  32. package/dist/index.js.map +1 -0
  33. package/dist/modules/codeInjector.d.ts +35 -0
  34. package/dist/modules/codeInjector.d.ts.map +1 -0
  35. package/dist/modules/codeInjector.js +480 -486
  36. package/dist/modules/codeInjector.js.map +1 -0
  37. package/dist/modules/configValidator.d.ts +12 -0
  38. package/dist/modules/configValidator.d.ts.map +1 -0
  39. package/dist/modules/configValidator.js +31 -22
  40. package/dist/modules/configValidator.js.map +1 -0
  41. package/dist/modules/operationalResource.d.ts +17 -0
  42. package/dist/modules/operationalResource.d.ts.map +1 -0
  43. package/dist/modules/operationalResource.js +50 -70
  44. package/dist/modules/operationalResource.js.map +1 -0
  45. package/dist/modules/restApi.d.ts +10 -0
  46. package/dist/modules/restApi.d.ts.map +1 -0
  47. package/dist/modules/restApi.js +104 -116
  48. package/dist/modules/restApi.js.map +1 -0
  49. package/dist/modules/styleGenerator.d.ts +9 -0
  50. package/dist/modules/styleGenerator.d.ts.map +1 -0
  51. package/dist/modules/styleGenerator.js +1 -0
  52. package/dist/modules/styleGenerator.js.map +1 -0
  53. package/dist/modules/styles.d.ts +96 -0
  54. package/dist/modules/styles.d.ts.map +1 -0
  55. package/dist/modules/styles.js +1 -0
  56. package/dist/modules/styles.js.map +1 -0
  57. package/dist/modules/utils.d.ts +39 -0
  58. package/dist/modules/utils.d.ts.map +1 -0
  59. package/dist/modules/utils.js +1 -0
  60. package/dist/modules/utils.js.map +1 -0
  61. package/dist/plugins/audit-log/types.d.ts +35 -0
  62. package/dist/plugins/audit-log/types.d.ts.map +1 -0
  63. package/dist/plugins/audit-log/types.js +2 -0
  64. package/dist/plugins/audit-log/types.js.map +1 -0
  65. package/dist/plugins/chat-gpt/types.d.ts +82 -0
  66. package/dist/plugins/chat-gpt/types.d.ts.map +1 -0
  67. package/dist/plugins/chat-gpt/types.js +2 -0
  68. package/dist/plugins/chat-gpt/types.js.map +1 -0
  69. package/dist/plugins/email-password-reset/types.d.ts +28 -0
  70. package/dist/plugins/email-password-reset/types.d.ts.map +1 -0
  71. package/dist/plugins/email-password-reset/types.js +2 -0
  72. package/dist/plugins/email-password-reset/types.js.map +1 -0
  73. package/dist/plugins/foreign-inline-list/types.d.ts +19 -0
  74. package/dist/plugins/foreign-inline-list/types.d.ts.map +1 -0
  75. package/dist/plugins/foreign-inline-list/types.js +2 -0
  76. package/dist/plugins/foreign-inline-list/types.js.map +1 -0
  77. package/dist/plugins/import-export/types.d.ts +3 -0
  78. package/dist/plugins/import-export/types.d.ts.map +1 -0
  79. package/dist/plugins/import-export/types.js +2 -0
  80. package/dist/plugins/import-export/types.js.map +1 -0
  81. package/dist/plugins/rich-editor/custom/async-queue.d.ts +8 -0
  82. package/dist/plugins/rich-editor/custom/async-queue.d.ts.map +1 -0
  83. package/dist/plugins/rich-editor/custom/async-queue.js +29 -0
  84. package/dist/plugins/rich-editor/custom/async-queue.js.map +1 -0
  85. package/dist/plugins/rich-editor/dist/custom/async-queue.d.ts +8 -0
  86. package/dist/plugins/rich-editor/dist/custom/async-queue.d.ts.map +1 -0
  87. package/dist/plugins/rich-editor/dist/custom/async-queue.js +29 -0
  88. package/dist/plugins/rich-editor/dist/custom/async-queue.js.map +1 -0
  89. package/dist/plugins/rich-editor/types.d.ts +153 -0
  90. package/dist/plugins/rich-editor/types.d.ts.map +1 -0
  91. package/dist/plugins/rich-editor/types.js +16 -0
  92. package/dist/plugins/rich-editor/types.js.map +1 -0
  93. package/dist/plugins/two-factors-auth/types.d.ts +18 -0
  94. package/dist/plugins/two-factors-auth/types.d.ts.map +1 -0
  95. package/dist/plugins/two-factors-auth/types.js +2 -0
  96. package/dist/plugins/two-factors-auth/types.js.map +1 -0
  97. package/dist/plugins/upload/types.d.ts +132 -0
  98. package/dist/plugins/upload/types.d.ts.map +1 -0
  99. package/dist/plugins/upload/types.js +2 -0
  100. package/dist/plugins/upload/types.js.map +1 -0
  101. package/dist/servers/express.d.ts +18 -0
  102. package/dist/servers/express.d.ts.map +1 -0
  103. package/dist/servers/express.js +30 -42
  104. package/dist/servers/express.js.map +1 -0
  105. package/dist/spa/index.html +2 -2
  106. package/dist/spa/package-lock.json +87 -1
  107. package/dist/spa/package.json +4 -1
  108. package/dist/spa/src/App.vue +154 -50
  109. package/dist/spa/src/components/AcceptModal.vue +1 -1
  110. package/dist/spa/src/components/Breadcrumbs.vue +1 -1
  111. package/dist/spa/src/components/CustomDatePicker.vue +1 -1
  112. package/dist/spa/src/components/CustomDateRangePicker.vue +1 -1
  113. package/dist/spa/src/components/CustomRangePicker.vue +9 -5
  114. package/dist/spa/src/components/Dropdown.vue +4 -4
  115. package/dist/spa/src/components/Filters.vue +2 -2
  116. package/dist/spa/src/components/MenuLink.vue +3 -0
  117. package/dist/spa/src/components/ResourceForm.vue +67 -36
  118. package/dist/spa/src/components/ResourceListTable.vue +216 -144
  119. package/dist/spa/src/components/SkeleteLoader.vue +4 -4
  120. package/dist/spa/src/components/Toast.vue +3 -2
  121. package/dist/spa/src/components/ValueRenderer.vue +81 -6
  122. package/dist/spa/src/composables/useFrontendApi.ts +1 -1
  123. package/dist/spa/src/composables/useStores.ts +18 -14
  124. package/dist/spa/src/index.scss +4 -0
  125. package/{spa → dist/spa}/src/renderers/CompactUUID.vue +4 -4
  126. package/{spa → dist/spa}/src/renderers/CountryFlag.vue +2 -2
  127. package/dist/spa/src/router/index.ts +4 -8
  128. package/dist/spa/src/spa_types/core.ts +2 -0
  129. package/dist/spa/src/stores/core.ts +6 -2
  130. package/dist/spa/src/stores/filters.ts +15 -10
  131. package/dist/spa/src/stores/toast.ts +22 -6
  132. package/dist/spa/src/types/AdminForthConfig.ts +340 -55
  133. package/dist/spa/src/types/FrontendAPI.ts +52 -30
  134. package/dist/spa/src/utils.ts +59 -2
  135. package/dist/spa/src/views/CreateView.vue +15 -4
  136. package/dist/spa/src/views/EditView.vue +20 -7
  137. package/dist/spa/src/views/ListView.vue +132 -38
  138. package/dist/spa/src/views/LoginView.vue +50 -18
  139. package/dist/spa/src/views/ShowView.vue +25 -15
  140. package/dist/types/AdminForthConfig.d.ts +1619 -0
  141. package/dist/types/AdminForthConfig.d.ts.map +1 -0
  142. package/dist/types/AdminForthConfig.js +1 -0
  143. package/dist/types/AdminForthConfig.js.map +1 -0
  144. package/{types/FrontendAPI.ts → dist/types/FrontendAPI.d.ts} +27 -52
  145. package/dist/types/FrontendAPI.d.ts.map +1 -0
  146. package/dist/types/FrontendAPI.js +1 -0
  147. package/dist/types/FrontendAPI.js.map +1 -0
  148. package/package.json +16 -6
  149. package/auth.ts +0 -140
  150. package/basePlugin.ts +0 -70
  151. package/dataConnectors/baseConnector.ts +0 -216
  152. package/dataConnectors/clickhouse.ts +0 -338
  153. package/dataConnectors/mongo.ts +0 -202
  154. package/dataConnectors/postgres.ts +0 -306
  155. package/dataConnectors/sqlite.ts +0 -254
  156. package/index.ts +0 -428
  157. package/modules/codeInjector.ts +0 -736
  158. package/modules/configValidator.ts +0 -571
  159. package/modules/operationalResource.ts +0 -98
  160. package/modules/restApi.ts +0 -718
  161. package/modules/styleGenerator.ts +0 -55
  162. package/modules/styles.ts +0 -126
  163. package/modules/utils.ts +0 -472
  164. package/servers/express.ts +0 -259
  165. package/spa/.eslintrc.cjs +0 -14
  166. package/spa/README.md +0 -39
  167. package/spa/env.d.ts +0 -1
  168. package/spa/index.html +0 -23
  169. package/spa/package-lock.json +0 -4602
  170. package/spa/package.json +0 -51
  171. package/spa/postcss.config.js +0 -6
  172. package/spa/public/assets/favicon.png +0 -0
  173. package/spa/src/App.vue +0 -418
  174. package/spa/src/assets/base.css +0 -2
  175. package/spa/src/assets/logo.svg +0 -19
  176. package/spa/src/components/AcceptModal.vue +0 -45
  177. package/spa/src/components/Breadcrumbs.vue +0 -41
  178. package/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
  179. package/spa/src/components/CustomDatePicker.vue +0 -176
  180. package/spa/src/components/CustomDateRangePicker.vue +0 -218
  181. package/spa/src/components/CustomRangePicker.vue +0 -156
  182. package/spa/src/components/Dropdown.vue +0 -168
  183. package/spa/src/components/Filters.vue +0 -222
  184. package/spa/src/components/HelloWorld.vue +0 -17
  185. package/spa/src/components/MenuLink.vue +0 -27
  186. package/spa/src/components/ResourceForm.vue +0 -290
  187. package/spa/src/components/ResourceListTable.vue +0 -466
  188. package/spa/src/components/SingleSkeletLoader.vue +0 -13
  189. package/spa/src/components/SkeleteLoader.vue +0 -23
  190. package/spa/src/components/Toast.vue +0 -78
  191. package/spa/src/components/ValueRenderer.vue +0 -114
  192. package/spa/src/components/icons/IconCalendar.vue +0 -5
  193. package/spa/src/components/icons/IconCommunity.vue +0 -7
  194. package/spa/src/components/icons/IconDocumentation.vue +0 -7
  195. package/spa/src/components/icons/IconEcosystem.vue +0 -7
  196. package/spa/src/components/icons/IconSupport.vue +0 -7
  197. package/spa/src/components/icons/IconTime.vue +0 -5
  198. package/spa/src/components/icons/IconTooling.vue +0 -19
  199. package/spa/src/composables/useFrontendApi.ts +0 -26
  200. package/spa/src/composables/useStores.ts +0 -131
  201. package/spa/src/index.scss +0 -31
  202. package/spa/src/main.ts +0 -18
  203. package/spa/src/router/index.ts +0 -59
  204. package/spa/src/spa_types/core.ts +0 -53
  205. package/spa/src/stores/core.ts +0 -148
  206. package/spa/src/stores/filters.ts +0 -27
  207. package/spa/src/stores/modal.ts +0 -48
  208. package/spa/src/stores/toast.ts +0 -31
  209. package/spa/src/stores/user.ts +0 -72
  210. package/spa/src/utils.ts +0 -160
  211. package/spa/src/views/CreateView.vue +0 -167
  212. package/spa/src/views/EditView.vue +0 -170
  213. package/spa/src/views/ListView.vue +0 -352
  214. package/spa/src/views/LoginView.vue +0 -192
  215. package/spa/src/views/ResourceParent.vue +0 -17
  216. package/spa/src/views/ShowView.vue +0 -186
  217. package/spa/tailwind.config.js +0 -17
  218. package/spa/tsconfig.app.json +0 -14
  219. package/spa/tsconfig.json +0 -11
  220. package/spa/tsconfig.node.json +0 -19
  221. package/spa/vite.config.ts +0 -56
  222. package/tsconfig.json +0 -112
  223. package/types/AdminForthConfig.ts +0 -1762
  224. /package/{spa → dist/spa}/src/components/ThreeDotsMenu.vue +0 -0
@@ -1,4 +1,5 @@
1
- import { Express } from 'express';
1
+ import type { Express } from 'express';
2
+ import type { Writable } from 'stream';
2
3
 
3
4
  export interface ICodeInjector {
4
5
  srcFoldersToSync: Object;
@@ -13,6 +14,7 @@ export interface IConfigValidator {
13
14
  export interface IAdminForthHttpResponse {
14
15
  setHeader: (key: string, value: string) => void,
15
16
  setStatus: (code: number, message: string) => void,
17
+ blobStream: () => Writable,
16
18
  };
17
19
 
18
20
  /**
@@ -51,16 +53,18 @@ export interface IHttpServer {
51
53
 
52
54
  export type AdminUser = {
53
55
  /**
54
- * primaryKey field value of user in table which is defined by {@link AdminForthConfig.auth.resourceId}
55
- * or null if it is user logged in as {@link AdminForthConfig.rootUser}
56
+ * primaryKey field value of user in table which is defined by {@link AdminForthConfig.auth.usersResourceId}
56
57
  */
57
58
  pk: string | null,
58
59
 
59
60
  /**
60
- * Username which takend from {@link AdminForthConfig.auth.usernameField} field in user resource {@link AdminForthConfig.auth.resourceId}
61
+ * Username which taken from {@link AdminForthConfig.auth.usernameField} field in user resource {@link AdminForthConfig.auth.usersResourceId}
61
62
  */
62
63
  username: string,
63
- isRoot: boolean,
64
+
65
+ /**
66
+ * User record fetched from database, from resource defined in {@link AdminForthConfig.auth.usersResourceId}
67
+ */
64
68
  dbUser: any,
65
69
  }
66
70
 
@@ -90,6 +94,17 @@ export interface IExpressHttpServer extends IHttpServer {
90
94
  authorize(callable: Function): void;
91
95
  }
92
96
 
97
+ export interface IAdminForthFilter {
98
+ field: string;
99
+ operator: AdminForthFilterOperators;
100
+ value: any;
101
+ }
102
+
103
+ export interface IAdminForthSort {
104
+ field: string,
105
+ direction: AdminForthSortDirections
106
+ }
107
+
93
108
  export interface IAdminForthDataSourceConnector {
94
109
 
95
110
  /**
@@ -145,15 +160,21 @@ export interface IAdminForthDataSourceConnector {
145
160
  *
146
161
  * Fields are returned from db "as is" then {@link AdminForthBaseConnector.getData} will transform each field using {@link IAdminForthDataSourceConnector.getFieldValue}
147
162
  */
148
- getDataWithOriginalTypes({ resource, limit, offset, sort, filters, getTotals }: {
163
+ getDataWithOriginalTypes({ resource, limit, offset, sort, filters }: {
149
164
  resource: AdminForthResource,
150
165
  limit: number,
151
166
  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}>;
167
+ sort: IAdminForthSort[],
168
+ filters: IAdminForthFilter[],
169
+ }): Promise<Array<any>>;
156
170
 
171
+ /**
172
+ * Used to get count of records in database.
173
+ */
174
+ getCount({ resource, filters }: {
175
+ resource: AdminForthResource,
176
+ filters: IAdminForthFilter[],
177
+ }): Promise<number>;
157
178
 
158
179
  /**
159
180
  * Optional method which used to get min and max values for columns in resource.
@@ -170,18 +191,16 @@ export interface IAdminForthDataSourceConnector {
170
191
  createRecordOriginalValues({ resource, record }: { resource: AdminForthResource, record: any }): Promise<void>;
171
192
 
172
193
  /**
173
- * Used to update record in database.
194
+ * Update record in database. newValues might have not all fields in record, but only changed ones.
174
195
  * recordId is value of field which is marked as {@link AdminForthResourceColumn.primaryKey}
175
- * newValues is array of fields which should be updated (might be not all fields in record, but only changed fields).
176
196
  */
177
- updateRecord({ resource, recordId, newValues }:
178
- { resource: AdminForthResource, recordId: string, newValues: any }
179
- ): Promise<void>;
180
-
197
+ updateRecordOriginalValues({ resource, recordId, newValues }: { resource: AdminForthResource; recordId: string; newValues: any; }): Promise<void>;
198
+
199
+
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,27 +215,40 @@ 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, adminUser }: {
226
+ resource: AdminForthResource,
227
+ record: any
228
+ adminUser: AdminUser
229
+ }): Promise<{ok: boolean, error?: string, createdRecord?: any}>;
230
+
231
+ updateRecord({ resource, recordId, newValues }: {
232
+ resource: AdminForthResource,
233
+ recordId: string,
234
+ newValues: any,
235
+ }): Promise<{ok: boolean, error?: string}>;
236
+
205
237
  getMinMaxForColumns({ resource, columns }: { resource: AdminForthResource, columns: AdminForthResourceColumn[] }): Promise<{ [key: string]: { min: any, max: any } }>;
206
238
  }
207
239
 
208
240
 
209
241
  export interface IAdminForthDataSourceConnectorConstructor {
210
- new ({ url }: { url: string }): IAdminForthDataSourceConnector;
242
+ new ({ url }: { url: string }): IAdminForthDataSourceConnectorBase;
211
243
  }
212
244
 
213
245
  export interface IAdminForthAuth {
214
- verify(jwt : string, mustHaveType: string): Promise<any>;
215
- issueJWT(payload: Object, type: string): string;
246
+ verify(jwt : string, mustHaveType: string, decodeUser?: boolean): Promise<any>;
247
+ issueJWT(payload: Object, type: string, expiresIn?: string): string;
216
248
 
217
249
  removeCustomCookie({response, name}: {response: any, name: string}): void;
218
250
 
219
- setAuthCookie({response, username, pk,}: {response: any, username: string, pk: string}): void;
251
+ setAuthCookie({expireInDays, response, username, pk,}: {expireInDays?: number, response: any, username: string, pk: string}): void;
220
252
 
221
253
  removeAuthCookie(response: any): void;
222
254
  }
@@ -238,7 +270,17 @@ export interface IAdminForth {
238
270
  [key: string]: IAdminForthDataSourceConnectorBase;
239
271
  };
240
272
 
241
- createResourceRecord(params: { resource: AdminForthResource, record: any, adminUser: AdminUser }): Promise<any>;
273
+ createResourceRecord(
274
+ params: { resource: AdminForthResource, record: any, adminUser: AdminUser }
275
+ ): Promise<{ error?: string, createdRecord?: any }>;
276
+
277
+ updateResourceRecord(
278
+ params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser }
279
+ ): Promise<{ error?: string }>;
280
+
281
+ deleteResourceRecord(
282
+ params: { resource: AdminForthResource, recordId: string, adminUser: AdminUser, record: any }
283
+ ): Promise<{ error?: string }>;
242
284
 
243
285
  auth: IAdminForthAuth;
244
286
 
@@ -263,6 +305,11 @@ export interface IAdminForth {
263
305
  */
264
306
  bundleNow({ hotReload, verbose }: { hotReload: boolean, verbose: boolean }): Promise<void>;
265
307
 
308
+ /**
309
+ * Resource to get access to operational resources for data api fetching and manipulation.
310
+ */
311
+ resource(resourceId: string): IOperationalResource;
312
+
266
313
  /**
267
314
  * This method will be automatically called from AdminForth HTTP adapter to serve AdminForth SPA.
268
315
  */
@@ -277,6 +324,15 @@ export interface IAdminForthPlugin {
277
324
  pluginInstanceId: string;
278
325
  customFolderPath: string;
279
326
  pluginOptions: any;
327
+ resourceConfig: AdminForthResource;
328
+ className: string;
329
+
330
+ /**
331
+ * Before activating all plugins are sorted by this number and then activated in order.
332
+ * If you want to make sure that your plugin is activated after some other plugin, set this number to higher value. (default is 0)
333
+ */
334
+ activationOrder: number;
335
+
280
336
 
281
337
  /**
282
338
  * AdminForth plugins concept is based on modification of full AdminForth configuration
@@ -461,6 +517,12 @@ export type AdminForthConfigMenuItem = {
461
517
  * You can use it to hide menu items depending on some user
462
518
  */
463
519
  visible?: (user: AdminUser) => boolean,
520
+
521
+ /**
522
+ * Optional callback which will be called before rendering the menu for each item.
523
+ * Result of callback if not null will be used as a small badge near the menu item.
524
+ */
525
+ badge?: string | ((user: AdminUser) => Promise<string>),
464
526
  }
465
527
 
466
528
 
@@ -529,6 +591,10 @@ export type AdminForthResourceColumn = {
529
591
  */
530
592
  isUnique?: boolean,
531
593
 
594
+ /**
595
+ * Will automatically convert any capital letters to lowercase in input during editing
596
+ */
597
+ enforceLowerCase?: boolean,
532
598
 
533
599
  /**
534
600
  * Runtime validation Regexp rules for this field.
@@ -650,13 +716,13 @@ export type AfterDataSourceResponseFunction = (params: {resource: AdminForthReso
650
716
  * Modify record to change how data is saved to database.
651
717
  * Return ok: false and error: string to stop execution and show error message to user. Return ok: true to continue execution.
652
718
  */
653
- export type BeforeSaveFunction = (params:{resource: AdminForthResource, adminUser: AdminUser, record: any}) => Promise<{ok: boolean, error?: string}>;
719
+ export type BeforeSaveFunction = (params: {resource: AdminForthResource, recordId: any, adminUser: AdminUser, record: any, oldRecord?: any}) => Promise<{ok: boolean, error?: string}>;
654
720
 
655
721
  /**
656
722
  * Modify record to change how data is saved to database.
657
723
  * Return ok: false and error: string to stop execution and show error message to user. Return ok: true to continue execution.
658
724
  */
659
- export type AfterSaveFunction = (params: {resource: AdminForthResource, adminUser: AdminUser, record: any}) => Promise<{ok: boolean, error?: string}>;
725
+ export type AfterSaveFunction = (params: {resource: AdminForthResource, recordId: any, adminUser: AdminUser, record: any, oldRecord?: any}) => Promise<{ok: boolean, error?: string}>;
660
726
 
661
727
  /**
662
728
  * Allow to get user data before login confirmation, will triger when user try to login.
@@ -692,13 +758,17 @@ export type AdminForthBulkAction = {
692
758
  * Callback which will be called on backend when user clicks on action button.
693
759
  * It should return Promise which will be resolved when action is done.
694
760
  */
695
- action: ({ resource, selectedIds, adminUser }: { resource: AdminForthResource, selectedIds: Array<any>, adminUser: AdminUser }) => Promise<{ ok: boolean, error?: string }>,
761
+ action: ({ resource, selectedIds, adminUser }: { resource: AdminForthResource, selectedIds: Array<any>, adminUser: AdminUser }) => Promise<{ ok: boolean, error?: string, successMessage?: string }>,
696
762
 
697
763
  /**
698
764
  * Confirmation message which will be displayed to user before action is executed.
699
765
  */
700
766
  confirm?: string,
701
767
 
768
+ /**
769
+ * Success message which will be displayed to user after action is executed.
770
+ */
771
+ successMessage?: string,
702
772
  /**
703
773
  * Allowed callback called to check whether action is allowed for user.
704
774
  * 1. It called first time when user goes to list view. If callback returns false, action button will be hidden on list view.
@@ -710,7 +780,7 @@ export type AdminForthBulkAction = {
710
780
  *
711
781
  * ```ts
712
782
  * allowed: async ({ resource, adminUser, selectedIds }) => {
713
- * if (adminUser.isRoot || adminUser.dbUser.role !== 'superadmin') {
783
+ * if (adminUser.dbUser.role !== 'superadmin') {
714
784
  * return false;
715
785
  * }
716
786
  * return true;
@@ -752,7 +822,7 @@ export type AdminForthBulkAction = {
752
822
  * ],
753
823
  * allowedActions: \{
754
824
  * edit: (\{ resource, adminUser, recordIds \}) => \{
755
- * return adminUser.isRoot || adminUser.dbUser.role === 'superadmin';
825
+ * return adminUser.dbUser.role === 'superadmin';
756
826
  * \}
757
827
  * \}
758
828
  * \}
@@ -798,7 +868,9 @@ export type AdminForthResource = {
798
868
  */
799
869
  columns: Array<AdminForthResourceColumn>,
800
870
 
801
-
871
+ /**
872
+ * Internal array of columns which are not virtual. You should not edit it.
873
+ */
802
874
  dataSourceColumns?: Array<AdminForthResourceColumn>, // TODO, mark as private
803
875
 
804
876
  /**
@@ -818,25 +890,79 @@ export type AdminForthResource = {
818
890
  *
819
891
  */
820
892
  plugins?: Array<IAdminForthPlugin>,
893
+
894
+ /**
895
+ * Hooks allow you to change the data on different stages of resource lifecycle.
896
+ * Hooks are functions which will be called on backend side (only backend side).
897
+ */
821
898
  hooks?: {
822
899
  show?: {
900
+ /**
901
+ * Typical usecases:
902
+ * - request additional data from database before returning to frontend for soft-join
903
+ */
823
904
  beforeDatasourceRequest?: BeforeDataSourceRequestFunction | Array<BeforeDataSourceRequestFunction>,
905
+
906
+ /**
907
+ * Typical usecases:
908
+ * - Transform value for some field for record returned from database before returning to frontend (minimize, sanitize, etc)
909
+ * - If some-why you can't use `backendOnly` you can cleanup sensitive fields here
910
+ * - Attach additional data to record before returning to frontend
911
+ */
824
912
  afterDatasourceResponse?: AfterDataSourceResponseFunction | Array<AfterDataSourceResponseFunction>,
825
913
  },
826
914
  list?: {
915
+ /**
916
+ * Typical usecases:
917
+ * - add additional filters in addition to what user selected before fetching data from database.
918
+ * - same as hooks.show.beforeDatasourceRequest
919
+ */
827
920
  beforeDatasourceRequest?: BeforeDataSourceRequestFunction | Array<BeforeDataSourceRequestFunction>,
921
+
922
+ /**
923
+ * Typical usecases:
924
+ * - Same as hooks.show.afterDatasourceResponse but applied for each record in list
925
+ */
828
926
  afterDatasourceResponse?: AfterDataSourceResponseFunction | Array<AfterDataSourceResponseFunction>,
829
927
  },
830
928
  create?: {
929
+ /**
930
+ * Typical usecases:
931
+ * - Validate record before saving to database and interrupt execution if validation failed (`allowedActions.create` should be preferred in most cases)
932
+ * - fill-in adminUser as creator of record
933
+ * - Attach additional data to record before saving to database (mostly fillOnCreate should be used instead)
934
+ */
831
935
  beforeSave?: BeforeSaveFunction | Array<BeforeSaveFunction>,
936
+
937
+ /**
938
+ * Typical usecases:
939
+ * - Initiate some trigger after record saved to database (e.g sync to another datasource)
940
+ */
832
941
  afterSave?: AfterSaveFunction | Array<AfterSaveFunction>,
833
942
  },
834
943
  edit?: {
944
+ /**
945
+ * Typical usecases:
946
+ * - Same as hooks.create.beforeSave but for edit page
947
+ */
835
948
  beforeSave?: BeforeSaveFunction | Array<BeforeSaveFunction>,
949
+
950
+ /**
951
+ * Typical usecases:
952
+ * - Same as hooks.create.afterSave but for edit page
953
+ */
836
954
  afterSave?: AfterSaveFunction | Array<AfterSaveFunction>,
837
955
  },
838
956
  delete?: {
957
+ /**
958
+ * Typical usecases:
959
+ * - Validate that record can be deleted and interrupt execution if validation failed (`allowedActions.delete` should be preferred in most cases)
960
+ */
839
961
  beforeSave?: BeforeSaveFunction | Array<BeforeSaveFunction>,
962
+ /**
963
+ * Typical usecases:
964
+ * - Initiate some trigger after record deleted from database (e.g sync to another datasource)
965
+ */
840
966
  afterSave?: BeforeSaveFunction | Array<BeforeSaveFunction>,
841
967
  },
842
968
  },
@@ -889,8 +1015,8 @@ export type AdminForthResource = {
889
1015
  * ```ts
890
1016
  * allowedActions: {
891
1017
  * create: ({ resource, adminUser }) => {
892
- * // Allow only superadmin or root user to create records
893
- * return adminUser.isRoot || adminUser.dbUser.role === 'superadmin';
1018
+ * // Allow only superadmin to create records
1019
+ * return adminUser.dbUser.role === 'superadmin';
894
1020
  * },
895
1021
  * delete: false, // disable delete action for all users
896
1022
  * }
@@ -904,6 +1030,34 @@ export type AdminForthResource = {
904
1030
  */
905
1031
  listPageSize?: number,
906
1032
 
1033
+ /**
1034
+ * Callback to define what happens when user clicks on record in list view.
1035
+ * By default show view will be opened.
1036
+ * If you wish to open custom page, return URL to the custom page (can start with https://, or relative adminforth path)
1037
+ * If you wish to open page in new tab, add `target=_blank` get param to returned URL, example:
1038
+ *
1039
+ * ```ts
1040
+ * listTableClickUrl: async (record, adminUser) => {
1041
+ * return `https://google.com/search?q=${record.name}&target=_blank`;
1042
+ * }
1043
+ * ```
1044
+ *
1045
+ * If you wish to do nothing on click, return null.
1046
+ *
1047
+ * Example:
1048
+ *
1049
+ * ```ts
1050
+ * listTableClickUrl: async (record, adminUser) => {
1051
+ * return null;
1052
+ * }
1053
+ * ```
1054
+ *
1055
+ * @param record - record which was clicked
1056
+ * @param adminUser - user who clicked
1057
+ * @returns
1058
+ */
1059
+ listTableClickUrl?: (record: any, adminUser: AdminUser) => Promise<string | null>,
1060
+
907
1061
  /**
908
1062
  * Custom components which can be injected into AdminForth CRUD pages.
909
1063
  * Each injection is a path to a custom component which will be displayed in the admin panel.
@@ -922,6 +1076,8 @@ export type AdminForthResource = {
922
1076
  *
923
1077
  */
924
1078
  pageInjections?: {
1079
+
1080
+
925
1081
  /**
926
1082
  * Custom components which can be injected into resource list page.
927
1083
  *
@@ -931,6 +1087,8 @@ export type AdminForthResource = {
931
1087
  beforeBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
932
1088
  afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
933
1089
  bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1090
+ threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1091
+ customActionIcons?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
934
1092
  },
935
1093
 
936
1094
  /**
@@ -942,6 +1100,7 @@ export type AdminForthResource = {
942
1100
  beforeBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
943
1101
  afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
944
1102
  bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1103
+ threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
945
1104
  },
946
1105
 
947
1106
  /**
@@ -953,6 +1112,7 @@ export type AdminForthResource = {
953
1112
  beforeBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
954
1113
  afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
955
1114
  bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1115
+ threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
956
1116
  },
957
1117
 
958
1118
  /**
@@ -964,6 +1124,7 @@ export type AdminForthResource = {
964
1124
  beforeBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
965
1125
  afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
966
1126
  bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1127
+ threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
967
1128
  },
968
1129
  }
969
1130
  },
@@ -995,33 +1156,21 @@ export type AdminForthDataSource = {
995
1156
  */
996
1157
  export type AdminForthConfig = {
997
1158
 
998
- /**
999
- * Root user should be used to login to the admin panel first time.
1000
- * Then you should create User for yourself using AdminForth (so it will be persisted in DB),
1001
- * and then disable this option as it is less secure
1002
- */
1003
- rootUser?: {
1004
- /**
1005
- * Username for root user
1006
- */
1007
- username: string,
1008
-
1009
- /**
1010
- * Password for root user
1011
- */
1012
- password: string,
1013
- },
1014
-
1015
1159
  /**
1016
1160
  * Authorization module configuration
1017
1161
  */
1018
1162
  auth?: {
1019
1163
  /**
1020
- * Resource ID for user resource.
1164
+ * Resource ID for resource which stores user table.
1021
1165
  * Resource is a table in database where users will be stored and fetched from. Resources and their ids are defined in resources section of the config.
1022
1166
  * In other words this setting is a reference to a table in database where users will be fetched from on login.
1023
1167
  */
1024
- resourceId: string,
1168
+ usersResourceId?: string,
1169
+
1170
+ /**
1171
+ * Legacy field left for backward compatibility. Use usersResourceId instead.
1172
+ */
1173
+ resourceId?: string,
1025
1174
 
1026
1175
  /**
1027
1176
  * Field name (column name) in user resource which will be used as username for searching user in database during login.
@@ -1046,11 +1195,20 @@ export type AdminForthConfig = {
1046
1195
  */
1047
1196
  loginBackgroundImage?: string,
1048
1197
 
1198
+
1199
+ /**
1200
+ * Position of background image on login page
1201
+ * 'over' - image will be displayed over full login page under login form
1202
+ * '1/2' - image will be displayed on left 1/2 of login page
1203
+ *
1204
+ * Default: '1/2'
1205
+ */
1206
+ loginBackgroundPosition?: 'over' | '1/2' | '1/3' | '2/3' | '3/4' | '2/5' | '3/5',
1207
+
1049
1208
  /**
1050
1209
  * Function or functions which will be called before user try to login.
1051
1210
  * Each function will resive User object as an argument
1052
1211
  */
1053
-
1054
1212
  beforeLoginConfirmation?: BeforeLoginConfirmationFunction | Array<BeforeLoginConfirmationFunction>,
1055
1213
 
1056
1214
  /**
@@ -1069,6 +1227,13 @@ export type AdminForthConfig = {
1069
1227
  * Any prompt to show users on login. Supports HTML.
1070
1228
  */
1071
1229
  loginPromptHTML?: string,
1230
+
1231
+ /**
1232
+ * Remember me days for "Remember Me" checkbox on login page.
1233
+ * If not set or set to null/0/undefined, "Remember Me" checkbox will not be displayed.
1234
+ * If rememberMeDays is set, then users who check "Remember Me" will be staying logged in for this amount of days.
1235
+ */
1236
+ rememberMeDays?: number,
1072
1237
  },
1073
1238
  /**
1074
1239
  * Array of resources which will be displayed in the admin panel.
@@ -1110,6 +1275,13 @@ export type AdminForthConfig = {
1110
1275
  */
1111
1276
  brandName?: string,
1112
1277
 
1278
+
1279
+ /**
1280
+ * Whether to show brand name in sidebar
1281
+ * default is true
1282
+ */
1283
+ showBrandNameInSidebar?: boolean,
1284
+
1113
1285
  /**
1114
1286
  * Path to your app logo
1115
1287
  *
@@ -1136,10 +1308,17 @@ export type AdminForthConfig = {
1136
1308
  favicon?: string,
1137
1309
 
1138
1310
  /**
1139
- * DayJS format string for all dates in the app
1311
+ * DayJS format string for all dates in the app.
1312
+ * Defaulted to 'MMM D, YYYY'
1140
1313
  */
1141
1314
  datesFormat?: string,
1142
1315
 
1316
+ /**
1317
+ * DayJS format string for all datetimes in the app.
1318
+ * Defaulted to 'HH:mm:ss'
1319
+ */
1320
+ timeFormat?: string,
1321
+
1143
1322
  /**
1144
1323
  * HTML title tag value, defaults to brandName
1145
1324
  */
@@ -1205,14 +1384,39 @@ export type AdminForthConfig = {
1205
1384
  * Object to redefine default styles for AdminForth components. Use this file as reference for all possible adjustments https://github.com/devforth/adminforth/blob/main/adminforth/modules/styles.ts
1206
1385
  */
1207
1386
  styles?: Object,
1387
+
1208
1388
  /**
1209
1389
  * Description of custom pages which will let register custom pages for custom routes in AdminForth.
1210
1390
  */
1211
-
1212
1391
  customPages?: Array<{
1213
1392
  path: string,
1214
1393
  component: AdminForthComponentDeclaration,
1215
1394
  }>,
1395
+
1396
+ /**
1397
+ * Function to return custom badge in side bar for users. Can return text or html
1398
+ * If function is not passed or returns null, badge will not be shown.
1399
+ * Execution is done on admin app load.
1400
+ */
1401
+ announcementBadge?: (user: AdminUser) => { text?: string, html?: string, closable?: boolean, title?: string } | null,
1402
+
1403
+ /**
1404
+ * Custom panel components or array of components which will be displayed in the login form
1405
+ * right after the inputs. Use it to add custom authorization methods like social login or other custom fields e.g. 'reset'
1406
+ * password link.
1407
+ */
1408
+ loginPageInjections?: {
1409
+ underInputs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1410
+ }
1411
+
1412
+ /**
1413
+ * Custom panel components or array of components which will be displayed in different parts of the admin panel.
1414
+ */
1415
+ globalInjections?: {
1416
+ userMenu?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1417
+ header?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1418
+ sidebar?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1419
+ }
1216
1420
  }
1217
1421
 
1218
1422
  /**
@@ -1224,11 +1428,77 @@ export type AdminForthConfig = {
1224
1428
  *
1225
1429
  */
1226
1430
  baseUrl?: string,
1227
-
1431
+
1432
+
1433
+ /**
1434
+ * Whether to show delete confirmation dialog before deleting record.
1435
+ * By default it is true.
1436
+ */
1228
1437
  deleteConfirmation?: boolean,
1229
1438
 
1230
1439
 
1231
1440
  }
1441
+
1442
+ // define typescript objects which I can instantiate as Filters.EQ(field, value) and they woudl
1443
+ // return { field: field, operator: 'eq', value: value }. They should be exported with Filters namespace so I can import Filters from this file
1444
+ // and use Filters.EQ(field, value) in my code
1445
+
1446
+ export type FDataFilter = (field: string, value: any) => IAdminForthFilter;
1447
+
1448
+ export class Filters {
1449
+ static EQ(field: string, value: any): IAdminForthFilter {
1450
+ return { field, operator: AdminForthFilterOperators.EQ, value };
1451
+ }
1452
+ static NEQ(field: string, value: any): IAdminForthFilter {
1453
+ return { field, operator: AdminForthFilterOperators.NE, value };
1454
+ }
1455
+ static GT(field: string, value: any): IAdminForthFilter {
1456
+ return { field, operator: AdminForthFilterOperators.GT, value };
1457
+ }
1458
+ static GTE(field: string, value: any): IAdminForthFilter {
1459
+ return { field, operator: AdminForthFilterOperators.GTE, value };
1460
+ }
1461
+ static LT(field: string, value: any): IAdminForthFilter {
1462
+ return { field, operator: AdminForthFilterOperators.LT, value };
1463
+ }
1464
+ static LTE(field: string, value: any): IAdminForthFilter {
1465
+ return { field, operator: AdminForthFilterOperators.LTE, value };
1466
+ }
1467
+ static IN(field: string, value: any): IAdminForthFilter {
1468
+ return { field, operator: AdminForthFilterOperators.IN, value };
1469
+ }
1470
+ static NOT_IN(field: string, value: any): IAdminForthFilter {
1471
+ return { field, operator: AdminForthFilterOperators.NIN, value };
1472
+ }
1473
+ static LIKE(field: string, value: any): IAdminForthFilter {
1474
+ return { field, operator: AdminForthFilterOperators.LIKE, value };
1475
+ }
1476
+ }
1477
+
1478
+ export type FDataSort = (field: string, direction: AdminForthSortDirections) => IAdminForthSort;
1479
+
1480
+ export class Sorts {
1481
+ static ASC(field: string): IAdminForthSort {
1482
+ return { field, direction: AdminForthSortDirections.asc };
1483
+ }
1484
+ static DESC(field: string): IAdminForthSort {
1485
+ return { field, direction: AdminForthSortDirections.desc };
1486
+ }
1487
+ }
1488
+
1489
+ export interface IOperationalResource {
1490
+ get: (filter: IAdminForthFilter | IAdminForthFilter[]) => Promise<any | null>;
1491
+
1492
+ list: (filter: IAdminForthFilter | IAdminForthFilter[], limit?: number, offset?: number, sort?: IAdminForthSort | IAdminForthSort[]) => Promise<any[]>;
1493
+
1494
+ count: (filter: IAdminForthFilter | IAdminForthFilter[] | undefined) => Promise<number>;
1495
+
1496
+ create: (record: any) => Promise<{ ok: boolean; createdRecord: any; error?: string; }>;
1497
+
1498
+ update: (primaryKey: any, record: any) => Promise<any>;
1499
+
1500
+ delete: (primaryKey: any) => Promise<boolean>;
1501
+ }
1232
1502
 
1233
1503
 
1234
1504
  export enum AllowedActionsEnum {
@@ -1303,6 +1573,21 @@ export type ValidationObject = {
1303
1573
  * Example: "Invalid email format"
1304
1574
  */
1305
1575
  message: string,
1576
+
1577
+ /**
1578
+ * Whether to check case sensitivity (i flag)
1579
+ */
1580
+ caseSensitive?: boolean,
1581
+
1582
+ /**
1583
+ * Whether to check Multiline strings (m flag)
1584
+ */
1585
+ multiline?: boolean,
1586
+
1587
+ /**
1588
+ * Whether to check global strings (g flag)
1589
+ */
1590
+ global?: boolean
1306
1591
  }
1307
1592
 
1308
1593
  export type AdminForthComponentDeclarationFull = {