adminforth 2.4.0-next.26 → 2.4.0-next.261

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 (168) hide show
  1. package/commands/callTsProxy.js +14 -4
  2. package/commands/cli.js +10 -3
  3. package/commands/createApp/templates/api.ts.hbs +10 -0
  4. package/commands/createApp/templates/custom/tsconfig.json.hbs +2 -3
  5. package/commands/createApp/templates/index.ts.hbs +12 -1
  6. package/commands/createApp/utils.js +25 -8
  7. package/commands/createCustomComponent/configLoader.js +17 -4
  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/commands/createPlugin/templates/package.json.hbs +1 -1
  12. package/commands/generateModels.js +30 -22
  13. package/dist/auth.d.ts +9 -1
  14. package/dist/auth.d.ts.map +1 -1
  15. package/dist/auth.js +21 -2
  16. package/dist/auth.js.map +1 -1
  17. package/dist/dataConnectors/baseConnector.d.ts.map +1 -1
  18. package/dist/dataConnectors/baseConnector.js +46 -15
  19. package/dist/dataConnectors/baseConnector.js.map +1 -1
  20. package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
  21. package/dist/dataConnectors/clickhouse.js +15 -0
  22. package/dist/dataConnectors/clickhouse.js.map +1 -1
  23. package/dist/dataConnectors/mongo.d.ts.map +1 -1
  24. package/dist/dataConnectors/mongo.js +50 -15
  25. package/dist/dataConnectors/mongo.js.map +1 -1
  26. package/dist/dataConnectors/mysql.d.ts.map +1 -1
  27. package/dist/dataConnectors/mysql.js +11 -0
  28. package/dist/dataConnectors/mysql.js.map +1 -1
  29. package/dist/dataConnectors/postgres.d.ts.map +1 -1
  30. package/dist/dataConnectors/postgres.js +43 -14
  31. package/dist/dataConnectors/postgres.js.map +1 -1
  32. package/dist/dataConnectors/sqlite.d.ts.map +1 -1
  33. package/dist/dataConnectors/sqlite.js +11 -0
  34. package/dist/dataConnectors/sqlite.js.map +1 -1
  35. package/dist/index.d.ts +2 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +23 -9
  38. package/dist/index.js.map +1 -1
  39. package/dist/modules/codeInjector.d.ts +2 -0
  40. package/dist/modules/codeInjector.d.ts.map +1 -1
  41. package/dist/modules/codeInjector.js +50 -6
  42. package/dist/modules/codeInjector.js.map +1 -1
  43. package/dist/modules/configValidator.d.ts +6 -0
  44. package/dist/modules/configValidator.d.ts.map +1 -1
  45. package/dist/modules/configValidator.js +184 -19
  46. package/dist/modules/configValidator.js.map +1 -1
  47. package/dist/modules/restApi.d.ts.map +1 -1
  48. package/dist/modules/restApi.js +164 -26
  49. package/dist/modules/restApi.js.map +1 -1
  50. package/dist/modules/styles.d.ts +499 -13
  51. package/dist/modules/styles.d.ts.map +1 -1
  52. package/dist/modules/styles.js +555 -31
  53. package/dist/modules/styles.js.map +1 -1
  54. package/dist/modules/utils.d.ts +7 -15
  55. package/dist/modules/utils.d.ts.map +1 -1
  56. package/dist/modules/utils.js +45 -68
  57. package/dist/modules/utils.js.map +1 -1
  58. package/dist/servers/express.d.ts +5 -0
  59. package/dist/servers/express.d.ts.map +1 -1
  60. package/dist/servers/express.js +40 -1
  61. package/dist/servers/express.js.map +1 -1
  62. package/dist/spa/index.html +1 -1
  63. package/dist/spa/package-lock.json +5 -4
  64. package/dist/spa/package.json +1 -1
  65. package/dist/spa/src/App.vue +58 -173
  66. package/dist/spa/src/adminforth.ts +42 -18
  67. package/dist/spa/src/afcl/BarChart.vue +2 -2
  68. package/dist/spa/src/afcl/Button.vue +6 -6
  69. package/dist/spa/src/afcl/ButtonGroup.vue +91 -0
  70. package/dist/spa/src/afcl/Card.vue +25 -0
  71. package/dist/spa/src/afcl/Checkbox.vue +21 -13
  72. package/dist/spa/src/afcl/CountryFlag.vue +4 -1
  73. package/dist/spa/src/{components/CustomDatePicker.vue → afcl/DatePicker.vue} +95 -9
  74. package/dist/spa/src/afcl/Dialog.vue +47 -27
  75. package/dist/spa/src/afcl/Dropzone.vue +12 -12
  76. package/dist/spa/src/afcl/Input.vue +5 -5
  77. package/dist/spa/src/afcl/JsonViewer.vue +25 -0
  78. package/dist/spa/src/afcl/LinkButton.vue +3 -3
  79. package/dist/spa/src/afcl/PieChart.vue +5 -5
  80. package/dist/spa/src/afcl/ProgressBar.vue +7 -7
  81. package/dist/spa/src/afcl/Select.vue +68 -34
  82. package/dist/spa/src/afcl/Skeleton.vue +6 -6
  83. package/dist/spa/src/afcl/Table.vue +213 -74
  84. package/dist/spa/src/afcl/Textarea.vue +31 -0
  85. package/dist/spa/src/afcl/Toggle.vue +32 -0
  86. package/dist/spa/src/afcl/Tooltip.vue +26 -18
  87. package/dist/spa/src/afcl/VerticalTabs.vue +16 -7
  88. package/dist/spa/src/afcl/index.ts +6 -3
  89. package/dist/spa/src/components/AcceptModal.vue +48 -14
  90. package/dist/spa/src/components/Breadcrumbs.vue +5 -5
  91. package/dist/spa/src/components/ColumnValueInput.vue +38 -18
  92. package/dist/spa/src/components/ColumnValueInputWrapper.vue +4 -3
  93. package/dist/spa/src/components/CustomDateRangePicker.vue +9 -8
  94. package/dist/spa/src/components/CustomRangePicker.vue +37 -8
  95. package/dist/spa/src/components/ErrorMessage.vue +21 -0
  96. package/dist/spa/src/components/Filters.vue +85 -39
  97. package/dist/spa/src/components/GroupsTable.vue +9 -8
  98. package/dist/spa/src/components/MenuLink.vue +90 -23
  99. package/dist/spa/src/components/ResourceForm.vue +94 -51
  100. package/dist/spa/src/components/ResourceListTable.vue +90 -80
  101. package/dist/spa/src/components/ResourceListTableVirtual.vue +86 -76
  102. package/dist/spa/src/components/ShowTable.vue +21 -15
  103. package/dist/spa/src/components/Sidebar.vue +470 -0
  104. package/dist/spa/src/components/SingleSkeletLoader.vue +6 -6
  105. package/dist/spa/src/components/SkeleteLoader.vue +3 -3
  106. package/dist/spa/src/components/ThreeDotsMenu.vue +73 -14
  107. package/dist/spa/src/components/Toast.vue +27 -9
  108. package/dist/spa/src/components/UserMenuSettingsButton.vue +69 -0
  109. package/dist/spa/src/components/ValueRenderer.vue +43 -16
  110. package/dist/spa/src/controls/BoolToggle.vue +34 -0
  111. package/dist/spa/src/i18n.ts +1 -1
  112. package/dist/spa/src/renderers/CompactField.vue +1 -1
  113. package/dist/spa/src/renderers/CompactUUID.vue +1 -1
  114. package/dist/spa/src/router/index.ts +8 -0
  115. package/dist/spa/src/shims-vue.d.ts +5 -0
  116. package/dist/spa/src/spa_types/core.ts +13 -1
  117. package/dist/spa/src/stores/core.ts +13 -1
  118. package/dist/spa/src/stores/filters.ts +29 -2
  119. package/dist/spa/src/stores/modal.ts +6 -1
  120. package/dist/spa/src/stores/toast.ts +22 -3
  121. package/dist/spa/src/types/Back.ts +158 -22
  122. package/dist/spa/src/types/Common.ts +81 -32
  123. package/dist/spa/src/types/FrontendAPI.ts +31 -5
  124. package/dist/spa/src/types/adapters/CaptchaAdapter.ts +34 -0
  125. package/dist/spa/src/types/adapters/EmailAdapter.ts +2 -2
  126. package/dist/spa/src/types/adapters/ImageVisionAdapter.ts +30 -0
  127. package/dist/spa/src/types/adapters/KeyValueAdapter.ts +16 -0
  128. package/dist/spa/src/types/adapters/index.ts +8 -0
  129. package/dist/spa/src/utils.ts +279 -9
  130. package/dist/spa/src/views/CreateView.vue +18 -19
  131. package/dist/spa/src/views/EditView.vue +25 -19
  132. package/dist/spa/src/views/ListView.vue +144 -87
  133. package/dist/spa/src/views/LoginView.vue +26 -35
  134. package/dist/spa/src/views/ResourceParent.vue +2 -2
  135. package/dist/spa/src/views/SettingsView.vue +121 -0
  136. package/dist/spa/src/views/ShowView.vue +59 -39
  137. package/dist/spa/src/websocket.ts +6 -1
  138. package/dist/spa/tsconfig.app.json +1 -1
  139. package/dist/spa/vite.config.ts +45 -2
  140. package/dist/types/Back.d.ts +134 -14
  141. package/dist/types/Back.d.ts.map +1 -1
  142. package/dist/types/Back.js +15 -0
  143. package/dist/types/Back.js.map +1 -1
  144. package/dist/types/Common.d.ts +96 -29
  145. package/dist/types/Common.d.ts.map +1 -1
  146. package/dist/types/Common.js.map +1 -1
  147. package/dist/types/FrontendAPI.d.ts +31 -3
  148. package/dist/types/FrontendAPI.d.ts.map +1 -1
  149. package/dist/types/FrontendAPI.js.map +1 -1
  150. package/dist/types/adapters/CaptchaAdapter.d.ts +30 -0
  151. package/dist/types/adapters/CaptchaAdapter.d.ts.map +1 -0
  152. package/dist/types/adapters/CaptchaAdapter.js +5 -0
  153. package/dist/types/adapters/CaptchaAdapter.js.map +1 -0
  154. package/dist/types/adapters/EmailAdapter.d.ts +1 -1
  155. package/dist/types/adapters/ImageVisionAdapter.d.ts +25 -0
  156. package/dist/types/adapters/ImageVisionAdapter.d.ts.map +1 -0
  157. package/dist/types/adapters/ImageVisionAdapter.js +2 -0
  158. package/dist/types/adapters/ImageVisionAdapter.js.map +1 -0
  159. package/dist/types/adapters/KeyValueAdapter.d.ts +10 -0
  160. package/dist/types/adapters/KeyValueAdapter.d.ts.map +1 -0
  161. package/dist/types/adapters/KeyValueAdapter.js +2 -0
  162. package/dist/types/adapters/KeyValueAdapter.js.map +1 -0
  163. package/dist/types/adapters/index.d.ts +9 -0
  164. package/dist/types/adapters/index.d.ts.map +1 -0
  165. package/dist/types/adapters/index.js +2 -0
  166. package/dist/types/adapters/index.js.map +1 -0
  167. package/package.json +4 -2
  168. package/dist/spa/src/types/adapters/index.js +0 -5
