adminforth 2.4.0-next.2 → 2.4.0-next.200

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 (197) hide show
  1. package/commands/callTsProxy.js +14 -4
  2. package/commands/cli.js +12 -4
  3. package/commands/createApp/templates/.env.local.hbs +2 -2
  4. package/commands/createApp/templates/custom/tsconfig.json.hbs +2 -3
  5. package/commands/createApp/templates/index.ts.hbs +11 -6
  6. package/commands/createApp/templates/package.json.hbs +1 -1
  7. package/commands/createApp/utils.js +40 -7
  8. package/commands/createCustomComponent/configLoader.js +3 -0
  9. package/commands/createCustomComponent/configUpdater.js +25 -21
  10. package/commands/createCustomComponent/fileGenerator.js +1 -1
  11. package/commands/createCustomComponent/main.js +3 -1
  12. package/commands/createCustomComponent/templates/customCrud/beforeActionButtons.vue.hbs +38 -0
  13. package/commands/createCustomComponent/templates/login/beforeLogin.vue.hbs +18 -0
  14. package/commands/createPlugin/templates/custom/tsconfig.json.hbs +2 -5
  15. package/commands/createPlugin/templates/package.json.hbs +1 -1
  16. package/dist/auth.d.ts +9 -1
  17. package/dist/auth.d.ts.map +1 -1
  18. package/dist/auth.js +15 -2
  19. package/dist/auth.js.map +1 -1
  20. package/dist/dataConnectors/baseConnector.d.ts.map +1 -1
  21. package/dist/dataConnectors/baseConnector.js +46 -15
  22. package/dist/dataConnectors/baseConnector.js.map +1 -1
  23. package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
  24. package/dist/dataConnectors/clickhouse.js +15 -0
  25. package/dist/dataConnectors/clickhouse.js.map +1 -1
  26. package/dist/dataConnectors/mongo.d.ts.map +1 -1
  27. package/dist/dataConnectors/mongo.js +44 -15
  28. package/dist/dataConnectors/mongo.js.map +1 -1
  29. package/dist/dataConnectors/mysql.d.ts.map +1 -1
  30. package/dist/dataConnectors/mysql.js +11 -0
  31. package/dist/dataConnectors/mysql.js.map +1 -1
  32. package/dist/dataConnectors/postgres.d.ts.map +1 -1
  33. package/dist/dataConnectors/postgres.js +11 -0
  34. package/dist/dataConnectors/postgres.js.map +1 -1
  35. package/dist/dataConnectors/sqlite.d.ts.map +1 -1
  36. package/dist/dataConnectors/sqlite.js +11 -0
  37. package/dist/dataConnectors/sqlite.js.map +1 -1
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +20 -9
  41. package/dist/index.js.map +1 -1
  42. package/dist/modules/codeInjector.d.ts +2 -0
  43. package/dist/modules/codeInjector.d.ts.map +1 -1
  44. package/dist/modules/codeInjector.js +55 -12
  45. package/dist/modules/codeInjector.js.map +1 -1
  46. package/dist/modules/configValidator.d.ts.map +1 -1
  47. package/dist/modules/configValidator.js +76 -8
  48. package/dist/modules/configValidator.js.map +1 -1
  49. package/dist/modules/restApi.d.ts.map +1 -1
  50. package/dist/modules/restApi.js +149 -25
  51. package/dist/modules/restApi.js.map +1 -1
  52. package/dist/modules/styles.d.ts +485 -13
  53. package/dist/modules/styles.d.ts.map +1 -1
  54. package/dist/modules/styles.js +541 -31
  55. package/dist/modules/styles.js.map +1 -1
  56. package/dist/modules/utils.d.ts +2 -0
  57. package/dist/modules/utils.d.ts.map +1 -1
  58. package/dist/modules/utils.js +16 -0
  59. package/dist/modules/utils.js.map +1 -1
  60. package/dist/servers/express.d.ts.map +1 -1
  61. package/dist/servers/express.js +14 -0
  62. package/dist/servers/express.js.map +1 -1
  63. package/dist/spa/index.html +1 -1
  64. package/dist/spa/package-lock.json +5 -4
  65. package/dist/spa/package.json +1 -1
  66. package/dist/spa/src/App.vue +54 -169
  67. package/dist/spa/src/adminforth.ts +42 -18
  68. package/dist/spa/src/afcl/BarChart.vue +2 -2
  69. package/dist/spa/src/afcl/Button.vue +6 -6
  70. package/dist/spa/src/afcl/ButtonGroup.vue +91 -0
  71. package/dist/spa/src/afcl/Card.vue +25 -0
  72. package/dist/spa/src/afcl/Checkbox.vue +21 -13
  73. package/dist/spa/src/afcl/CountryFlag.vue +4 -1
  74. package/dist/spa/src/{components/CustomDatePicker.vue → afcl/DatePicker.vue} +95 -9
  75. package/dist/spa/src/afcl/Dialog.vue +44 -27
  76. package/dist/spa/src/afcl/Dropzone.vue +15 -13
  77. package/dist/spa/src/afcl/Input.vue +9 -7
  78. package/dist/spa/src/afcl/JsonViewer.vue +25 -0
  79. package/dist/spa/src/afcl/Link.vue +1 -1
  80. package/dist/spa/src/afcl/LinkButton.vue +3 -3
  81. package/dist/spa/src/afcl/PieChart.vue +5 -5
  82. package/dist/spa/src/afcl/ProgressBar.vue +7 -7
  83. package/dist/spa/src/afcl/Select.vue +68 -34
  84. package/dist/spa/src/afcl/Skeleton.vue +6 -6
  85. package/dist/spa/src/afcl/Table.vue +213 -74
  86. package/dist/spa/src/afcl/Textarea.vue +31 -0
  87. package/dist/spa/src/afcl/Toggle.vue +32 -0
  88. package/dist/spa/src/afcl/Tooltip.vue +2 -3
  89. package/dist/spa/src/afcl/VerticalTabs.vue +16 -7
  90. package/dist/spa/src/afcl/index.ts +6 -3
  91. package/dist/spa/src/components/AcceptModal.vue +7 -7
  92. package/dist/spa/src/components/Breadcrumbs.vue +5 -5
  93. package/dist/spa/src/components/ColumnValueInput.vue +38 -18
  94. package/dist/spa/src/components/ColumnValueInputWrapper.vue +4 -3
  95. package/dist/spa/src/components/CustomDateRangePicker.vue +9 -8
  96. package/dist/spa/src/components/CustomRangePicker.vue +37 -8
  97. package/dist/spa/src/components/ErrorMessage.vue +21 -0
  98. package/dist/spa/src/components/Filters.vue +85 -39
  99. package/dist/spa/src/components/GroupsTable.vue +9 -8
  100. package/dist/spa/src/components/MenuLink.vue +90 -23
  101. package/dist/spa/src/components/ResourceForm.vue +94 -51
  102. package/dist/spa/src/components/ResourceListTable.vue +78 -80
  103. package/dist/spa/src/components/ResourceListTableVirtual.vue +70 -72
  104. package/dist/spa/src/components/ShowTable.vue +17 -12
  105. package/dist/spa/src/components/Sidebar.vue +443 -0
  106. package/dist/spa/src/components/SingleSkeletLoader.vue +6 -6
  107. package/dist/spa/src/components/SkeleteLoader.vue +3 -3
  108. package/dist/spa/src/components/ThreeDotsMenu.vue +73 -14
  109. package/dist/spa/src/components/Toast.vue +27 -9
  110. package/dist/spa/src/components/UserMenuSettingsButton.vue +68 -0
  111. package/dist/spa/src/components/ValueRenderer.vue +43 -16
  112. package/dist/spa/src/controls/BoolToggle.vue +34 -0
  113. package/dist/spa/src/i18n.ts +1 -1
  114. package/dist/spa/src/renderers/CompactField.vue +1 -1
  115. package/dist/spa/src/renderers/CompactUUID.vue +1 -1
  116. package/dist/spa/src/router/index.ts +8 -0
  117. package/dist/spa/src/shims-vue.d.ts +5 -0
  118. package/dist/spa/src/spa_types/core.ts +13 -1
  119. package/dist/spa/src/stores/core.ts +1 -1
  120. package/dist/spa/src/stores/filters.ts +29 -2
  121. package/dist/spa/src/stores/modal.ts +6 -1
  122. package/dist/spa/src/stores/toast.ts +22 -3
  123. package/dist/spa/src/types/Back.ts +139 -22
  124. package/dist/spa/src/types/Common.ts +68 -32
  125. package/dist/spa/src/types/FrontendAPI.ts +31 -5
  126. package/dist/spa/src/types/adapters/CaptchaAdapter.ts +34 -0
  127. package/dist/spa/src/types/adapters/CompletionAdapter.ts +25 -0
  128. package/dist/spa/src/types/adapters/EmailAdapter.ts +27 -0
  129. package/dist/spa/src/types/adapters/ImageGenerationAdapter.ts +50 -0
  130. package/dist/spa/src/types/adapters/ImageVisionAdapter.ts +30 -0
  131. package/dist/spa/src/types/adapters/KeyValueAdapter.ts +16 -0
  132. package/dist/spa/src/types/adapters/OAuth2Adapter.ts +34 -0
  133. package/dist/spa/src/types/adapters/StorageAdapter.ts +73 -0
  134. package/dist/spa/src/types/adapters/index.ts +8 -0
  135. package/dist/spa/src/utils.ts +219 -8
  136. package/dist/spa/src/views/CreateView.vue +18 -19
  137. package/dist/spa/src/views/EditView.vue +25 -19
  138. package/dist/spa/src/views/ListView.vue +139 -86
  139. package/dist/spa/src/views/LoginView.vue +65 -55
  140. package/dist/spa/src/views/ResourceParent.vue +2 -2
  141. package/dist/spa/src/views/SettingsView.vue +121 -0
  142. package/dist/spa/src/views/ShowView.vue +59 -39
  143. package/dist/spa/src/websocket.ts +6 -1
  144. package/dist/spa/tsconfig.app.json +1 -1
  145. package/dist/spa/vite.config.ts +45 -2
  146. package/dist/types/Back.d.ts +117 -14
  147. package/dist/types/Back.d.ts.map +1 -1
  148. package/dist/types/Back.js +15 -0
  149. package/dist/types/Back.js.map +1 -1
  150. package/dist/types/Common.d.ts +60 -29
  151. package/dist/types/Common.d.ts.map +1 -1
  152. package/dist/types/Common.js.map +1 -1
  153. package/dist/types/FrontendAPI.d.ts +31 -3
  154. package/dist/types/FrontendAPI.d.ts.map +1 -1
  155. package/dist/types/FrontendAPI.js.map +1 -1
  156. package/dist/types/adapters/CaptchaAdapter.d.ts +30 -0
  157. package/dist/types/adapters/CaptchaAdapter.d.ts.map +1 -0
  158. package/dist/types/adapters/CaptchaAdapter.js +5 -0
  159. package/dist/types/adapters/CaptchaAdapter.js.map +1 -0
  160. package/dist/types/adapters/CompletionAdapter.d.ts +20 -0
  161. package/dist/types/adapters/CompletionAdapter.d.ts.map +1 -0
  162. package/dist/types/adapters/CompletionAdapter.js +2 -0
  163. package/dist/types/adapters/CompletionAdapter.js.map +1 -0
  164. package/dist/types/adapters/EmailAdapter.d.ts +20 -0
  165. package/dist/types/adapters/EmailAdapter.d.ts.map +1 -0
  166. package/dist/types/adapters/EmailAdapter.js +2 -0
  167. package/dist/types/adapters/EmailAdapter.js.map +1 -0
  168. package/dist/types/adapters/ImageGenerationAdapter.d.ts +37 -0
  169. package/dist/types/adapters/ImageGenerationAdapter.d.ts.map +1 -0
  170. package/dist/types/adapters/ImageGenerationAdapter.js +2 -0
  171. package/dist/types/adapters/ImageGenerationAdapter.js.map +1 -0
  172. package/dist/types/adapters/ImageVisionAdapter.d.ts +25 -0
  173. package/dist/types/adapters/ImageVisionAdapter.d.ts.map +1 -0
  174. package/dist/types/adapters/ImageVisionAdapter.js +2 -0
  175. package/dist/types/adapters/ImageVisionAdapter.js.map +1 -0
  176. package/dist/types/adapters/KeyValueAdapter.d.ts +10 -0
  177. package/dist/types/adapters/KeyValueAdapter.d.ts.map +1 -0
  178. package/dist/types/adapters/KeyValueAdapter.js +2 -0
  179. package/dist/types/adapters/KeyValueAdapter.js.map +1 -0
  180. package/dist/types/adapters/OAuth2Adapter.d.ts +32 -0
  181. package/dist/types/adapters/OAuth2Adapter.d.ts.map +1 -0
  182. package/dist/types/adapters/OAuth2Adapter.js +2 -0
  183. package/dist/types/adapters/OAuth2Adapter.js.map +1 -0
  184. package/dist/types/adapters/StorageAdapter.d.ts +63 -0
  185. package/dist/types/adapters/StorageAdapter.d.ts.map +1 -0
  186. package/dist/types/adapters/StorageAdapter.js +2 -0
  187. package/dist/types/adapters/StorageAdapter.js.map +1 -0
  188. package/dist/types/adapters/index.d.ts +9 -0
  189. package/dist/types/adapters/index.d.ts.map +1 -0
  190. package/dist/types/adapters/index.js +2 -0
  191. package/dist/types/adapters/index.js.map +1 -0
  192. package/package.json +3 -2
  193. package/dist/spa/src/types/Adapters.ts +0 -213
  194. package/dist/types/Adapters.d.ts +0 -168
  195. package/dist/types/Adapters.d.ts.map +0 -1
  196. package/dist/types/Adapters.js +0 -2
  197. 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;
