adminforth 2.4.0-next.17 → 2.4.0-next.171

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 (177) hide show
  1. package/commands/callTsProxy.js +14 -4
  2. package/commands/cli.js +12 -4
  3. package/commands/createApp/templates/custom/tsconfig.json.hbs +2 -3
  4. package/commands/createApp/templates/index.ts.hbs +10 -2
  5. package/commands/createApp/templates/package.json.hbs +1 -1
  6. package/commands/createApp/utils.js +27 -2
  7. package/commands/createCustomComponent/configLoader.js +3 -0
  8. package/commands/createCustomComponent/main.js +1 -0
  9. package/commands/createCustomComponent/templates/customCrud/beforeActionButtons.vue.hbs +38 -0
  10. package/commands/createPlugin/templates/custom/tsconfig.json.hbs +2 -5
  11. package/dist/dataConnectors/baseConnector.d.ts.map +1 -1
  12. package/dist/dataConnectors/baseConnector.js +46 -15
  13. package/dist/dataConnectors/baseConnector.js.map +1 -1
  14. package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
  15. package/dist/dataConnectors/clickhouse.js +15 -0
  16. package/dist/dataConnectors/clickhouse.js.map +1 -1
  17. package/dist/dataConnectors/mongo.d.ts.map +1 -1
  18. package/dist/dataConnectors/mongo.js +44 -15
  19. package/dist/dataConnectors/mongo.js.map +1 -1
  20. package/dist/dataConnectors/mysql.d.ts.map +1 -1
  21. package/dist/dataConnectors/mysql.js +11 -0
  22. package/dist/dataConnectors/mysql.js.map +1 -1
  23. package/dist/dataConnectors/postgres.d.ts.map +1 -1
  24. package/dist/dataConnectors/postgres.js +11 -0
  25. package/dist/dataConnectors/postgres.js.map +1 -1
  26. package/dist/dataConnectors/sqlite.d.ts.map +1 -1
  27. package/dist/dataConnectors/sqlite.js +11 -0
  28. package/dist/dataConnectors/sqlite.js.map +1 -1
  29. package/dist/index.d.ts +2 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +20 -9
  32. package/dist/index.js.map +1 -1
  33. package/dist/modules/codeInjector.d.ts +1 -0
  34. package/dist/modules/codeInjector.d.ts.map +1 -1
  35. package/dist/modules/codeInjector.js +42 -5
  36. package/dist/modules/codeInjector.js.map +1 -1
  37. package/dist/modules/configValidator.d.ts.map +1 -1
  38. package/dist/modules/configValidator.js +62 -3
  39. package/dist/modules/configValidator.js.map +1 -1
  40. package/dist/modules/restApi.d.ts.map +1 -1
  41. package/dist/modules/restApi.js +149 -25
  42. package/dist/modules/restApi.js.map +1 -1
  43. package/dist/modules/styles.d.ts +457 -13
  44. package/dist/modules/styles.d.ts.map +1 -1
  45. package/dist/modules/styles.js +513 -31
  46. package/dist/modules/styles.js.map +1 -1
  47. package/dist/modules/utils.d.ts +1 -0
  48. package/dist/modules/utils.d.ts.map +1 -1
  49. package/dist/modules/utils.js +9 -0
  50. package/dist/modules/utils.js.map +1 -1
  51. package/dist/spa/index.html +1 -1
  52. package/dist/spa/package-lock.json +5 -4
  53. package/dist/spa/package.json +1 -1
  54. package/dist/spa/src/App.vue +48 -167
  55. package/dist/spa/src/adminforth.ts +42 -18
  56. package/dist/spa/src/afcl/BarChart.vue +2 -2
  57. package/dist/spa/src/afcl/Button.vue +6 -6
  58. package/dist/spa/src/afcl/Checkbox.vue +21 -13
  59. package/dist/spa/src/afcl/CountryFlag.vue +4 -1
  60. package/dist/spa/src/{components/CustomDatePicker.vue → afcl/DatePicker.vue} +95 -9
  61. package/dist/spa/src/afcl/Dialog.vue +44 -27
  62. package/dist/spa/src/afcl/Dropzone.vue +12 -12
  63. package/dist/spa/src/afcl/Input.vue +6 -6
  64. package/dist/spa/src/afcl/JsonViewer.vue +25 -0
  65. package/dist/spa/src/afcl/LinkButton.vue +1 -1
  66. package/dist/spa/src/afcl/PieChart.vue +5 -5
  67. package/dist/spa/src/afcl/ProgressBar.vue +7 -7
  68. package/dist/spa/src/afcl/Select.vue +68 -34
  69. package/dist/spa/src/afcl/Skeleton.vue +6 -6
  70. package/dist/spa/src/afcl/Table.vue +202 -72
  71. package/dist/spa/src/afcl/Textarea.vue +31 -0
  72. package/dist/spa/src/afcl/Toggle.vue +32 -0
  73. package/dist/spa/src/afcl/Tooltip.vue +1 -2
  74. package/dist/spa/src/afcl/VerticalTabs.vue +16 -7
  75. package/dist/spa/src/afcl/index.ts +4 -3
  76. package/dist/spa/src/components/AcceptModal.vue +7 -7
  77. package/dist/spa/src/components/Breadcrumbs.vue +5 -5
  78. package/dist/spa/src/components/ColumnValueInput.vue +38 -18
  79. package/dist/spa/src/components/ColumnValueInputWrapper.vue +4 -3
  80. package/dist/spa/src/components/CustomDateRangePicker.vue +9 -8
  81. package/dist/spa/src/components/CustomRangePicker.vue +37 -8
  82. package/dist/spa/src/components/ErrorMessage.vue +21 -0
  83. package/dist/spa/src/components/Filters.vue +85 -39
  84. package/dist/spa/src/components/GroupsTable.vue +9 -8
  85. package/dist/spa/src/components/MenuLink.vue +47 -23
  86. package/dist/spa/src/components/ResourceForm.vue +94 -51
  87. package/dist/spa/src/components/ResourceListTable.vue +78 -80
  88. package/dist/spa/src/components/ResourceListTableVirtual.vue +70 -72
  89. package/dist/spa/src/components/ShowTable.vue +17 -12
  90. package/dist/spa/src/components/Sidebar.vue +419 -0
  91. package/dist/spa/src/components/SingleSkeletLoader.vue +6 -6
  92. package/dist/spa/src/components/SkeleteLoader.vue +3 -3
  93. package/dist/spa/src/components/ThreeDotsMenu.vue +73 -14
  94. package/dist/spa/src/components/Toast.vue +27 -9
  95. package/dist/spa/src/components/UserMenuSettingsButton.vue +77 -0
  96. package/dist/spa/src/components/ValueRenderer.vue +43 -16
  97. package/dist/spa/src/controls/BoolToggle.vue +34 -0
  98. package/dist/spa/src/i18n.ts +1 -1
  99. package/dist/spa/src/renderers/CompactField.vue +1 -1
  100. package/dist/spa/src/renderers/CompactUUID.vue +1 -1
  101. package/dist/spa/src/router/index.ts +8 -0
  102. package/dist/spa/src/shims-vue.d.ts +5 -0
  103. package/dist/spa/src/spa_types/core.ts +12 -1
  104. package/dist/spa/src/stores/core.ts +1 -1
  105. package/dist/spa/src/stores/filters.ts +29 -2
  106. package/dist/spa/src/stores/modal.ts +6 -1
  107. package/dist/spa/src/stores/toast.ts +22 -3
  108. package/dist/spa/src/types/Back.ts +131 -22
  109. package/dist/spa/src/types/Common.ts +55 -31
  110. package/dist/spa/src/types/FrontendAPI.ts +31 -5
  111. package/dist/spa/src/types/adapters/CompletionAdapter.ts +25 -0
  112. package/dist/spa/src/types/adapters/EmailAdapter.ts +27 -0
  113. package/dist/spa/src/types/adapters/ImageGenerationAdapter.ts +50 -0
  114. package/dist/spa/src/types/adapters/ImageVisionAdapter.ts +30 -0
  115. package/dist/spa/src/types/adapters/KeyValueAdapter.ts +16 -0
  116. package/dist/spa/src/types/adapters/OAuth2Adapter.ts +34 -0
  117. package/dist/spa/src/types/adapters/StorageAdapter.ts +73 -0
  118. package/dist/spa/src/types/adapters/index.ts +7 -0
  119. package/dist/spa/src/utils.ts +217 -7
  120. package/dist/spa/src/views/CreateView.vue +18 -19
  121. package/dist/spa/src/views/EditView.vue +25 -19
  122. package/dist/spa/src/views/ListView.vue +126 -81
  123. package/dist/spa/src/views/LoginView.vue +24 -33
  124. package/dist/spa/src/views/ResourceParent.vue +2 -2
  125. package/dist/spa/src/views/SettingsView.vue +139 -0
  126. package/dist/spa/src/views/ShowView.vue +59 -39
  127. package/dist/spa/src/websocket.ts +6 -1
  128. package/dist/spa/tsconfig.app.json +1 -1
  129. package/dist/spa/vite.config.ts +45 -2
  130. package/dist/types/Back.d.ts +96 -14
  131. package/dist/types/Back.d.ts.map +1 -1
  132. package/dist/types/Back.js +15 -0
  133. package/dist/types/Back.js.map +1 -1
  134. package/dist/types/Common.d.ts +48 -28
  135. package/dist/types/Common.d.ts.map +1 -1
  136. package/dist/types/Common.js.map +1 -1
  137. package/dist/types/FrontendAPI.d.ts +31 -3
  138. package/dist/types/FrontendAPI.d.ts.map +1 -1
  139. package/dist/types/FrontendAPI.js.map +1 -1
  140. package/dist/types/adapters/CompletionAdapter.d.ts +20 -0
  141. package/dist/types/adapters/CompletionAdapter.d.ts.map +1 -0
  142. package/dist/types/adapters/CompletionAdapter.js +2 -0
  143. package/dist/types/adapters/CompletionAdapter.js.map +1 -0
  144. package/dist/types/adapters/EmailAdapter.d.ts +20 -0
  145. package/dist/types/adapters/EmailAdapter.d.ts.map +1 -0
  146. package/dist/types/adapters/EmailAdapter.js +2 -0
  147. package/dist/types/adapters/EmailAdapter.js.map +1 -0
  148. package/dist/types/adapters/ImageGenerationAdapter.d.ts +37 -0
  149. package/dist/types/adapters/ImageGenerationAdapter.d.ts.map +1 -0
  150. package/dist/types/adapters/ImageGenerationAdapter.js +2 -0
  151. package/dist/types/adapters/ImageGenerationAdapter.js.map +1 -0
  152. package/dist/types/adapters/ImageVisionAdapter.d.ts +25 -0
  153. package/dist/types/adapters/ImageVisionAdapter.d.ts.map +1 -0
  154. package/dist/types/adapters/ImageVisionAdapter.js +2 -0
  155. package/dist/types/adapters/ImageVisionAdapter.js.map +1 -0
  156. package/dist/types/adapters/KeyValueAdapter.d.ts +10 -0
  157. package/dist/types/adapters/KeyValueAdapter.d.ts.map +1 -0
  158. package/dist/types/adapters/KeyValueAdapter.js +2 -0
  159. package/dist/types/adapters/KeyValueAdapter.js.map +1 -0
  160. package/dist/types/adapters/OAuth2Adapter.d.ts +32 -0
  161. package/dist/types/adapters/OAuth2Adapter.d.ts.map +1 -0
  162. package/dist/types/adapters/OAuth2Adapter.js +2 -0
  163. package/dist/types/adapters/OAuth2Adapter.js.map +1 -0
  164. package/dist/types/adapters/StorageAdapter.d.ts +63 -0
  165. package/dist/types/adapters/StorageAdapter.d.ts.map +1 -0
  166. package/dist/types/adapters/StorageAdapter.js +2 -0
  167. package/dist/types/adapters/StorageAdapter.js.map +1 -0
  168. package/dist/types/adapters/index.d.ts +8 -0
  169. package/dist/types/adapters/index.d.ts.map +1 -0
  170. package/dist/types/adapters/index.js +2 -0
  171. package/dist/types/adapters/index.js.map +1 -0
  172. package/package.json +3 -2
  173. package/dist/spa/src/types/Adapters.ts +0 -213
  174. package/dist/types/Adapters.d.ts +0 -168
  175. package/dist/types/Adapters.d.ts.map +0 -1
  176. package/dist/types/Adapters.js +0 -2
  177. package/dist/types/Adapters.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import type { Express } from 'express';