@@ -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,12 +22,13 @@ 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
 
29
29
  export interface IConfigValidator {
30
30
  validateConfig(): void;
31
+ validateAfterPluginsActivation(): void;
31
32
  postProcessAfterDiscover(resource: AdminForthResource): void;
32
33
  }
33
34
 
@@ -92,19 +93,36 @@ export interface IExpressHttpServer extends IHttpServer {
92
93
  * Adds adminUser to request object if user is authorized. Drops request with 401 status if user is not authorized.
93
94
  * @param callable : Function which will be called if user is authorized.
94
95
  *
95
- * Example:
96
96
  *
97
+ * @example
97
98
  * ```ts
98
- * expressApp.get('/myApi', authorize((req, res) => \{
99
+ * expressApp.get('/myApi', authorize((req, res) => {
99
100
  * console.log('User is authorized', req.adminUser);
100
- * res.json(\{ message: 'Hello World' \});
101
- * \}));
102
- * ``
101
+ * res.json({ message: 'Hello World' });
102
+ * }));
103
+ * ```
103
104
  *
104
- */
105
+ */
105
106
  authorize(callable: Function): void;
106
107
  }
107
108
 
109
+ export interface ITranslateFunction {
110
+ (
111
+ msg: string,
112
+ category: string,
113
+ params: any,
114
+ pluralizationNumber?: number
115
+ ): Promise<string>;
116
+ }
117
+
118
+ // Omit <Request, 'param'> is used to remove 'param' method from Request type for correct docs generation
119
+ export interface IAdminUserExpressRequest extends Omit<Request, 'protocol' | 'param' | 'unshift'> {
120
+ adminUser: AdminUser;
121
+ }
122
+
123
+ export interface ITranslateExpressRequest extends Omit<Request, 'protocol' | 'param' | 'unshift'> {
124
+ tr: ITranslateFunction;
125
+ }
108
126
 