@@ -287,6 +306,10 @@ export interface IAdminForthAuth {
287
306
 
288
307
  removeCustomCookie({response, name}: {response: any, name: string}): void;
289
308
 
309
+ setCustomCookie({response, payload}: {response: any, payload: {name: string, value: string, expiry: number, expirySeconds: number, httpOnly: boolean}}): void;
310
+
311
+ getCustomCookie({cookies, name}: {cookies: {key: string, value: string}[], name: string}): string | null;
312
+
290
313
  setAuthCookie({expireInDays, response, username, pk,}: {expireInDays?: number, response: any, username: string, pk: string}): void;
291
314
 
292
315
  removeAuthCookie(response: any): void;
@@ -336,7 +359,7 @@ export interface IAdminForth {
336
359
 
337
360
  createResourceRecord(
338
361
  params: { resource: AdminForthResource, record: any, adminUser: AdminUser, extra?: HttpExtra }
339
- ): Promise<{ error?: string, createdRecord?: any }>;
362
+ ): Promise<{ error?: string, createdRecord?: any, newRecordId?: any }>;
340
363
 
341
364
  updateResourceRecord(
342
365
  params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra }
@@ -474,7 +497,7 @@ export type BeforeDataSourceRequestFunction = (params: {
474
497
  requestUrl: string,
475
498
  },
476
499
  adminforth: IAdminForth,
477
- }) => Promise<{ok: boolean, error?: string}>;
500
+ }) => Promise<{ok: boolean, error?: string, newRecordId?: string}>;
478
501
 
