cabloy 5.1.95 → 5.1.97

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/.cabloy-version +1 -0
  2. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +4 -1
  3. package/.claude/skills/cabloy-resource-field-update/SKILL.md +6 -3
  4. package/.github/workflows/vona-test-crud.yml +2 -0
  5. package/.github/workflows/vona-test-mysql.yml +2 -0
  6. package/.github/workflows/vona-test-pg.yml +2 -0
  7. package/.github/workflows/vona-test-sqlite3.yml +2 -0
  8. package/CHANGELOG.md +38 -0
  9. package/CLAUDE.md +1 -0
  10. package/cabloy-docs/ai/playbook-backend-module.md +6 -3
  11. package/cabloy-docs/fullstack/framework-performance.md +3 -3
  12. package/cabloy-docs/fullstack/quickstart.md +1 -1
  13. package/package.json +1 -1
  14. package/scripts/release.ts +27 -1
  15. package/vona/docker-compose-original/docker-compose-dockerfile-app +4 -0
  16. package/vona/docker-compose-original/docker-compose.original.yml +0 -1
  17. package/vona/env/.env +0 -1
  18. package/vona/env/.env.prod +0 -1
  19. package/vona/env/.env.prod.docker +0 -7
  20. package/vona/package.original.json +3 -3
  21. package/vona/packages-cli/cabloy-cli/package.json +2 -2
  22. package/vona/packages-cli/cli/package.json +1 -1
  23. package/vona/packages-cli/cli-set-api/package.json +2 -2
  24. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.bin.build.ts +70 -2
  25. package/vona/packages-utils/babel-plugin-vona-bean-module/package.json +2 -2
  26. package/vona/packages-utils/module-glob/package.json +2 -2
  27. package/vona/packages-utils/module-info-pro/package.json +2 -2
  28. package/vona/packages-utils/utils/package.json +2 -2
  29. package/vona/packages-vona/vona/package.json +1 -1
  30. package/vona/packages-vona/vona-core/package.json +2 -2
  31. package/vona/packages-vona/vona-core/src/lib/addon/addon.ts +77 -0
  32. package/vona/packages-vona/vona-core/src/lib/addon/index.ts +3 -0
  33. package/vona/packages-vona/vona-core/src/lib/addon/sharp.ts +46 -0
  34. package/vona/packages-vona/vona-core/src/lib/addon/sqlite3.ts +23 -0
  35. package/vona/packages-vona/vona-core/src/lib/index.ts +1 -0
  36. package/vona/packages-vona/vona-core/src/lib/utils/index.ts +0 -1
  37. package/vona/packages-vona/vona-core/src/lib/utils/util.ts +5 -0
  38. package/vona/packages-vona/vona-mock/package.json +2 -2
  39. package/vona/pnpm-lock.yaml +441 -62
  40. package/vona/pnpm-workspace.yaml +1 -1
  41. package/vona/src/backend/cli.ts +2 -5
  42. package/vona/src/backend/config/config/config.ts +0 -4
  43. package/vona/src/suite/a-demo/modules/demo-basic/src/bean/ssrMenu.admin.ts +1 -1
  44. package/vona/src/suite/a-training/modules/training-record/src/.metadata/index.ts +26 -0
  45. package/vona/src/suite/a-training/modules/training-record/src/bean/imageScene.sceneImage.ts +11 -0
  46. package/vona/src/suite/a-training/modules/training-record/src/bean/meta.version.ts +1 -0
  47. package/vona/src/suite/a-training/modules/training-record/src/config/locale/en-us.ts +1 -0
  48. package/vona/src/suite/a-training/modules/training-record/src/config/locale/zh-cn.ts +1 -0
  49. package/vona/src/suite/a-training/modules/training-record/src/dto/recordSelectResItem.tsx +12 -0
  50. package/vona/src/suite/a-training/modules/training-record/src/dto/recordView.tsx +12 -0
  51. package/vona/src/suite/a-training/modules/training-record/src/entity/record.tsx +26 -1
  52. package/vona/src/suite/a-training/modules/training-record/src/index.ts +1 -0
  53. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +27 -1
  54. package/vona/src/suite/a-training/modules/training-student/src/bean/imageScene.studentImage.ts +10 -0
  55. package/vona/src/suite/a-training/modules/training-student/src/bean/meta.version.ts +1 -0
  56. package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +1 -0
  57. package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +1 -0
  58. package/vona/src/suite/a-training/modules/training-student/src/dto/detailRecordBase.tsx +16 -2
  59. package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +1 -1
  60. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +12 -0
  61. package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +1 -1
  62. package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +13 -1
  63. package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +26 -1
  64. package/vona/src/suite/a-training/modules/training-student/src/index.ts +1 -0
  65. package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +1 -0
  66. package/vona/src/suite-vendor/a-auth/modules/a-auth/package.json +1 -1
  67. package/vona/src/suite-vendor/a-auth/modules/a-auth/src/bean/bean.authProvider.ts +2 -5
  68. package/vona/src/suite-vendor/a-auth/package.json +1 -1
  69. package/vona/src/suite-vendor/a-image/modules/a-image/cli/imageProvider/boilerplate/{{sceneName}}.{{beanName}}.ts_ +23 -0
  70. package/vona/src/suite-vendor/a-image/modules/a-image/cli/imageScene/boilerplate/{{sceneName}}.{{beanName}}.ts_ +5 -0
  71. package/vona/src/suite-vendor/a-image/modules/a-image/package.json +68 -0
  72. package/vona/src/suite-vendor/a-image/modules/a-image/src/.metadata/index.ts +482 -0
  73. package/vona/src/suite-vendor/a-image/modules/a-image/src/.metadata/locales.ts +18 -0
  74. package/vona/src/suite-vendor/a-image/modules/a-image/src/.metadata/this.ts +2 -0
  75. package/vona/src/suite-vendor/a-image/modules/a-image/src/bean/bean.image.ts +443 -0
  76. package/vona/src/suite-vendor/a-image/modules/a-image/src/bean/bean.imageProvider.ts +55 -0
  77. package/vona/src/suite-vendor/a-image/modules/a-image/src/bean/bean.imageUploadPolicy.ts +174 -0
  78. package/vona/src/suite-vendor/a-image/modules/a-image/src/bean/meta.redlock.ts +11 -0
  79. package/vona/src/suite-vendor/a-image/modules/a-image/src/bean/meta.version.ts +40 -0
  80. package/vona/src/suite-vendor/a-image/modules/a-image/src/bean/serializerTransform.resolveView.ts +44 -0
  81. package/vona/src/suite-vendor/a-image/modules/a-image/src/bean/serializerTransform.resolveViews.ts +44 -0
  82. package/vona/src/suite-vendor/a-image/modules/a-image/src/config/config.ts +17 -0
  83. package/vona/src/suite-vendor/a-image/modules/a-image/src/config/locale/en-us.ts +1 -0
  84. package/vona/src/suite-vendor/a-image/modules/a-image/src/config/locale/zh-cn.ts +1 -0
  85. package/vona/src/suite-vendor/a-image/modules/a-image/src/controller/image.ts +165 -0
  86. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageDeliveryRequest.ts +20 -0
  87. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageDirectUploadRequest.ts +36 -0
  88. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageDirectUploadResponse.ts +38 -0
  89. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageTransformOptions.tsx +42 -0
  90. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageUploadResponse.ts +62 -0
  91. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageUploadTokenRequest.ts +24 -0
  92. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageUploadTokenResponse.ts +16 -0
  93. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageUploadUrlRequest.ts +33 -0
  94. package/vona/src/suite-vendor/a-image/modules/a-image/src/dto/imageView.ts +46 -0
  95. package/vona/src/suite-vendor/a-image/modules/a-image/src/entity/image.ts +58 -0
  96. package/vona/src/suite-vendor/a-image/modules/a-image/src/entity/imageProvider.ts +24 -0
  97. package/vona/src/suite-vendor/a-image/modules/a-image/src/index.ts +4 -0
  98. package/vona/src/suite-vendor/a-image/modules/a-image/src/lib/imageProvider.ts +9 -0
  99. package/vona/src/suite-vendor/a-image/modules/a-image/src/lib/imageScene.ts +7 -0
  100. package/vona/src/suite-vendor/a-image/modules/a-image/src/lib/imageVariant.ts +46 -0
  101. package/vona/src/suite-vendor/a-image/modules/a-image/src/lib/index.ts +3 -0
  102. package/vona/src/suite-vendor/a-image/modules/a-image/src/model/image.ts +10 -0
  103. package/vona/src/suite-vendor/a-image/modules/a-image/src/model/imageProvider.ts +10 -0
  104. package/vona/src/suite-vendor/a-image/modules/a-image/src/types/image.ts +208 -0
  105. package/vona/src/suite-vendor/a-image/modules/a-image/src/types/imageProvider.ts +110 -0
  106. package/vona/src/suite-vendor/a-image/modules/a-image/src/types/imageScene.ts +52 -0
  107. package/vona/src/suite-vendor/a-image/modules/a-image/src/types/index.ts +3 -0
  108. package/vona/src/suite-vendor/a-image/modules/a-image/tsconfig.build.json +11 -0
  109. package/vona/src/suite-vendor/a-image/modules/a-image/tsconfig.json +7 -0
  110. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/package.json +49 -0
  111. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/.metadata/index.ts +89 -0
  112. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/.metadata/this.ts +2 -0
  113. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/bean/imageProvider.cloudflare.ts +155 -0
  114. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/index.ts +1 -0
  115. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/lib/cloudflareImageUrl.ts +112 -0
  116. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/service/imageCloudflare.ts +273 -0
  117. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/tsconfig.build.json +11 -0
  118. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/tsconfig.json +7 -0
  119. package/vona/src/suite-vendor/a-image/modules/image-native/package.json +63 -0
  120. package/vona/src/suite-vendor/a-image/modules/image-native/src/.metadata/index.ts +114 -0
  121. package/vona/src/suite-vendor/a-image/modules/image-native/src/.metadata/this.ts +2 -0
  122. package/vona/src/suite-vendor/a-image/modules/image-native/src/bean/imageProvider.native.ts +131 -0
  123. package/vona/src/suite-vendor/a-image/modules/image-native/src/config/config.ts +11 -0
  124. package/vona/src/suite-vendor/a-image/modules/image-native/src/index.ts +1 -0
  125. package/vona/src/suite-vendor/a-image/modules/image-native/src/monkey.ts +33 -0
  126. package/vona/src/suite-vendor/a-image/modules/image-native/src/service/imageNative.ts +291 -0
  127. package/vona/src/suite-vendor/a-image/modules/image-native/tsconfig.build.json +11 -0
  128. package/vona/src/suite-vendor/a-image/modules/image-native/tsconfig.json +7 -0
  129. package/vona/src/suite-vendor/a-image/package.json +14 -0
  130. package/vona/src/suite-vendor/a-image/tsconfig.base.json +4 -0
  131. package/vona/src/suite-vendor/a-image/tsconfig.json +16 -0
  132. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +2 -2
  133. package/vona/src/suite-vendor/a-vona/modules/a-jwt/package.json +1 -1
  134. package/vona/src/suite-vendor/a-vona/modules/a-jwt/src/service/jwtClient.ts +5 -0
  135. package/vona/src/suite-vendor/a-vona/modules/a-jwt/src/types/jwt.ts +1 -0
  136. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/package.json +1 -1
  137. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/schema/makeSchemaLikes.ts +6 -3
  138. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/lib/utils.ts +13 -7
  139. package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
  140. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/database.ts +0 -1
  141. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/package.json +9 -1
  142. package/vona/src/suite-vendor/a-vona/modules/a-upload/package.json +1 -1
  143. package/vona/src/suite-vendor/a-vona/modules/a-upload/src/bean/interceptor.upload.ts +39 -7
  144. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  145. package/zova/packages-cli/cli/package.json +3 -3
  146. package/zova/packages-cli/cli-set-front/package.json +9 -9
  147. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +20 -10
  148. package/zova/packages-utils/babel-plugin-zova-bean-module/package.json +2 -2
  149. package/zova/packages-utils/babel-plugin-zova-bean-use/package.json +2 -2
  150. package/zova/packages-utils/babel-plugin-zova-behavior/package.json +2 -2
  151. package/zova/packages-utils/babel-plugin-zova-component/package.json +2 -2
  152. package/zova/packages-utils/zova-jsx/package.json +3 -3
  153. package/zova/packages-utils/zova-vite/package.json +7 -7
  154. package/zova/packages-zova/zova/package.json +3 -3
  155. package/zova/packages-zova/zova-core/package.json +3 -3
  156. package/zova/pnpm-lock.yaml +126 -74
  157. package/zova/src/suite/a-home/modules/home-api/src/api/captcha.ts +3 -1
  158. package/zova/src/suite/a-home/modules/home-api/src/api/home.ts +3 -1
  159. package/zova/src/suite/a-home/modules/home-api/src/api/homeBaseMenu.ts +3 -1
  160. package/zova/src/suite/a-home/modules/home-api/src/api/homeBasePermission.ts +3 -1
  161. package/zova/src/suite/a-home/modules/home-api/src/api/homeUserPassport.ts +22 -20
  162. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/schemas.ts +163 -53
  163. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +2060 -675
  164. package/zova/src/suite/a-home/modules/home-api/src/api/testSsrToolOne.ts +3 -1
  165. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/captcha.ts +3 -1
  166. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/home.ts +3 -1
  167. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/homeBaseMenu.ts +3 -1
  168. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/homeBasePermission.ts +3 -1
  169. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/homeUserPassport.ts +13 -11
  170. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/testSsrToolOne.ts +3 -1
  171. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +54 -16
  172. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +468 -8
  173. package/zova/src/suite/a-training/modules/training-student/src/apiSchema/trainingStudent.ts +3 -1
  174. package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/tableCell.actionUpdate.tsx +1 -1
  175. package/zova/src/suite/cabloy-basic/modules/basic-details/src/component/actionCreate/controller.tsx +1 -1
  176. package/zova/src/suite/cabloy-basic/modules/basic-details/src/service/detail.tsx +53 -1
  177. package/zova/src/suite/cabloy-basic/modules/basic-image/cli/openapi.config.ts +9 -0
  178. package/zova/src/suite/cabloy-basic/modules/basic-image/package.json +60 -0
  179. package/zova/src/suite/cabloy-basic/modules/basic-image/src/.metadata/component/formFieldImage.ts +31 -0
  180. package/zova/src/suite/cabloy-basic/modules/basic-image/src/.metadata/index.ts +191 -0
  181. package/zova/src/suite/cabloy-basic/modules/basic-image/src/.metadata/locales.ts +7 -0
  182. package/zova/src/suite/cabloy-basic/modules/basic-image/src/.metadata/this.ts +2 -0
  183. package/zova/src/suite/cabloy-basic/modules/basic-image/src/api/image.ts +104 -0
  184. package/zova/src/suite/cabloy-basic/modules/basic-image/src/api/openapi/baseURL.ts +5 -0
  185. package/zova/src/suite/cabloy-basic/modules/basic-image/src/api/openapi/index.ts +3 -0
  186. package/zova/src/suite/cabloy-basic/modules/basic-image/src/api/openapi/schemas.ts +262 -0
  187. package/zova/src/suite/cabloy-basic/modules/basic-image/src/api/openapi/types.ts +5159 -0
  188. package/zova/src/suite/cabloy-basic/modules/basic-image/src/apiSchema/image.ts +35 -0
  189. package/zova/src/suite/cabloy-basic/modules/basic-image/src/bean/tableCell.image.tsx +200 -0
  190. package/zova/src/suite/cabloy-basic/modules/basic-image/src/component/formFieldImage/controller.tsx +781 -0
  191. package/zova/src/suite/cabloy-basic/modules/basic-image/src/config/locale/en-us.ts +18 -0
  192. package/zova/src/suite/cabloy-basic/modules/basic-image/src/config/locale/zh-cn.ts +18 -0
  193. package/zova/src/suite/cabloy-basic/modules/basic-image/src/index.ts +4 -0
  194. package/zova/src/suite/cabloy-basic/modules/basic-image/src/lib/index.ts +2 -0
  195. package/zova/src/suite/cabloy-basic/modules/basic-image/src/lib/preview.ts +105 -0
  196. package/zova/src/suite/cabloy-basic/modules/basic-image/src/lib/previewDialog.tsx +190 -0
  197. package/zova/src/suite/cabloy-basic/modules/basic-image/src/types/image.ts +5 -0
  198. package/zova/src/suite/cabloy-basic/modules/basic-image/src/types/index.ts +1 -0
  199. package/zova/src/suite/cabloy-basic/modules/basic-image/tsconfig.build.json +13 -0
  200. package/zova/src/suite/cabloy-basic/modules/basic-image/tsconfig.json +5 -0
  201. package/zova/src/suite/cabloy-basic/package.json +1 -0
  202. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  203. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/image.ts +1 -0
  204. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/index.ts +1 -0
  205. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +5 -5
  206. package/zova/src/suite-vendor/a-zova/package.json +3 -3
  207. package/vona/packages-vona/vona-core/src/lib/utils/sqlite3.ts +0 -50
  208. /package/vona/patches/{zova-core@5.1.75.patch → zova-core@5.1.76.patch} +0 -0