109
127
  export interface IAdminForthSingleFilter {
110
128
  field?: string;
@@ -113,7 +131,9 @@ export interface IAdminForthSingleFilter {
113
131
  | AdminForthFilterOperators.LTE | AdminForthFilterOperators.LIKE | AdminForthFilterOperators.ILIKE
114
132
  | AdminForthFilterOperators.IN | AdminForthFilterOperators.NIN;
115
133
  value?: any;
134
+ rightField?: string;
116
135
  insecureRawSQL?: string;
136
+ insecureRawNoSQL?: any;
117
137
  }
118
138
  export interface IAdminForthAndOrFilter {
119
139
  operator: AdminForthFilterOperators.AND | AdminForthFilterOperators.OR;
@@ -287,6 +307,10 @@ export interface IAdminForthAuth {
287
307
 
288
308
  removeCustomCookie({response, name}: {response: any, name: string}): void;
289
309
 
310
+ setCustomCookie({response, payload}: {response: any, payload: {name: string, value: string, expiry: number, expirySeconds: number, httpOnly: boolean}}): void;
311
+
312
+ getCustomCookie({cookies, name}: {cookies: {key: string, value: string}[], name: string}): string | null;
313
+
290
314
  setAuthCookie({expireInDays, response, username, pk,}: {expireInDays?: number, response: any, username: string, pk: string}): void;
291
315
 
292
316
  removeAuthCookie(response: any): void;
@@ -336,7 +360,7 @@ export interface IAdminForth {
336
360
 
337
361
  createResourceRecord(
338
362
  params: { resource: AdminForthResource, record: any, adminUser: AdminUser, extra?: HttpExtra }
339
- ): Promise<{ error?: string, createdRecord?: any }>;
363
+ ): Promise<{ error?: string, createdRecord?: any, newRecordId?: any }>;
340
364
 
341
365
  updateResourceRecord(
342
366
  params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra }
@@ -474,7 +498,7 @@ export type BeforeDataSourceRequestFunction = (params: {
474
498
  requestUrl: string,
475
499
  },
476
500
  adminforth: IAdminForth,
477
- }) => Promise<{ok: boolean, error?: string}>;
501
+ }) => Promise<{ok: boolean, error?: string, newRecordId?: string}>;
478
502
 