479
502
  /**
480
503
  * Modify response to change how data is returned after fetching from database.
@@ -525,7 +548,7 @@ export type BeforeEditSaveFunction = (params: {
525
548
  oldRecord: any,
526
549
  adminforth: IAdminForth,
527
550
  extra?: HttpExtra,
528
- }) => Promise<{ok: boolean, error?: string}>;
551
+ }) => Promise<{ok: boolean, error?: string | null}>;
529
552
 
530
553
 
531
554
 
@@ -535,7 +558,7 @@ export type BeforeCreateSaveFunction = (params: {
535
558
  record: any,
536
559
  adminforth: IAdminForth,
537
560
  extra?: HttpExtra,
538
- }) => Promise<{ok: boolean, error?: string}>;
561
+ }) => Promise<{ok: boolean, error?: string | null, newRecordId?: string}>;
539
562
 
540
563
  export type AfterCreateSaveFunction = (params: {
541
564
  resource: AdminForthResource,
@@ -619,12 +642,23 @@ interface AdminForthInputConfigCustomization {
619
642
  */
620
643
  brandName?: string,
621
644
 
645
+ /**
646
+ * Whether to use single theme for the app
647
+ */
648
+ singleTheme?: 'light' | 'dark',
649
+
622
650
  /**
623
651
  * Whether to show brand name in sidebar
624
652
  * default is true
625
653
  */