1
+ import type { Express, Request } from 'express';
2
2
  import type { Writable } from 'stream';
3
3
 
4
4
  import { ActionCheckSource, AdminForthFilterOperators, AdminForthSortDirections, AllowedActionsEnum,
@@ -8,12 +8,12 @@ import { ActionCheckSource, AdminForthFilterOperators, AdminForthSortDirections,
8
8
  type AdminForthBulkActionCommon,
9
9
  type AdminForthForeignResourceCommon,
10
10
  type AdminForthResourceColumnCommon,
11
- AdminForthResourceInputCommon,
12
- AdminForthComponentDeclarationFull,
13
- AdminForthConfigMenuItem,
14
- AnnouncementBadgeResponse,
11
+ type AdminForthResourceInputCommon,
12
+ type AdminForthComponentDeclarationFull,
13
+ type AdminForthConfigMenuItem,
14
+ type AnnouncementBadgeResponse,
15
15
  AdminForthResourcePages,
16
- AdminForthResourceColumnInputCommon,
16
+ type AdminForthResourceColumnInputCommon,
17
17
  } from './Common.js';
18
18
 
19
19
  export interface ICodeInjector {
@@ -22,7 +22,7 @@ export interface ICodeInjector {
22
22
  devServerPort: number;
23
23
 
24
24
  getServeDir(): string;
25
-
25
+ registerCustomComponent(filePath: string): void;
26
26
  spaTmpPath(): string;
27
27
  }
28
28
 
@@ -92,19 +92,36 @@ export interface IExpressHttpServer extends IHttpServer {
92
92
  * Adds adminUser to request object if user is authorized. Drops request with 401 status if user is not authorized.
93
93
  * @param callable : Function which will be called if user is authorized.
94
94
  *
95
- * Example:
96
95
  *
96
+ * @example
97
97
  * ```ts
98
- * expressApp.get('/myApi', authorize((req, res) => \{
98
+ * expressApp.get('/myApi', authorize((req, res) => {
99
99
  * console.log('User is authorized', req.adminUser);
100
- * res.json(\{ message: 'Hello World' \});
101
- * \}));
102
- * ``
100
+ * res.json({ message: 'Hello World' });
101
+ * }));
102
+ * ```
103
103
  *
104
- */
104
+ */
105
105
  authorize(callable: Function): void;
106
106
  }
107
107
 
108
+ export interface ITranslateFunction {
109
+ (
110
+ msg: string,
111
+ category: string,
112
+ params: any,
113
+ pluralizationNumber?: number
114
+ ): Promise<string>;
115
+ }
116
+
117
+ // Omit <Request, 'param'> is used to remove 'param' method from Request type for correct docs generation
118
+ export interface IAdminUserExpressRequest extends Omit<Request, 'protocol' | 'param' | 'unshift'> {
119
+ adminUser: AdminUser;
120
+ }
121
+
122
+ export interface ITranslateExpressRequest extends Omit<Request, 'protocol' | 'param' | 'unshift'> {
123
+ tr: ITranslateFunction;
124
+ }
108
125
 
109
126
  export interface IAdminForthSingleFilter {
110
127
  field?: string;
@@ -113,7 +130,9 @@ export interface IAdminForthSingleFilter {
113
130
  | AdminForthFilterOperators.LTE | AdminForthFilterOperators.LIKE | AdminForthFilterOperators.ILIKE
114
131
  | AdminForthFilterOperators.IN | AdminForthFilterOperators.NIN;
115
132
  value?: any;
133
+ rightField?: string;
116
134
  insecureRawSQL?: string;
135
+ insecureRawNoSQL?: any;
117
136
  }
118
137
  export interface IAdminForthAndOrFilter {
119
138
  operator: AdminForthFilterOperators.AND | AdminForthFilterOperators.OR;
@@ -336,7 +355,7 @@ export interface IAdminForth {
336
355
 
337
356
  createResourceRecord(
338
357
  params: { resource: AdminForthResource, record: any, adminUser: AdminUser, extra?: HttpExtra }
339
- ): Promise<{ error?: string, createdRecord?: any }>;
358
+ ): Promise<{ error?: string, createdRecord?: any, newRecordId?: any }>;
340
359
 
341
360
  updateResourceRecord(
342
361
  params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra }
@@ -474,7 +493,7 @@ export type BeforeDataSourceRequestFunction = (params: {
474
493
  requestUrl: string,
475
494
  },
476
495
  adminforth: IAdminForth,
477
- }) => Promise<{ok: boolean, error?: string}>;
496
+ }) => Promise<{ok: boolean, error?: string, newRecordId?: string}>;
478
497
 
479
498
  /**
480
499
  * Modify response to change how data is returned after fetching from database.
@@ -525,7 +544,7 @@ export type BeforeEditSaveFunction = (params: {
525
544
  oldRecord: any,
526
545
  adminforth: IAdminForth,
527
546
  extra?: HttpExtra,
528
- }) => Promise<{ok: boolean, error?: string}>;
547
+ }) => Promise<{ok: boolean, error?: string | null}>;
529
548
 
530
549
 
531
550
 
@@ -535,7 +554,7 @@ export type BeforeCreateSaveFunction = (params: {
535
554
  record: any,
536
555
  adminforth: IAdminForth,
537
556
  extra?: HttpExtra,
538
- }) => Promise<{ok: boolean, error?: string}>;
557
+ }) => Promise<{ok: boolean, error?: string | null, newRecordId?: string}>;
539
558
 
540
559
  export type AfterCreateSaveFunction = (params: {
541
560
  resource: AdminForthResource,
@@ -619,12 +638,23 @@ interface AdminForthInputConfigCustomization {
619
638
  */
620
639
  brandName?: string,
621
640
 
641
+ /**
642
+ * Whether to use single theme for the app
643
+ */
644
+ singleTheme?: 'light' | 'dark',
645
+
622
646
  /**
623
647
  * Whether to show brand name in sidebar
624
648
  * default is true
625
649
  */
626
650
  showBrandNameInSidebar?: boolean,
627
651
 
652
+ /**
653
+ * Whether to show brand logo in sidebar
654
+ * default is true
655
+ */
656
+ showBrandLogoInSidebar?: boolean,
657
+
628
658
  /**
629
659
  * Path to your app logo
630
660
  *
@@ -638,6 +668,19 @@ interface AdminForthInputConfigCustomization {
638
668
  */
639
669
  brandLogo?: string,
640
670
 
671
+
672
+ /**
673
+ * Path to your app logo for icon only sidebar
674
+ *
675
+ * Example:
676
+ * Place file `logo.svg` to `./custom` folder and set this option:
677
+ *
678
+ */
679
+ iconOnlySidebar?: {
680
+ logo?: string,
681
+ enabled?: boolean,
682
+ },
683
+
641
684
  /**
642
685
  * Path to your app favicon
643
686
  *
@@ -757,8 +800,19 @@ interface AdminForthInputConfigCustomization {
757
800
  userMenu?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
758
801
  header?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
759
802
  sidebar?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
803
+ sidebarTop?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
760
804
  everyPageBottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
761
805
  }
806
+
807
+ /**
808
+ * Allows adding custom elements (e.g., <link>, <script>, <meta>) to the <head> of the HTML document.
809
+ * Each item must include a tag name and a set of attributes.
810
+ */
811
+ customHeadItems?: {
812
+ tagName: string;
813
+ attributes: Record<string, string | boolean>;
814
+ }[];
815
+
762
816
  }