479
503
  /**
480
504
  * Modify response to change how data is returned after fetching from database.
@@ -525,7 +549,7 @@ export type BeforeEditSaveFunction = (params: {
525
549
  oldRecord: any,
526
550
  adminforth: IAdminForth,
527
551
  extra?: HttpExtra,
528
- }) => Promise<{ok: boolean, error?: string}>;
552
+ }) => Promise<{ok: boolean, error?: string | null}>;
529
553
 
530
554
 
531
555
 
@@ -535,7 +559,7 @@ export type BeforeCreateSaveFunction = (params: {
535
559
  record: any,
536
560
  adminforth: IAdminForth,
537
561
  extra?: HttpExtra,
538
- }) => Promise<{ok: boolean, error?: string}>;
562
+ }) => Promise<{ok: boolean, error?: string | null, newRecordId?: string}>;
539
563
 
540
564
  export type AfterCreateSaveFunction = (params: {
541
565
  resource: AdminForthResource,
@@ -587,6 +611,19 @@ export type BeforeLoginConfirmationFunction = (params?: {
587
611
  }
588
612
  }>;
589
613
 
614
+ /**
615
+ * Allow to make extra authorization
616
+ */
617
+ export type AdminUserAuthorizeFunction = ((params?: {
618
+ adminUser: AdminUser,
619
+ response: IAdminForthHttpResponse,
620
+ adminforth: IAdminForth,
621
+ extra?: HttpExtra,
622
+ }) => Promise<{
623
+ error?: string,
624
+ allowed?: boolean,
625
+ }>);
626
+
590
627
 
591
628
  /**
592
629
  * Data source describes database connection which will be used to fetch data for resources.
@@ -619,12 +656,23 @@ interface AdminForthInputConfigCustomization {
619
656
  */
620
657
  brandName?: string,
621
658
 
659
+ /**
660
+ * Whether to use single theme for the app
661
+ */
662
+ singleTheme?: 'light' | 'dark',
663
+
622
664
  /**
623
665
  * Whether to show brand name in sidebar
624
666
  * default is true
625
667
  */