626
654
  showBrandNameInSidebar?: boolean,
627
655
 
656
+ /**
657
+ * Whether to show brand logo in sidebar
658
+ * default is true
659
+ */
660
+ showBrandLogoInSidebar?: boolean,
661
+
628
662
  /**
629
663
  * Path to your app logo
630
664
  *
@@ -638,6 +672,19 @@ interface AdminForthInputConfigCustomization {
638
672
  */
639
673
  brandLogo?: string,
640
674
 
675
+
676
+ /**
677
+ * Path to your app logo for icon only sidebar
678
+ *
679
+ * Example:
680
+ * Place file `logo.svg` to `./custom` folder and set this option:
681
+ *
682
+ */
683
+ iconOnlySidebar?: {
684
+ logo?: string,
685
+ enabled?: boolean,
686
+ },
687
+
641
688
  /**
642
689
  * Path to your app favicon
643
690
  *
@@ -747,6 +794,7 @@ interface AdminForthInputConfigCustomization {
747
794
  */
748
795
  loginPageInjections?: {
749
796
  underInputs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
797
+ panelHeader?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
750
798
  }
751
799
 
752
800
  /**
@@ -756,8 +804,20 @@ interface AdminForthInputConfigCustomization {
756
804
  userMenu?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
757
805
  header?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
758
806
  sidebar?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
807
+ sidebarTop?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
759
808
  everyPageBottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
760
809
  }
810
+
811
+ /**
812
+ * Allows adding custom elements (e.g., <link>, <script>, <meta>) to the <head> of the HTML document.
813
+ * Each item must include a tag name and a set of attributes.
814
+ */
815
+ customHeadItems?: {
816
+ tagName: string;
817
+ attributes: Record<string, string | boolean>;
818
+ innerCode?: string;
819
+ }[];
820
+
761
821
  }