@@ -0,0 +1,35 @@
1
+ import type { IApiSchemaOptions } from 'zova-module-a-api';
2
+
3
+ import { BeanBase } from 'zova';
4
+ import { ApiSchema } from 'zova-module-a-api';
5
+
6
+ import {
7
+ ApiApiImagecreateUploadTokenPath,
8
+ ApiApiImageuploadPath,
9
+ ApiApiImagecreateDirectUploadPath,
10
+ ApiApiImageuploadUrlPath,
11
+ ApiApiImagedeliveryPath,
12
+ } from '../api/image.js';
13
+
14
+ @ApiSchema()
15
+ export class ApiSchemaImage extends BeanBase {
16
+ createUploadToken(options?: IApiSchemaOptions) {
17
+ return this.$sdk.createApiSchemas(ApiApiImagecreateUploadTokenPath, 'post', options);
18
+ }
19
+
20
+ upload(options?: IApiSchemaOptions) {
21
+ return this.$sdk.createApiSchemas(ApiApiImageuploadPath, 'post', options);
22
+ }
23
+
24
+ createDirectUpload(options?: IApiSchemaOptions) {
25
+ return this.$sdk.createApiSchemas(ApiApiImagecreateDirectUploadPath, 'post', options);
26
+ }
27
+
28
+ uploadUrl(options?: IApiSchemaOptions) {
29
+ return this.$sdk.createApiSchemas(ApiApiImageuploadUrlPath, 'post', options);
30
+ }
31
+
32
+ delivery(options?: IApiSchemaOptions) {
33
+ return this.$sdk.createApiSchemas(ApiApiImagedeliveryPath, 'get', options);
34
+ }
35
+ }
@@ -0,0 +1,200 @@
1
+ import type { VNode } from 'vue';
2
+ import type { IResourceTableCellOptionsBase } from 'zova-module-a-openapi';
3
+ import type {
4
+ IJsxRenderContextTableCell,
5
+ ITableCellRender,
6
+ NextTableCellRender,
7
+ } from 'zova-module-a-table';
8
+
9
+ import { classes } from 'typestyle';
10
+ import { BeanBase } from 'zova';
11
+ import { TableCell } from 'zova-module-a-table';
12
+
13
+ import type { IImagePreviewItem } from '../lib/index.js';
14
+
15
+ import {
16
+ buildImagePreviewTitle,
17
+ collectImageRelationPreviewItems,
18
+ collectImageUrlPreviewItems,
19
+ inferImageRelationName,
20
+ openImagePreviewDialog,
21
+ resolveImagePreviewUrl,
22
+ summarizeImageRelationPreviewValue,
23
+ summarizeImageUrlPreviewValue,
24
+ } from '../lib/index.js';
25
+
26
+ declare module 'zova-module-a-openapi' {
27
+ export interface IResourceTableCellRecord {
28
+ 'basic-image:image'?: ITableCellOptionsImage;
29
+ }
30
+ }
31
+
32
+ export interface ITableCellOptionsImage extends IResourceTableCellOptionsBase {
33
+ size?: number;
34
+ fit?: 'cover' | 'contain';
35
+ relationName?: string;
36
+ }
37
+
38
+ interface IImagePreviewSource {
39
+ kind: 'relation' | 'url';
40
+ value: unknown;
41
+ }
42
+
43
+ interface IImagePreviewSummary {
44
+ count: number;
45
+ item?: IImagePreviewItem;
46
+ source: IImagePreviewSource;
47
+ }
48
+
49
+ @TableCell<ITableCellOptionsImage>({
50
+ size: 40,
51
+ fit: 'cover',
52
+ })
53
+ export class TableCellImage extends BeanBase implements ITableCellRender {
54
+ render(
55
+ options: ITableCellOptionsImage,
56
+ renderContext: IJsxRenderContextTableCell,
57
+ next: NextTableCellRender,
58
+ ) {
59
+ const value = next();
60
+ const preview = this._resolvePreviewSummary(options, renderContext, value);
61
+ const item = preview.item;
62
+ const previewUrl = item ? this._resolvePreviewUrl(item.url) : undefined;
63
+ if (!item || !previewUrl) return item?.filename ?? value;
64
+ const previewTitle = this._getPreviewTitle(renderContext, preview);
65
+ const imageNode = this._renderPreviewImage(options, item, previewUrl);
66
+ const contentNode = this._renderPreviewWithBadge(imageNode, preview.count);
67
+ return this._renderPreviewTrigger(contentNode, preview, previewTitle);
68
+ }
69
+
70
+ private _renderPreviewTrigger(
71
+ contentNode: VNode,
72
+ preview: IImagePreviewSummary,
73
+ previewTitle: string,
74
+ ): VNode {
75
+ return (
76
+ <button
77
+ type="button"
78
+ class="group inline-flex min-w-0 cursor-zoom-in items-center gap-2 rounded-box border-0 bg-transparent p-0 text-left align-middle"
79
+ title={previewTitle}
80
+ onClick={event => {
81
+ event.preventDefault();
82
+ event.stopPropagation();
83
+ this._openPreviewDialog(preview, previewTitle);
84
+ }}
85
+ >
86
+ {contentNode}
87
+ </button>
88
+ );
89
+ }
90
+
91
+ private _renderPreviewWithBadge(imageNode: VNode, count: number): VNode {
92
+ if (count <= 1) return imageNode;
93
+ return (
94
+ <div class="flex items-center gap-2 min-w-0">
95
+ {imageNode}
96
+ <span class="badge badge-sm font-medium border-0 whitespace-nowrap px-2 badge-neutral text-neutral-content">
97
+ +{count - 1}
98
+ </span>
99
+ </div>
100
+ );
101
+ }
102
+
103
+ private _renderPreviewImage(
104
+ options: ITableCellOptionsImage,
105
+ item: IImagePreviewItem,
106
+ previewUrl: string,
107
+ ): VNode {
108
+ const size = options.size ?? 40;
109
+ const style = {
110
+ ...(options.style as any),
111
+ width: `${size}px`,
112
+ height: `${size}px`,
113
+ } as any;
114
+ return (
115
+ <div
116
+ class={classes(
117
+ 'overflow-hidden rounded-box bg-base-200 shrink-0 transition duration-150 group-hover:shadow-md group-hover:ring-2 group-hover:ring-primary/30',
118
+ options.class,
119
+ )}
120
+ style={style}
121
+ >
122
+ <img
123
+ class="h-full w-full object-cover"
124
+ style={{ objectFit: options.fit ?? 'cover' }}
125
+ src={previewUrl}
126
+ alt={item.filename ?? 'image'}
127
+ />
128
+ </div>
129
+ );
130
+ }
131
+
132
+ private _openPreviewDialog(preview: IImagePreviewSummary, previewTitle: string) {
133
+ const items = this._resolveDialogItems(preview);
134
+ openImagePreviewDialog({
135
+ appModal: this.$appModal,
136
+ title: previewTitle,
137
+ items,
138
+ baseURL: this.sys.config.api.baseURL,
139
+ });
140
+ }
141
+
142
+ private _getPreviewTitle(
143
+ renderContext: IJsxRenderContextTableCell,
144
+ preview: IImagePreviewSummary,
145
+ ) {
146
+ return buildImagePreviewTitle(this._getPreviewFieldTitle(renderContext), preview.count, () =>
147
+ this.scope.locale.PreviewImage(),
148
+ );
149
+ }
150
+
151
+ private _getPreviewFieldTitle(renderContext: IJsxRenderContextTableCell) {
152
+ return renderContext.$celScope.property?.title ?? renderContext.$celScope.name;
153
+ }
154
+
155
+ private _resolvePreviewSummary(
156
+ options: ITableCellOptionsImage,
157
+ renderContext: IJsxRenderContextTableCell,
158
+ value: unknown,
159
+ ): IImagePreviewSummary {
160
+ const relationPreview = this._getRelationPreviewSummary(options, renderContext);
161
+ if (relationPreview.count) return relationPreview;
162
+ return this._normalizeUrlPreview(value);
163
+ }
164
+
165
+ private _getRelationPreviewSummary(
166
+ options: ITableCellOptionsImage,
167
+ renderContext: IJsxRenderContextTableCell,
168
+ ): IImagePreviewSummary {
169
+ const relationName = inferImageRelationName(renderContext.$celScope.name, options.relationName);
170
+ const relationValue = relationName
171
+ ? renderContext.cellContext.row.original[relationName]
172
+ : undefined;
173
+ const { count, item } = summarizeImageRelationPreviewValue(relationValue);
174
+ return {
175
+ count,
176
+ item,
177
+ source: { kind: 'relation', value: relationValue },
178
+ };
179
+ }
180
+
181
+ private _normalizeUrlPreview(value: unknown): IImagePreviewSummary {
182
+ const { count, item } = summarizeImageUrlPreviewValue(value);
183
+ return {
184
+ count,
185
+ item,
186
+ source: { kind: 'url', value },
187
+ };
188
+ }
189
+
190
+ private _resolveDialogItems(preview: IImagePreviewSummary): IImagePreviewItem[] {
191
+ if (preview.source.kind === 'relation') {
192
+ return collectImageRelationPreviewItems(preview.source.value);
193
+ }
194
+ return collectImageUrlPreviewItems(preview.source.value);
195
+ }
196
+
197
+ private _resolvePreviewUrl(url: string) {
198
+ return resolveImagePreviewUrl(url, this.sys.config.api.baseURL);
199
+ }
200
+ }