626
668
  showBrandNameInSidebar?: boolean,
627
669
 
670
+ /**
671
+ * Whether to show brand logo in sidebar
672
+ * default is true
673
+ */
674
+ showBrandLogoInSidebar?: boolean,
675
+
628
676
  /**
629
677
  * Path to your app logo
630
678
  *
@@ -638,6 +686,19 @@ interface AdminForthInputConfigCustomization {
638
686
  */
639
687
  brandLogo?: string,
640
688
 
689
+
690
+ /**
691
+ * Path to your app logo for icon only sidebar
692
+ *
693
+ * Example:
694
+ * Place file `logo.svg` to `./custom` folder and set this option:
695
+ *
696
+ */
697
+ iconOnlySidebar?: {
698
+ logo?: string,
699
+ enabled?: boolean,
700
+ },
701
+
641
702
  /**
642
703
  * Path to your app favicon
643
704
  *
@@ -747,6 +808,7 @@ interface AdminForthInputConfigCustomization {
747
808
  */
748
809
  loginPageInjections?: {
749
810
  underInputs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
811
+ underLoginButton?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
750
812
  panelHeader?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
751
813
  }
752
814
 
@@ -757,8 +819,20 @@ interface AdminForthInputConfigCustomization {
757
819
  userMenu?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
758
820
  header?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
759
821
  sidebar?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
822
+ sidebarTop?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
760
823
  everyPageBottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
761
824
  }
825
+
826
+ /**
827
+ * Allows adding custom elements (e.g., &lt;link&gt;, &lt;script&gt;, &lt;meta&gt;) to the &lt;head&gt; of the HTML document.
828
+ * Each item must include a tag name and a set of attributes.
829
+ */
830
+ customHeadItems?: {
831
+ tagName: string;
832
+ attributes: Record<string, string | boolean>;
833
+ innerCode?: string;
834
+ }[];
835
+
762
836
  }
763
837
 