762
822
 
763
823
  export interface AdminForthActionInput {
@@ -934,6 +994,13 @@ export interface AdminForthInputConfig {
934
994
  */
935
995
  loginBackgroundPosition?: 'over' | '1/2' | '1/3' | '2/3' | '3/4' | '2/5' | '3/5',
936
996
 
997
+ /**
998
+ * If true, background blend mode will be removed from login background image when position is 'over'
999
+ *
1000
+ * Default: false
1001
+ */
1002
+ removeBackgroundBlendMode?: boolean,
1003
+
937
1004
  /**
938
1005
  * Function or functions which will be called before user try to login.
939
1006
  * Each function will resive User object as an argument
@@ -955,7 +1022,7 @@ export interface AdminForthInputConfig {
955
1022
  /**
956
1023
  * Any prompt to show users on login. Supports HTML.
957
1024
  */
958
- loginPromptHTML?: string,
1025
+ loginPromptHTML?: string | (() => string | void | undefined | Promise<string | void | undefined>) | undefined
959
1026
 
960
1027
  /**
961
1028
  * Remember me days for "Remember Me" checkbox on login page.
@@ -987,6 +1054,16 @@ export interface AdminForthInputConfig {
987
1054
  * If you are using Cloudflare, set this to 'CF-Connecting-IP'. Case-insensitive.
988
1055
  */
989
1056
  clientIpHeader?: string,
1057
+
1058
+ /**
1059
+ * Add custom page to the settings page
1060
+ */
1061
+ userMenuSettingsPages: {
1062
+ icon?: string,
1063
+ pageLabel: string,
1064
+ slug?: string,
1065
+ component: string
1066
+ }[],
990
1067
  },
991
1068
 
992
1069
  /**
@@ -1054,14 +1131,23 @@ export interface AdminForthConfigCustomization extends Omit<AdminForthInputConfi
1054
1131
 
1055
1132
  loginPageInjections: {
1056
1133
  underInputs: Array<AdminForthComponentDeclarationFull>,
1134
+ panelHeader: Array<AdminForthComponentDeclarationFull>,
1057
1135
  },
1058
1136
 
1059
1137
  globalInjections: {
1060
1138
  userMenu: Array<AdminForthComponentDeclarationFull>,
1061
1139
  header: Array<AdminForthComponentDeclarationFull>,
1062
1140
  sidebar: Array<AdminForthComponentDeclarationFull>,
1141
+ sidebarTop: Array<AdminForthComponentDeclarationFull>,
1063
1142
  everyPageBottom: Array<AdminForthComponentDeclarationFull>,
1064
1143
  },
1144
+
1145
+ customHeadItems?: {
1146
+ tagName: string;
1147
+ attributes: Record<string, string | boolean>;
1148
+ innerCode?: string;
1149
+ }[];
1150
+
1065
1151
  }
1066
1152
 
1067
1153
  export interface AdminForthConfig extends Omit<AdminForthInputConfig, 'customization' | 'resources'> {
@@ -1109,6 +1195,21 @@ export class Filters {
1109
1195
  static LIKE(field: string, value: any): IAdminForthSingleFilter {
1110
1196
  return { field, operator: AdminForthFilterOperators.LIKE, value };
1111
1197
  }
1198
+ static ILIKE(field: string, value: any): IAdminForthSingleFilter {
1199
+ return { field, operator: AdminForthFilterOperators.ILIKE, value };
1200
+ }
1201
+ static GT_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1202
+ return { field: leftField, operator: AdminForthFilterOperators.GT, rightField };
1203
+ }
1204
+ static GTE_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1205
+ return { field: leftField, operator: AdminForthFilterOperators.GTE, rightField };
1206
+ }
1207
+ static LT_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1208
+ return { field: leftField, operator: AdminForthFilterOperators.LT, rightField };
1209
+ }
1210
+ static LTE_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1211
+ return { field: leftField, operator: AdminForthFilterOperators.LTE, rightField };
1212
+ }
1112
1213
  static AND(
1113
1214
  ...args: (IAdminForthSingleFilter | IAdminForthAndOrFilter | Array<IAdminForthSingleFilter | IAdminForthAndOrFilter>)[]
1114
1215
  ): IAdminForthAndOrFilter {
@@ -1316,9 +1417,13 @@ export interface AdminForthResource extends Omit<AdminForthResourceInput, 'optio
1316
1417
  },
1317
1418
  create?: {
1318
1419
  /**
1420
+ * Should return `ok: true` to continue saving pipeline and allow creating record in database, and `ok: false` to interrupt pipeline and prevent record creation.
1421
+ * If you need to show error on UI, set `error: \<error message\>` in response.
1422
+ *
1319
1423
  * Typical use-cases:
1320
- * - Validate record before saving to database and interrupt execution if validation failed (`allowedActions.create` should be preferred in most cases)
1321
- * - fill-in adminUser as creator of record
1424
+ * - Create record by custom code (return `{ ok: false, newRecordId: <id of created record from custom code> }`)
1425
+ * - 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
1426
+ * - fill-in adminUser as creator of record (set `record.<some field> = x; return \{ ok: true \}`)
1322
1427
  * - Attach additional data to record before saving to database (mostly fillOnCreate should be used instead)
1323
1428
  */
1324
1429
  beforeSave?: Array<BeforeCreateSaveFunction>,
@@ -1469,15 +1574,27 @@ export type ShowInInput = ShowInModernInput | ShowInLegacyInput;
1469
1574
  export type ShowIn = {
1470
1575
  [key in AdminForthResourcePages]: AllowedActionValue
1471
1576
  }
1577
+ export type BackendOnlyInput =
1578
+ | boolean
1579
+ | ((p: {
1580
+ adminUser: AdminUser;
1581
+ resource: AdminForthResource;
1582
+ meta: any;
1583
+ source: ActionCheckSource;
1584
+ adminforth: IAdminForth;
1585
+ }) => boolean | Promise<boolean>);
1586
+
1472
1587
 
1473
- export interface AdminForthResourceColumnInput extends Omit<AdminForthResourceColumnInputCommon, 'showIn'> {
1588
+ export interface AdminForthResourceColumnInput extends Omit<AdminForthResourceColumnInputCommon, 'showIn' | 'backendOnly'> {
1474
1589
  showIn?: ShowInInput,
1475
1590
  foreignResource?: AdminForthForeignResource,
1591
+ backendOnly?: BackendOnlyInput;
1476
1592
  }
1477
1593
 
1478
- export interface AdminForthResourceColumn extends Omit<AdminForthResourceColumnCommon, 'showIn'> {
1594
+ export interface AdminForthResourceColumn extends Omit<AdminForthResourceColumnCommon, 'showIn' | 'backendOnly'> {
1479
1595
  showIn?: ShowIn,
1480
1596
  foreignResource?: AdminForthForeignResource,
1597
+ backendOnly?: BackendOnlyInput;
1481
1598
  }
1482
1599
 
1483
1600
  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 {
@@ -261,11 +261,29 @@ export interface AdminForthComponentDeclarationFull {
261
261
  * </script>
262
262
  *
263
263
  */
264
- meta?: any,
264
+ meta?: {
265
+ /**
266
+ * Controls sidebar and header visibility for custom pages
267
+ * - 'default': Show both sidebar and header (default behavior)
268
+ * - 'none': Hide both sidebar and header (full custom layout)
269
+ * - 'preferIconOnly': Show header but prefer icon-only sidebar
270
+ */
271
+ sidebarAndHeader?: 'default' | 'none' | 'preferIconOnly',
272
+
273
+ [key: string]: any,
274
+ }
265
275
  }
276
+ import { type AdminForthActionInput } from './Back.js'
277
+ export { type AdminForthActionInput } from './Back.js'
266
278
 
267
279
  export type AdminForthComponentDeclaration = AdminForthComponentDeclarationFull | string;
268
280
 
281
+ export type FieldGroup = {
282
+ groupName: string;
283
+ columns: string[];
284
+ noTitle?: boolean;
285
+ };
286
+
269
287
  /**
270
288
  * Resource describes one table or collection in database.
271
289
  * AdminForth generates set of pages for 'list', 'show', 'edit', 'create', 'filter' operations for each resource.
@@ -347,6 +365,11 @@ export interface AdminForthResourceInputCommon {
347
365
  direction: AdminForthSortDirections | string,
348
366
  }
349
367
 
368
+ /*
369
+ * Custom actions list. Actions available in show, edit and create views.
370
+ */
371
+ actions?: AdminForthActionInput[],
372
+
350
373
  /**
351
374
  * Custom bulk actions list. Bulk actions available in list view when user selects multiple records by
352
375
  * using checkboxes.
@@ -374,26 +397,10 @@ export interface AdminForthResourceInputCommon {
374
397
  /**
375
398
  * Allows to make groups of columns in show, create and edit resource pages.
376
399
  */
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
- }[];
400
+ fieldGroups?: FieldGroup[];
401
+ createFieldGroups?: FieldGroup[];
402
+ editFieldGroups?: FieldGroup[];
403
+ showFieldGroups?: FieldGroup[];
397
404
 
398
405
  /**
399
406
  * Page size for list view
@@ -471,6 +478,7 @@ export interface AdminForthResourceInputCommon {
471
478
  list?: {
472
479
  beforeBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
473
480
  afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
481
+ beforeActionButtons?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
474
482
  bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
475
483
  threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
476
484
  customActionIcons?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
@@ -584,6 +592,8 @@ export interface AdminForthForeignResourceCommon {
584
592
  polymorphicResources?: Array<AdminForthPolymorphicForeignResource>,
585
593
  polymorphicOn?: string,
586
594
  unsetLabel?: string,
595
+ searchableFields?: string | string[],
596
+ searchIsCaseSensitive?: boolean,
587
597
  }
588
598
 
589
599
  export type FillOnCreateFunction = (params: {
@@ -810,9 +820,6 @@ export interface AdminForthResourceColumnInputCommon {
810
820
  */
811
821
  minLength?: number,
812
822
 
813
- min?: number,
814
- max?: number,
815
-
816
823
  /**
817
824
  * Minimum value that can be entered in this field.
818
825
  */
@@ -878,6 +885,15 @@ export interface AdminForthResourceColumnCommon extends AdminForthResourceColumn
878
885
 
879
886
  editingNote?: { create?: string, edit?: string },
880
887
 
888
+ /**
889
+ * Minimal value stored in this field.
890
+ */
891
+ min?: number,
892
+
893
+ /**
894
+ * Maximum value stored in this field.
895
+ */
896
+ max?: number,
881
897
  }
882
898
 
883
899
  export enum AdminForthMenuTypes {
@@ -1055,15 +1071,23 @@ export interface AdminForthConfigForFrontend {
1055
1071
  usernameFieldName: string,
1056
1072
  loginBackgroundImage: string,
1057
1073
  loginBackgroundPosition: string,
1074
+ removeBackgroundBlendMode: boolean,
1058
1075
  title?: string,
1059
1076
  demoCredentials?: string,
1060
- loginPromptHTML?: string,
1077
+ loginPromptHTML?: string | (() => string | Promise<string> | void | Promise<void> | Promise<undefined>) | undefined
1061
1078
  loginPageInjections: {
1062
1079
  underInputs: Array<AdminForthComponentDeclaration>,
1080
+ panelHeader: Array<AdminForthComponentDeclaration>,
1063
1081
  },
1064
1082
  rememberMeDays: number,
1065
1083
  showBrandNameInSidebar: boolean,
1084
+ showBrandLogoInSidebar: boolean,
1066
1085
  brandLogo?: string,
1086
+ iconOnlySidebar?: {
1087
+ logo?: string,
1088
+ enabled?: boolean,
1089
+ },
1090
+ singleTheme?: 'light' | 'dark',
1067
1091
  datesFormat: string,
1068
1092
  timeFormat: string,
1069
1093
  auth: any,
@@ -1078,8 +1102,20 @@ export interface AdminForthConfigForFrontend {
1078
1102
  userMenu: Array<AdminForthComponentDeclarationFull>,
1079
1103
  header: Array<AdminForthComponentDeclarationFull>,
1080
1104
  sidebar: Array<AdminForthComponentDeclarationFull>,
1105
+ sidebarTop: Array<AdminForthComponentDeclarationFull>,
1081
1106
  everyPageBottom: Array<AdminForthComponentDeclarationFull>,
1082
- }
1107
+ },
1108
+ customHeadItems?: {
1109
+ tagName: string;
1110
+ attributes: Record<string, string | boolean>;
1111
+ innerCode?: string;
1112
+ }[],
1113
+ settingPages?:{
1114
+ icon?: string,
1115
+ pageLabel: string,
1116
+ slug?: string,
1117
+ component: string,
1118
+ }[],
1083
1119
  }
1084
1120
 
1085
1121
  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,34 @@
1
+ /**
2
+ * Interface for Captcha adapters.
3
+ */
4
+
5
+ export interface CaptchaAdapter {
6
+ /**
7
+ * Returns the script source URL for the captcha widget.
8
+ */
9
+ getScriptSrc(): string;
10
+
11
+ /**
12
+ * Returns the site key for the captcha.
13
+ */
14
+ getSiteKey(): string;
15
+
16
+ /**
17
+ * Returns the widget ID for the captcha.
18
+ */
19
+ getWidgetId(): string;
20
+
21
+ /**
22
+ * Returns the script HTML for the captcha widget.
23
+ */
24
+ getRenderWidgetCode(): string;
25
+
26
+ /**
27
+ * Returns the function name to render the captcha widget.
28
+ */
29
+ getRenderWidgetFunctionName(): string;
30
+ /**
31
+ * Validates the captcha token.
32
+ */
33
+ validate(token: string, ip: string): Promise<Record<string, any>>;
34
+ }
@@ -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
+ }