763
817
 
764
818
  export interface AdminForthActionInput {
@@ -935,6 +989,13 @@ export interface AdminForthInputConfig {
935
989
  */
936
990
  loginBackgroundPosition?: 'over' | '1/2' | '1/3' | '2/3' | '3/4' | '2/5' | '3/5',
937
991
 
992
+ /**
993
+ * If true, background blend mode will be removed from login background image when position is 'over'
994
+ *
995
+ * Default: false
996
+ */
997
+ removeBackgroundBlendMode?: boolean,
998
+
938
999
  /**
939
1000
  * Function or functions which will be called before user try to login.
940
1001
  * Each function will resive User object as an argument
@@ -956,7 +1017,7 @@ export interface AdminForthInputConfig {
956
1017
  /**
957
1018
  * Any prompt to show users on login. Supports HTML.
958
1019
  */
959
- loginPromptHTML?: string,
1020
+ loginPromptHTML?: string | (() => string | void | undefined | Promise<string | void | undefined>) | undefined
960
1021
 
961
1022
  /**
962
1023
  * Remember me days for "Remember Me" checkbox on login page.
@@ -988,6 +1049,16 @@ export interface AdminForthInputConfig {
988
1049
  * If you are using Cloudflare, set this to 'CF-Connecting-IP'. Case-insensitive.
989
1050
  */
990
1051
  clientIpHeader?: string,
1052
+
1053
+ /**
1054
+ * Add custom page to the settings page
1055
+ */
1056
+ userMenuSettingsPages: {
1057
+ icon?: string,
1058
+ pageLabel: string,
1059
+ slug?: string,
1060
+ component: string
1061
+ }[],
991
1062
  },
992
1063
 
993
1064
  /**
@@ -1062,8 +1133,15 @@ export interface AdminForthConfigCustomization extends Omit<AdminForthInputConfi
1062
1133
  userMenu: Array<AdminForthComponentDeclarationFull>,
1063
1134
  header: Array<AdminForthComponentDeclarationFull>,
1064
1135
  sidebar: Array<AdminForthComponentDeclarationFull>,
1136
+ sidebarTop: Array<AdminForthComponentDeclarationFull>,
1065
1137
  everyPageBottom: Array<AdminForthComponentDeclarationFull>,
1066
1138
  },
1139
+
1140
+ customHeadItems?: {
1141
+ tagName: string;
1142
+ attributes: Record<string, string | boolean>;
1143
+ }[];
1144
+
1067
1145
  }
1068
1146
 
1069
1147
  export interface AdminForthConfig extends Omit<AdminForthInputConfig, 'customization' | 'resources'> {
@@ -1111,6 +1189,21 @@ export class Filters {
1111
1189
  static LIKE(field: string, value: any): IAdminForthSingleFilter {
1112
1190
  return { field, operator: AdminForthFilterOperators.LIKE, value };
1113
1191
  }
1192
+ static ILIKE(field: string, value: any): IAdminForthSingleFilter {
1193
+ return { field, operator: AdminForthFilterOperators.ILIKE, value };
1194
+ }
1195
+ static GT_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1196
+ return { field: leftField, operator: AdminForthFilterOperators.GT, rightField };
1197
+ }
1198
+ static GTE_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1199
+ return { field: leftField, operator: AdminForthFilterOperators.GTE, rightField };
1200
+ }
1201
+ static LT_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1202
+ return { field: leftField, operator: AdminForthFilterOperators.LT, rightField };
1203
+ }
1204
+ static LTE_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1205
+ return { field: leftField, operator: AdminForthFilterOperators.LTE, rightField };
1206
+ }
1114
1207
  static AND(
1115
1208
  ...args: (IAdminForthSingleFilter | IAdminForthAndOrFilter | Array<IAdminForthSingleFilter | IAdminForthAndOrFilter>)[]
1116
1209
  ): IAdminForthAndOrFilter {
@@ -1318,9 +1411,13 @@ export interface AdminForthResource extends Omit<AdminForthResourceInput, 'optio
1318
1411
  },
1319
1412
  create?: {
1320
1413
  /**
1414
+ * Should return `ok: true` to continue saving pipeline and allow creating record in database, and `ok: false` to interrupt pipeline and prevent record creation.
1415
+ * If you need to show error on UI, set `error: \<error message\>` in response.
1416
+ *
1321
1417
  * Typical use-cases:
1322
- * - Validate record before saving to database and interrupt execution if validation failed (`allowedActions.create` should be preferred in most cases)
1323
- * - fill-in adminUser as creator of record
1418
+ * - Create record by custom code (return `{ ok: false, newRecordId: <id of created record from custom code> }`)
1419
+ * - Validate record before saving to database and interrupt execution if validation failed (return `{ ok: false, error: <validation error> }`), though `allowedActions.create` should be preferred in most cases
1420
+ * - fill-in adminUser as creator of record (set `record.<some field> = x; return \{ ok: true \}`)
1324
1421
  * - Attach additional data to record before saving to database (mostly fillOnCreate should be used instead)
1325
1422
  */
1326
1423
  beforeSave?: Array<BeforeCreateSaveFunction>,
@@ -1471,15 +1568,27 @@ export type ShowInInput = ShowInModernInput | ShowInLegacyInput;
1471
1568
  export type ShowIn = {
1472
1569
  [key in AdminForthResourcePages]: AllowedActionValue
1473
1570
  }
1571
+ export type BackendOnlyInput =
1572
+ | boolean
1573
+ | ((p: {
1574
+ adminUser: AdminUser;
1575
+ resource: AdminForthResource;
1576
+ meta: any;
1577
+ source: ActionCheckSource;
1578
+ adminforth: IAdminForth;
1579
+ }) => boolean | Promise<boolean>);
1580
+
1474
1581
 
1475
- export interface AdminForthResourceColumnInput extends Omit<AdminForthResourceColumnInputCommon, 'showIn'> {
1582
+ export interface AdminForthResourceColumnInput extends Omit<AdminForthResourceColumnInputCommon, 'showIn' | 'backendOnly'> {
1476
1583
  showIn?: ShowInInput,
1477
1584
  foreignResource?: AdminForthForeignResource,
1585
+ backendOnly?: BackendOnlyInput;
1478
1586
  }
1479
1587
 
1480
- export interface AdminForthResourceColumn extends Omit<AdminForthResourceColumnCommon, 'showIn'> {
1588
+ export interface AdminForthResourceColumn extends Omit<AdminForthResourceColumnCommon, 'showIn' | 'backendOnly'> {
1481
1589
  showIn?: ShowIn,
1482
1590
  foreignResource?: AdminForthForeignResource,
1591
+ backendOnly?: BackendOnlyInput;
1483
1592
  }
1484
1593
 
1485
1594
  export interface IWebSocketClient {
@@ -1,4 +1,3 @@
1
-
2
1
  /**
3
2
  * Types that are common for both frontend side (SPA) and backend side (server).
4
3
  */
@@ -95,12 +94,9 @@ export interface AdminForthBulkActionCommon {
95
94
  label: string,
96
95
 
97
96
  /**
98
- * Bulk Action button state 'danger'|success|'active',
99
- * * 'danger' - red button
100
- * * 'success' - green button
101
- * * 'active' - blue button
97
+ * Add custom class
102
98
  **/
103
- state?: 'danger' | 'success' | 'active';
99
+ buttonCustomCssClass?: string;
104
100
 
105
101
  /**
106
102
  * Optional small badge for button which will be displayed in the list view
@@ -122,6 +118,10 @@ export interface AdminForthBulkActionCommon {
122
118
  */
123
119
  successMessage?: string,
124
120
 
121
+ /**
122
+ * Show in three dots dropdown menu in list view.
123
+ */
124
+ showInThreeDotsDropdown?: boolean,
125
125
  }
126
126
 
127
127
  export interface AdminForthFieldComponents {
@@ -263,9 +263,17 @@ export interface AdminForthComponentDeclarationFull {
263
263
  */
264
264
  meta?: any,
265
265
  }
266
+ import { type AdminForthActionInput } from './Back.js'
267
+ export { type AdminForthActionInput } from './Back.js'
266
268
 
267
269
  export type AdminForthComponentDeclaration = AdminForthComponentDeclarationFull | string;
268
270
 
271
+ export type FieldGroup = {
272
+ groupName: string;
273
+ columns: string[];
274
+ noTitle?: boolean;
275
+ };
276
+
269
277
  /**
270
278
  * Resource describes one table or collection in database.
271
279
  * AdminForth generates set of pages for 'list', 'show', 'edit', 'create', 'filter' operations for each resource.
@@ -347,6 +355,11 @@ export interface AdminForthResourceInputCommon {
347
355
  direction: AdminForthSortDirections | string,
348
356
  }
349
357
 
358
+ /*
359
+ * Custom actions list. Actions available in show, edit and create views.
360
+ */
361
+ actions?: AdminForthActionInput[],
362
+
350
363
  /**
351
364
  * Custom bulk actions list. Bulk actions available in list view when user selects multiple records by
352
365
  * using checkboxes.
@@ -374,26 +387,10 @@ export interface AdminForthResourceInputCommon {
374
387
  /**
375
388
  * Allows to make groups of columns in show, create and edit resource pages.
376
389
  */
377
- fieldGroups?: {
378
- groupName: string;
379
- columns: string[];
380
- noTitle?: boolean;
381
- }[];
382
- createFieldGroups?: {
383
- groupName: string;
384
- columns: string[];
385
- noTitle?: boolean;
386
- }[];
387
- editFieldGroups?: {
388
- groupName: string;
389
- columns: string[];
390
- noTitle?: boolean;
391
- }[];
392
- showFieldGroups?: {
393
- groupName: string;
394
- columns: string[];
395
- noTitle?: boolean;
396
- }[];
390
+ fieldGroups?: FieldGroup[];
391
+ createFieldGroups?: FieldGroup[];
392
+ editFieldGroups?: FieldGroup[];
393
+ showFieldGroups?: FieldGroup[];
397
394
 
398
395
  /**
399
396
  * Page size for list view
@@ -471,6 +468,7 @@ export interface AdminForthResourceInputCommon {
471
468
  list?: {
472
469
  beforeBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
473
470
  afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
471
+ beforeActionButtons?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
474
472
  bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
475
473
  threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
476
474
  customActionIcons?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
@@ -584,6 +582,8 @@ export interface AdminForthForeignResourceCommon {
584
582
  polymorphicResources?: Array<AdminForthPolymorphicForeignResource>,
585
583
  polymorphicOn?: string,
586
584
  unsetLabel?: string,
585
+ searchableFields?: string | string[],
586
+ searchIsCaseSensitive?: boolean,
587
587
  }
588
588
 
589
589
  export type FillOnCreateFunction = (params: {
@@ -810,9 +810,6 @@ export interface AdminForthResourceColumnInputCommon {
810
810
  */
811
811
  minLength?: number,
812
812
 
813
- min?: number,
814
- max?: number,
815
-
816
813
  /**
817
814
  * Minimum value that can be entered in this field.
818
815
  */
@@ -878,6 +875,15 @@ export interface AdminForthResourceColumnCommon extends AdminForthResourceColumn
878
875
 
879
876
  editingNote?: { create?: string, edit?: string },
880
877
 
878
+ /**
879
+ * Minimal value stored in this field.
880
+ */
881
+ min?: number,
882
+
883
+ /**
884
+ * Maximum value stored in this field.
885
+ */
886
+ max?: number,
881
887
  }
882
888
 
883
889
  export enum AdminForthMenuTypes {
@@ -1055,16 +1061,23 @@ export interface AdminForthConfigForFrontend {
1055
1061
  usernameFieldName: string,
1056
1062
  loginBackgroundImage: string,
1057
1063
  loginBackgroundPosition: string,
1064
+ removeBackgroundBlendMode: boolean,
1058
1065
  title?: string,
1059
1066
  demoCredentials?: string,
1060
- loginPromptHTML?: string,
1067
+ loginPromptHTML?: string | (() => string | Promise<string> | void | Promise<void> | Promise<undefined>) | undefined
1061
1068
  loginPageInjections: {
1062
1069
  underInputs: Array<AdminForthComponentDeclaration>,
1063
1070
  panelHeader: Array<AdminForthComponentDeclaration>,
1064
1071
  },
1065
1072
  rememberMeDays: number,
1066
1073
  showBrandNameInSidebar: boolean,
1074
+ showBrandLogoInSidebar: boolean,
1067
1075
  brandLogo?: string,
1076
+ iconOnlySidebar?: {
1077
+ logo?: string,
1078
+ enabled?: boolean,
1079
+ },
1080
+ singleTheme?: 'light' | 'dark',
1068
1081
  datesFormat: string,
1069
1082
  timeFormat: string,
1070
1083
  auth: any,
@@ -1079,8 +1092,19 @@ export interface AdminForthConfigForFrontend {
1079
1092
  userMenu: Array<AdminForthComponentDeclarationFull>,
1080
1093
  header: Array<AdminForthComponentDeclarationFull>,
1081
1094
  sidebar: Array<AdminForthComponentDeclarationFull>,
1095
+ sidebarTop: Array<AdminForthComponentDeclarationFull>,
1082
1096
  everyPageBottom: Array<AdminForthComponentDeclarationFull>,
1083
- }
1097
+ },
1098
+ customHeadItems?: {
1099
+ tagName: string;
1100
+ attributes: Record<string, string | boolean>;
1101
+ }[],
1102
+ settingPages?:{
1103
+ icon?: string,
1104
+ pageLabel: string,
1105
+ slug?: string,
1106
+ component: string,
1107
+ }[],
1084
1108
  }
1085
1109
 
1086
1110
  export interface GetBaseConfigResponse {
@@ -55,7 +55,7 @@ export interface FrontendAPIInterface {
55
55
  *
56
56
  * @param params - The parameters of the alert
57
57
  */
58
- alert(params:AlertParams): void;
58
+ alert(params:AlertParams): void | Promise<string> | string;
59
59
 
60
60
 
61
61
  list: {
@@ -82,27 +82,40 @@ export interface FrontendAPIInterface {
82
82
  */
83
83
  closeThreeDotsDropdown(): void;
84
84
 
85
-
86
85
  /**
87
- * Set a filter in the list
88
- * Works only when user located on the list page.
86
+ * Set a filter in the list.
87
+ * Works only when user located on the list page. If filter already exists, it will be replaced with the new one.
89
88
  * Can be used to set filter from charts or other components in pageInjections.
90
89
  *
90
+ * Filters are automatically marked as hidden (won't count in badge) if:
91
+ * - Column has showIn.filter: false
92
+ *
91
93
  * Example:
92
94
  *
93
95
  * ```ts
94
96
  * import adminforth from '@/adminforth'
95
97
  *
98
+ * // Regular filter (will show in badge if column.showIn.filter !== false)
96
99
  * adminforth.list.setFilter({field: 'name', operator: 'ilike', value: 'john'})
100
+ *
101
+ * // Hidden filter (won't show in badge if column.showIn.filter === false)
102
+ * adminforth.list.setFilter({field: 'internal_status', operator: 'eq', value: 'active'})
97
103
  * ```
98
104
  *
105
+ * Please note that you can set/update filter even for fields which have showIn.filter=false in resource configuration.
106
+ * Also you can set filter for virtual columns. For example Universal search plugin calls updateFilter for virtual column which has showIn.filter=false (because we dont want to show this column in filter dropdown, plugin renders its own filter UI)
107
+ *
99
108
  * @param filter - The filter to set
100
109
  */
101
110
  setFilter(filter: FilterParams): void;
102
111
 
103
112
  /**
113
+ * DEPRECATED: does the same as setFilter, kept for backward compatibility
104
114
  * Update a filter in the list
105
115
  *
116
+ * Filters visibility in badge is automatically determined by column configuration:
117
+ * - Hidden if column has showIn.filter: false
118
+ *
106
119
  * Example:
107
120
  *
108
121
  * ```ts
@@ -121,6 +134,14 @@ export interface FrontendAPIInterface {
121
134
  clearFilters(): void;
122
135
  }
123
136
 
137
+ show: {
138
+ /**
139
+ * Full refresh the current record on the show page. Loader may be shown during fetching.
140
+ * Fire-and-forget; you don't need to await it.
141
+ */
142
+ refresh(): void;
143
+ }
144
+
124
145
  menu: {
125
146
  /**
126
147
  * Refreshes the badges in the menu, by recalling the badge function for each menu item
@@ -171,7 +192,12 @@ export type AlertParams = {
171
192
  * Default is 10 seconds;
172
193
  */
173
194
  timeout?: number | 'unlimited';
174
-
195
+
196
+ /**
197
+ * Optional buttons to display in the alert
198
+ */
199
+ buttons?: {value: any, label: string}[];
200
+
175
201
  }
176
202
 
177
203
 
@@ -0,0 +1,25 @@
1
+ export interface CompletionAdapter {
2
+
3
+ /**
4
+ * This method is called to validate the configuration of the adapter
5
+ * and should throw a clear user-readbale error if the configuration is invalid.
6
+ */
7
+ validate(): void;
8
+
9
+ /**
10
+ * This method should return a text completion based on the provided content and stop sequence.
11
+ * @param content - The input text to complete
12
+ * @param stop - An array of stop sequences to indicate where to stop the completion
13
+ * @param maxTokens - The maximum number of tokens to generate
14
+ * @returns A promise that resolves to an object containing the completed text and other metadata
15
+ */
16
+ complete(
17
+ content: string,
18
+ stop: string[],
19
+ maxTokens: number,
20
+ ): Promise<{
21
+ content?: string;
22
+ finishReason?: string;
23
+ error?: string;
24
+ }>;
25
+ }
@@ -0,0 +1,27 @@
1
+ export interface EmailAdapter {
2
+
3
+ /**
4
+ * This method is called to validate the configuration of the adapter
5
+ * and should throw a clear user-readable error if the configuration is invalid.
6
+ */
7
+ validate(): Promise<void>;
8
+
9
+ /**
10
+ * This method should send an email using the adapter
11
+ * @param from - The sender's email address
12
+ * @param to - The recipient's email address
13
+ * @param text - The plain text version of the email
14
+ * @param html - The HTML version of the email
15
+ * @param subject - The subject of the email
16
+ */
17
+ sendEmail(
18
+ from: string,
19
+ to: string,
20
+ text: string,
21
+ html: string,
22
+ subject: string
23
+ ): Promise<{
24
+ error?: string;
25
+ ok?: boolean;
26
+ }>;
27
+ }
@@ -0,0 +1,50 @@
1
+ export interface ImageGenerationAdapter {
2
+
3
+ /**
4
+ * This method is called to validate the configuration of the adapter
5
+ * and should throw a clear user-readbale error if the configuration is invalid.
6
+ */
7
+ validate(): void;
8
+
9
+ /**
10
+ * Return max number of images which model can generate in one request
11
+ */
12
+ outputImagesMaxCountSupported(): number;
13
+
14
+ /**
15
+ * Return the list of supported dimensions in format ["100x500", "200x200"]
16
+ */
17
+ outputDimensionsSupported(): string[];
18
+
19
+ /**
20
+ * Input file extension supported
21
+ */
22
+ inputFileExtensionSupported(): string[];
23
+
24
+ /**
25
+ * This method should generate an image based on the provided prompt and input files.
26
+ * @param prompt - The prompt to generate the image
27
+ * @param inputFiles - An array of input file paths (optional)
28
+ * @param n - The number of images to generate (default is 1)
29
+ * @param size - The size of the generated image (default is the lowest dimension supported)
30
+ * @returns A promise that resolves to an object containing the generated image URLs and any error message
31
+ */
32
+ generate({
33
+ prompt,
34
+ inputFiles,
35
+ n,
36
+ size,
37
+ }: {
38
+ prompt: string,
39
+ inputFiles: string[],
40
+
41
+ // default = lowest dimension supported
42
+ size?: string,
43
+
44
+ // one by default
45
+ n?: number
46
+ }): Promise<{
47
+ imageURLs?: string[];
48
+ error?: string;
49
+ }>;
50
+ }