764
838
  export interface AdminForthActionInput {
@@ -935,12 +1009,24 @@ export interface AdminForthInputConfig {
935
1009
  */
936
1010
  loginBackgroundPosition?: 'over' | '1/2' | '1/3' | '2/3' | '3/4' | '2/5' | '3/5',
937
1011
 
1012
+ /**
1013
+ * If true, background blend mode will be removed from login background image when position is 'over'
1014
+ *
1015
+ * Default: false
1016
+ */
1017
+ removeBackgroundBlendMode?: boolean,
1018
+
938
1019
  /**
939
1020
  * Function or functions which will be called before user try to login.
940
1021
  * Each function will resive User object as an argument
941
1022
  */
942
1023
  beforeLoginConfirmation?: BeforeLoginConfirmationFunction | Array<BeforeLoginConfirmationFunction>,
943
1024
 
1025
+ /**
1026
+ * Array of functions which will be called before any request to AdminForth API.
1027
+ */
1028
+ adminUserAuthorize?: AdminUserAuthorizeFunction | Array<AdminUserAuthorizeFunction>,
1029
+
944
1030
  /**
945
1031
  * Optionally if your users table has a field(column) with full name, you can set it here.
946
1032
  * This field will be used to display user name in the top right corner of the admin panel.
@@ -956,7 +1042,7 @@ export interface AdminForthInputConfig {
956
1042
  /**
957
1043
  * Any prompt to show users on login. Supports HTML.
958
1044
  */
959
- loginPromptHTML?: string,
1045
+ loginPromptHTML?: string | (() => string | void | undefined | Promise<string | void | undefined>) | undefined
960
1046
 
961
1047
  /**
962
1048
  * Remember me days for "Remember Me" checkbox on login page.
@@ -988,6 +1074,16 @@ export interface AdminForthInputConfig {
988
1074
  * If you are using Cloudflare, set this to 'CF-Connecting-IP'. Case-insensitive.
989
1075
  */
990
1076
  clientIpHeader?: string,
1077
+
1078
+ /**
1079
+ * Add custom page to the settings page
1080
+ */
1081
+ userMenuSettingsPages: {
1082
+ icon?: string,
1083
+ pageLabel: string,
1084
+ slug?: string,
1085
+ component: string
1086
+ }[],
991
1087
  },
992
1088
 
993
1089
  /**
@@ -1055,6 +1151,7 @@ export interface AdminForthConfigCustomization extends Omit<AdminForthInputConfi
1055
1151
 
1056
1152
  loginPageInjections: {
1057
1153
  underInputs: Array<AdminForthComponentDeclarationFull>,
1154
+ underLoginButton?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
1058
1155
  panelHeader: Array<AdminForthComponentDeclarationFull>,
1059
1156
  },
1060
1157
 
@@ -1062,8 +1159,16 @@ export interface AdminForthConfigCustomization extends Omit<AdminForthInputConfi
1062
1159
  userMenu: Array<AdminForthComponentDeclarationFull>,
1063
1160
  header: Array<AdminForthComponentDeclarationFull>,
1064
1161
  sidebar: Array<AdminForthComponentDeclarationFull>,
1162
+ sidebarTop: Array<AdminForthComponentDeclarationFull>,
1065
1163
  everyPageBottom: Array<AdminForthComponentDeclarationFull>,
1066
1164
  },
1165
+
1166
+ customHeadItems?: {
1167
+ tagName: string;
1168
+ attributes: Record<string, string | boolean>;
1169
+ innerCode?: string;
1170
+ }[];
1171
+
1067
1172
  }
1068
1173
 
1069
1174
  export interface AdminForthConfig extends Omit<AdminForthInputConfig, 'customization' | 'resources'> {
@@ -1111,6 +1216,21 @@ export class Filters {
1111
1216
  static LIKE(field: string, value: any): IAdminForthSingleFilter {
1112
1217
  return { field, operator: AdminForthFilterOperators.LIKE, value };
1113
1218
  }
1219
+ static ILIKE(field: string, value: any): IAdminForthSingleFilter {
1220
+ return { field, operator: AdminForthFilterOperators.ILIKE, value };
1221
+ }
1222
+ static GT_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1223
+ return { field: leftField, operator: AdminForthFilterOperators.GT, rightField };
1224
+ }
1225
+ static GTE_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1226
+ return { field: leftField, operator: AdminForthFilterOperators.GTE, rightField };
1227
+ }
1228
+ static LT_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1229
+ return { field: leftField, operator: AdminForthFilterOperators.LT, rightField };
1230
+ }
1231
+ static LTE_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
1232
+ return { field: leftField, operator: AdminForthFilterOperators.LTE, rightField };
1233
+ }
1114
1234
  static AND(
1115
1235
  ...args: (IAdminForthSingleFilter | IAdminForthAndOrFilter | Array<IAdminForthSingleFilter | IAdminForthAndOrFilter>)[]
1116
1236
  ): IAdminForthAndOrFilter {
@@ -1318,9 +1438,13 @@ export interface AdminForthResource extends Omit<AdminForthResourceInput, 'optio
1318
1438
  },
1319
1439
  create?: {
1320
1440
  /**
1441
+ * Should return `ok: true` to continue saving pipeline and allow creating record in database, and `ok: false` to interrupt pipeline and prevent record creation.
1442
+ * If you need to show error on UI, set `error: \<error message\>` in response.
1443
+ *
1321
1444
  * 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
1445
+ * - Create record by custom code (return `{ ok: false, newRecordId: <id of created record from custom code> }`)
1446
+ * - 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
1447
+ * - fill-in adminUser as creator of record (set `record.<some field> = x; return \{ ok: true \}`)
1324
1448
  * - Attach additional data to record before saving to database (mostly fillOnCreate should be used instead)
1325
1449
  */
1326
1450
  beforeSave?: Array<BeforeCreateSaveFunction>,
@@ -1471,15 +1595,27 @@ export type ShowInInput = ShowInModernInput | ShowInLegacyInput;
1471
1595
  export type ShowIn = {
1472
1596
  [key in AdminForthResourcePages]: AllowedActionValue
1473
1597
  }
1598
+ export type BackendOnlyInput =
1599
+ | boolean
1600
+ | ((p: {
1601
+ adminUser: AdminUser;
1602
+ resource: AdminForthResource;
1603
+ meta: any;
1604
+ source: ActionCheckSource;
1605
+ adminforth: IAdminForth;
1606
+ }) => boolean | Promise<boolean>);
1607
+
1474
1608
 
1475
- export interface AdminForthResourceColumnInput extends Omit<AdminForthResourceColumnInputCommon, 'showIn'> {
1609
+ export interface AdminForthResourceColumnInput extends Omit<AdminForthResourceColumnInputCommon, 'showIn' | 'backendOnly'> {
1476
1610
  showIn?: ShowInInput,
1477
1611
  foreignResource?: AdminForthForeignResource,
1612
+ backendOnly?: BackendOnlyInput;
1478
1613
  }
1479
1614
 
1480
- export interface AdminForthResourceColumn extends Omit<AdminForthResourceColumnCommon, 'showIn'> {
1615
+ export interface AdminForthResourceColumn extends Omit<AdminForthResourceColumnCommon, 'showIn' | 'backendOnly'> {
1481
1616
  showIn?: ShowIn,
1482
1617
  foreignResource?: AdminForthForeignResource,
1618
+ backendOnly?: BackendOnlyInput;
1483
1619
  }
1484
1620
 
1485
1621
  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
  */
@@ -68,6 +67,11 @@ export type AllowedActionsResolved = {
68
67
  [key in AllowedActionsEnum]: boolean
69
68
  }
70
69
 
70
+ // conditional operators for predicates
71
+ type Value = any;
72
+ type Operators = { $eq: Value } | { $not: Value } | { $gt: Value } | { $gte: Value } | { $lt: Value } | { $lte: Value } | { $in: Value[] } | { $nin: Value[] } | { $includes: Value } | { $nincludes: Value };
73
+ export type Predicate = { $and: Predicate[] } | { $or: Predicate[] } | { [key: string]: Operators | Value };
74
+
71
75
  export interface AdminUser {
72
76
  /**
73
77
  * primaryKey field value of user in table which is defined by {@link AdminForthConfig.auth.usersResourceId}
@@ -95,12 +99,9 @@ export interface AdminForthBulkActionCommon {
95
99
  label: string,
96
100
 
97
101
  /**
98
- * Bulk Action button state 'danger'|success|'active',
99
- * * 'danger' - red button
100
- * * 'success' - green button
101
- * * 'active' - blue button
102
+ * Add custom class
102
103
  **/
103
- state?: 'danger' | 'success' | 'active';
104
+ buttonCustomCssClass?: string;
104
105
 
105
106
  /**
106
107
  * Optional small badge for button which will be displayed in the list view
@@ -122,6 +123,10 @@ export interface AdminForthBulkActionCommon {
122
123
  */
123
124
  successMessage?: string,
124
125
 
126
+ /**
127
+ * Show in three dots dropdown menu in list view.
128
+ */
129
+ showInThreeDotsDropdown?: boolean,
125
130
  }
126
131
 
127
132
  export interface AdminForthFieldComponents {
@@ -261,11 +266,29 @@ export interface AdminForthComponentDeclarationFull {
261
266
  * </script>
262
267
  *
263
268
  */
264
- meta?: any,
269
+ meta?: {
270
+ /**
271
+ * Controls sidebar and header visibility for custom pages
272
+ * - 'default': Show both sidebar and header (default behavior)
273
+ * - 'none': Hide both sidebar and header (full custom layout)
274
+ * - 'preferIconOnly': Show header but prefer icon-only sidebar
275
+ */
276
+ sidebarAndHeader?: 'default' | 'none' | 'preferIconOnly',
277
+
278
+ [key: string]: any,
279
+ }
265
280
  }
281
+ import { type AdminForthActionInput } from './Back.js'
282
+ export { type AdminForthActionInput } from './Back.js'
266
283
 
267
284
  export type AdminForthComponentDeclaration = AdminForthComponentDeclarationFull | string;
268
285
 
286
+ export type FieldGroup = {
287
+ groupName: string;
288
+ columns: string[];
289
+ noTitle?: boolean;
290
+ };
291
+
269
292
  /**
270
293
  * Resource describes one table or collection in database.
271
294
  * AdminForth generates set of pages for 'list', 'show', 'edit', 'create', 'filter' operations for each resource.
@@ -347,6 +370,11 @@ export interface AdminForthResourceInputCommon {
347
370
  direction: AdminForthSortDirections | string,
348
371
  }
349
372
 
373
+ /*
374
+ * Custom actions list. Actions available in show, edit and create views.
375
+ */
376
+ actions?: AdminForthActionInput[],
377
+
350
378
  /**
351
379
  * Custom bulk actions list. Bulk actions available in list view when user selects multiple records by
352
380
  * using checkboxes.
@@ -374,26 +402,10 @@ export interface AdminForthResourceInputCommon {
374
402
  /**
375
403
  * Allows to make groups of columns in show, create and edit resource pages.
376
404
  */
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
- }[];
405
+ fieldGroups?: FieldGroup[];
406
+ createFieldGroups?: FieldGroup[];
407
+ editFieldGroups?: FieldGroup[];
408
+ showFieldGroups?: FieldGroup[];
397
409
 
398
410
  /**
399
411
  * Page size for list view
@@ -471,6 +483,7 @@ export interface AdminForthResourceInputCommon {
471
483
  list?: {
472
484
  beforeBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
473
485
  afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
486
+ beforeActionButtons?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
474
487
  bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
475
488
  threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
476
489
  customActionIcons?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
@@ -584,6 +597,8 @@ export interface AdminForthForeignResourceCommon {
584
597
  polymorphicResources?: Array<AdminForthPolymorphicForeignResource>,
585
598
  polymorphicOn?: string,
586
599
  unsetLabel?: string,
600
+ searchableFields?: string | string[],
601
+ searchIsCaseSensitive?: boolean,
587
602
  }
588
603
 
589
604
  export type FillOnCreateFunction = (params: {
@@ -810,9 +825,6 @@ export interface AdminForthResourceColumnInputCommon {
810
825
  */
811
826
  minLength?: number,
812
827
 
813
- min?: number,
814
- max?: number,
815
-
816
828
  /**
817
829
  * Minimum value that can be entered in this field.
818
830
  */
@@ -865,6 +877,15 @@ export interface AdminForthResourceColumnInputCommon {
865
877
  */
866
878
  masked?: boolean,
867
879
 
880
+ /**
881
+ * Sticky position for column
882
+ */
883
+ listSticky?: boolean;
884
+
885
+ /**
886
+ * Show field only if certain conditions are met.
887
+ */
888
+ showIf?: Predicate;
868
889
  }
869
890
 
870
891
  export interface AdminForthResourceColumnCommon extends AdminForthResourceColumnInputCommon {
@@ -878,6 +899,15 @@ export interface AdminForthResourceColumnCommon extends AdminForthResourceColumn
878
899
 
879
900
  editingNote?: { create?: string, edit?: string },
880
901
 
902
+ /**
903
+ * Minimal value stored in this field.
904
+ */
905
+ min?: number,
906
+
907
+ /**
908
+ * Maximum value stored in this field.
909
+ */
910
+ max?: number,
881
911
  }
882
912
 
883
913
  export enum AdminForthMenuTypes {
@@ -1055,16 +1085,23 @@ export interface AdminForthConfigForFrontend {
1055
1085
  usernameFieldName: string,
1056
1086
  loginBackgroundImage: string,
1057
1087
  loginBackgroundPosition: string,
1088
+ removeBackgroundBlendMode: boolean,
1058
1089
  title?: string,
1059
1090
  demoCredentials?: string,
1060
- loginPromptHTML?: string,
1091
+ loginPromptHTML?: string | (() => string | Promise<string> | void | Promise<void> | Promise<undefined>) | undefined
1061
1092
  loginPageInjections: {
1062
1093
  underInputs: Array<AdminForthComponentDeclaration>,
1063
1094
  panelHeader: Array<AdminForthComponentDeclaration>,
1064
1095
  },
1065
1096
  rememberMeDays: number,
1066
1097
  showBrandNameInSidebar: boolean,
1098
+ showBrandLogoInSidebar: boolean,
1067
1099
  brandLogo?: string,
1100
+ iconOnlySidebar?: {
1101
+ logo?: string,
1102
+ enabled?: boolean,
1103
+ },
1104
+ singleTheme?: 'light' | 'dark',
1068
1105
  datesFormat: string,
1069
1106
  timeFormat: string,
1070
1107
  auth: any,
@@ -1079,8 +1116,20 @@ export interface AdminForthConfigForFrontend {
1079
1116
  userMenu: Array<AdminForthComponentDeclarationFull>,
1080
1117
  header: Array<AdminForthComponentDeclarationFull>,
1081
1118
  sidebar: Array<AdminForthComponentDeclarationFull>,
1119
+ sidebarTop: Array<AdminForthComponentDeclarationFull>,
1082
1120
  everyPageBottom: Array<AdminForthComponentDeclarationFull>,
1083
- }
1121
+ },
1122
+ customHeadItems?: {
1123
+ tagName: string;
1124
+ attributes: Record<string, string | boolean>;
1125
+ innerCode?: string;
1126
+ }[],
1127
+ settingPages?:{
1128
+ icon?: string,
1129
+ pageLabel: string,
1130
+ slug?: string,
1131
+ component: string,
1132
+ }[],
1084
1133
  }
1085
1134
 
1086
1135
  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