cabloy 5.1.157 → 5.1.159

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 (90) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-contract-loop/SKILL.md +24 -7
  3. package/.claude/skills/cabloy-contract-loop/evals/evals.json +12 -0
  4. package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +28 -0
  5. package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +19 -2
  6. package/.claude/skills/cabloy-resource-field-update/SKILL.md +18 -0
  7. package/.claude/skills/cabloy-zova-source-reading/SKILL.md +14 -0
  8. package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +10 -0
  9. package/.github/workflows/docs-pages.yml +18 -2
  10. package/CHANGELOG.md +26 -0
  11. package/CONTRIBUTING.md +84 -0
  12. package/LICENSES.md +5 -0
  13. package/package.json +2 -1
  14. package/repo-docs/.vitepress/config.mjs +34 -4
  15. package/repo-docs/.vitepress/theme/components/GitHubRepositoriesNav.vue +255 -0
  16. package/repo-docs/.vitepress/theme/custom.css +21 -0
  17. package/repo-docs/.vitepress/theme/index.js +7 -1
  18. package/repo-docs/backend/resource-field-update.md +48 -1
  19. package/repo-docs/blogs/index.md +2 -0
  20. package/repo-docs/frontend/form-layout-guide.md +6 -6
  21. package/repo-docs/frontend/page-guide.md +12 -0
  22. package/repo-docs/frontend/page-meta-guide.md +27 -0
  23. package/repo-docs/frontend/ssr-architecture-overview.md +4 -0
  24. package/repo-docs/frontend/ssr-build-deploy-guide.md +1 -1
  25. package/repo-docs/frontend/zova-form-source-reading-map.md +2 -2
  26. package/repo-docs/frontend/zova-form-under-the-hood.md +1 -1
  27. package/repo-docs/frontend/zova-reactivity-under-the-hood.md +65 -9
  28. package/repo-docs/fullstack/contract-loop-playbook.md +2 -0
  29. package/repo-docs/fullstack/ssr-site-and-flavor-setup.md +198 -0
  30. package/repo-docs/fullstack/vona-zova-integration.md +2 -0
  31. package/repo-e2e/docs/playwright.config.ts +37 -0
  32. package/repo-e2e/docs/specs/blogs-index.spec.ts +180 -0
  33. package/repo-e2e/docs/specs/github-repositories-nav.spec.ts +69 -0
  34. package/repo-e2e/docs/test-results/.last-run.json +4 -0
  35. package/repo-e2e/specs/cabloy-basic.spec.ts +136 -2
  36. package/vona/packages-cli/cli/package.json +1 -1
  37. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudBasic/boilerplate/src/entity/{{resourceName}}.tsx_ +1 -1
  38. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/entity/{{resourceName}}.tsx_ +1 -1
  39. package/vona/packages-cli/cli-set-api/package.json +1 -1
  40. package/vona/packages-vona/vona/package.json +1 -1
  41. package/vona/pnpm-lock.yaml +21 -80
  42. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +3 -0
  43. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +3 -0
  44. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productCreate.tsx +2 -0
  45. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productUpdate.tsx +2 -0
  46. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productView.tsx +2 -0
  47. package/vona/src/suite/a-training/modules/training-record/src/dto/recordCreate.tsx +1 -0
  48. package/vona/src/suite/a-training/modules/training-record/src/dto/recordSelectReq.tsx +3 -7
  49. package/vona/src/suite/a-training/modules/training-record/src/dto/recordUpdate.tsx +1 -0
  50. package/vona/src/suite/a-training/modules/training-record/src/dto/recordView.tsx +1 -0
  51. package/vona/src/suite/a-training/modules/training-record/src/entity/record.tsx +8 -0
  52. package/vona/src/suite/a-training/modules/training-record/test/record.test.ts +51 -0
  53. package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +3 -0
  54. package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +3 -0
  55. package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +1 -0
  56. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +1 -0
  57. package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +1 -0
  58. package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +1 -0
  59. package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +10 -1
  60. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +99 -1
  61. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
  62. package/vona/src/suite-vendor/a-cabloy/package.json +2 -2
  63. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  64. package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
  65. package/vona/src/suite-vendor/a-vona/modules/a-web/src/bean/pipe.filter.ts +85 -57
  66. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  67. package/zova/packages-cli/cli/package.json +2 -2
  68. package/zova/packages-cli/cli-set-front/cli/templates/rest/render.ts +2 -0
  69. package/zova/packages-cli/cli-set-front/cli/templates/rest/rest.ts +13 -3
  70. package/zova/packages-cli/cli-set-front/package.json +1 -1
  71. package/zova/packages-zova/zova/package.json +2 -2
  72. package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx +31 -11
  73. package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controller.tsx +3 -0
  74. package/zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx +1 -1
  75. package/zova/src/suite/cabloy-basic/modules/basic-table/src/component/table/render.tsx +68 -8
  76. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  77. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +4 -0
  78. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  79. package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
  80. package/zova/src/suite-vendor/a-zova/modules/a-form/src/lib/formLayout.ts +0 -6
  81. package/zova/src/suite-vendor/a-zova/modules/a-form/test/lib/formLayout.test.ts +16 -9
  82. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  83. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +4 -0
  84. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +13 -2
  85. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/schema.ts +1 -0
  86. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  87. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +50 -0
  88. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx +60 -7
  89. package/zova/src/suite-vendor/a-zova/modules/a-table/src/types/table.ts +6 -4
  90. package/zova/src/suite-vendor/a-zova/package.json +4 -4
@@ -11,7 +11,7 @@ export interface IEntityOptions<%=argv.resourceNameCapitalize%> extends IDecorat
11
11
  @Entity<IEntityOptions<%=argv.resourceNameCapitalize%>>('<%=argv.moduleResourceName%>', {
12
12
  openapi: { title: $locale('<%=argv.resourceNameCapitalize%>') },
13
13
  fields: {
14
- id: $makeMetadata(ZovaRender.order(1, 'core')),
14
+ id: $makeMetadata(ZovaRender.order(1, 'core'), ZovaRender.column({ width: 50, fixed: 'left' })),
15
15
  iid: $makeMetadata(ZovaRender.visible(false)),
16
16
  deleted: $makeMetadata(ZovaRender.visible(false)),
17
17
  createdAt: $makeMetadata(
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-cli-set-api",
3
- "version": "1.1.141",
3
+ "version": "1.1.142",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "vona cli-set-api",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona",
3
- "version": "5.1.91",
3
+ "version": "5.1.92",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "Vona is an intuitive, elegant and powerful Node.js framework for rapidly developing enterprise applications of any size",
6
6
  "keywords": [
@@ -548,6 +548,9 @@ importers:
548
548
  '@tanstack/vue-query':
549
549
  specifier: ^5.101.1
550
550
  version: 5.101.2(vue@3.5.39(typescript@5.9.3))
551
+ '@tanstack/vue-table':
552
+ specifier: ^8.21.3
553
+ version: 8.21.3(vue@3.5.39(typescript@5.9.3))
551
554
  openapi3-ts:
552
555
  specifier: ^4.6.0
553
556
  version: 4.6.0
@@ -615,17 +618,17 @@ importers:
615
618
  specifier: ^5.0.5
616
619
  version: 5.0.5
617
620
  zova-module-rest-resource:
618
- specifier: ^5.1.48
621
+ specifier: ^5.1.49
619
622
  version: 5.1.49
620
623
 
621
624
  .zova-rest/cabloy-basic-web:
622
625
  dependencies:
623
- '@tanstack/query-core':
624
- specifier: ^5.101.1
625
- version: 5.101.2
626
626
  '@tanstack/vue-query':
627
627
  specifier: ^5.101.1
628
628
  version: 5.101.2(vue@3.5.39(typescript@5.9.3))
629
+ '@tanstack/vue-table':
630
+ specifier: ^8.21.3
631
+ version: 8.21.3(vue@3.5.39(typescript@5.9.3))
629
632
  openapi3-ts:
630
633
  specifier: ^4.6.0
631
634
  version: 4.6.0
@@ -639,8 +642,8 @@ importers:
639
642
  specifier: npm:@cabloy/zod@4.3.8
640
643
  version: '@cabloy/zod@4.3.8'
641
644
  zova:
642
- specifier: ^5.1.153
643
- version: 5.1.153(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
645
+ specifier: ^5.1.155
646
+ version: 5.1.155(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
644
647
  zova-jsx:
645
648
  specifier: ^1.1.88
646
649
  version: 1.1.88(typescript@5.9.3)
@@ -657,8 +660,8 @@ importers:
657
660
  specifier: ^5.1.34
658
661
  version: 5.1.34
659
662
  zova-module-a-form:
660
- specifier: ^5.1.48
661
- version: 5.1.48(vue@3.5.39(typescript@5.9.3))
663
+ specifier: ^5.1.50
664
+ version: 5.1.50(vue@3.5.39(typescript@5.9.3))
662
665
  zova-module-a-icon:
663
666
  specifier: ^5.1.27
664
667
  version: 5.1.27
@@ -666,11 +669,11 @@ importers:
666
669
  specifier: ^5.1.31
667
670
  version: 5.1.31
668
671
  zova-module-a-model:
669
- specifier: ^5.1.35
670
- version: 5.1.35(vue@3.5.39(typescript@5.9.3))
672
+ specifier: ^5.1.36
673
+ version: 5.1.36(vue@3.5.39(typescript@5.9.3))
671
674
  zova-module-a-openapi:
672
- specifier: ^5.1.50
673
- version: 5.1.50
675
+ specifier: ^5.1.51
676
+ version: 5.1.51
674
677
  zova-module-a-pay:
675
678
  specifier: ^5.0.7
676
679
  version: 5.0.7
@@ -693,8 +696,8 @@ importers:
693
696
  specifier: ^5.0.5
694
697
  version: 5.0.5
695
698
  zova-module-rest-resource:
696
- specifier: ^5.1.46
697
- version: 5.1.46
699
+ specifier: ^5.1.49
700
+ version: 5.1.49
698
701
 
699
702
  .zova-rest/cabloy-commerce:
700
703
  dependencies:
@@ -1610,7 +1613,7 @@ importers:
1610
1613
  specifier: ^5.0.3
1611
1614
  version: link:modules/a-markdown
1612
1615
  vona-module-a-rbac:
1613
- specifier: ^5.0.2
1616
+ specifier: ^5.0.4
1614
1617
  version: link:modules/a-rbac
1615
1618
  vona-module-a-socket:
1616
1619
  specifier: workspace:^
@@ -8977,9 +8980,6 @@ packages:
8977
8980
  zova-module-a-fetch@5.1.25:
8978
8981
  resolution: {integrity: sha512-kbMB/jIynN0dhivEZLLaY+ic9mU0rZJBeyjXwzAiWuOS330YsxipasxBZhACJD8s29RmLC9EQajI+vVLoBEveQ==}
8979
8982
 
8980
- zova-module-a-form@5.1.48:
8981
- resolution: {integrity: sha512-/YuNFocyP3P6THVrSebi1jRm5+og7YOleBWc7gPzqKUFWTmxN7XBbomRidQWXSRenSd7AWBjNgO3OajhOdswlw==}
8982
-
8983
8983
  zova-module-a-form@5.1.49:
8984
8984
  resolution: {integrity: sha512-p/faHaDELk2xH4TbuXQ9E+vIUZ4yZYS4URFF0HtrJ+bXDBMCJmjOl3H0encedLh9ZS0dGYpvejHPh3nLvw27JA==}
8985
8985
 
@@ -9055,18 +9055,12 @@ packages:
9055
9055
  zova-module-rest-resource@5.1.49:
9056
9056
  resolution: {integrity: sha512-tLf3BLov4GnV1QPivvLro6T2sNdriDZ8vZMsghuUN7dl+PRCG2pI0q9hBCrqe2faRSIcVUXowwnEbEynmaM7Zg==}
9057
9057
 
9058
- zova-suite-a-zova@5.1.152:
9059
- resolution: {integrity: sha512-P/dcMb2fcMpnmDMlrgvpddWUbupnvohD1Jp60VYWoqI0JcWMlYTJvWQWrwszDqiMvMiOTH5mmQBTws0KzbsXpA==}
9060
-
9061
9058
  zova-suite-a-zova@5.1.153:
9062
9059
  resolution: {integrity: sha512-Q7R6GL5O/Tlqk4cnFYumMR2eeCwAqfnTtFrYQuuQMpz7BmYhAPmMmJQWF2reHlRjG6B4dbOPZ5pxl1iWagY7PA==}
9063
9060
 
9064
9061
  zova-suite-a-zova@5.1.154:
9065
9062
  resolution: {integrity: sha512-ii1qFxaBNc4PpNSj+sKgiH0Ryefr4KE0Gb5M8o2Df0hoe8//3uM7QK02GyQDKAK+bu6Q+7mwBZFW8hcD8TrEYw==}
9066
9063
 
9067
- zova@5.1.153:
9068
- resolution: {integrity: sha512-2c+4lhgZgIzM6a066eRU/Ru6CvrSTwRsq1SgsSj+NuLOxUXoj+JPvwUezuRRmBCTukpRMd2nfw8u6vWHzVArTA==}
9069
-
9070
9064
  zova@5.1.154:
9071
9065
  resolution: {integrity: sha512-QF0f+wwLeuf18hsmZj1/3G/AQ9cNQYMKZiCoBBsTDh7oIhaxsmI5wxtjo59HiOEkk5ZmWPHqwjA4iepTLoKqeg==}
9072
9066
 
@@ -15411,14 +15405,6 @@ snapshots:
15411
15405
  - debug
15412
15406
  - supports-color
15413
15407
 
15414
- zova-module-a-form@5.1.48(vue@3.5.39(typescript@5.9.3)):
15415
- dependencies:
15416
- '@tanstack/vue-form': 1.33.2(vue@3.5.39(typescript@5.9.3))
15417
- '@tanstack/vue-store': 0.11.0(vue@3.5.39(typescript@5.9.3))
15418
- transitivePeerDependencies:
15419
- - '@vue/composition-api'
15420
- - vue
15421
-
15422
15408
  zova-module-a-form@5.1.49(vue@3.5.39(typescript@5.9.3)):
15423
15409
  dependencies:
15424
15410
  '@tanstack/vue-form': 1.33.2(vue@3.5.39(typescript@5.9.3))
@@ -15546,40 +15532,6 @@ snapshots:
15546
15532
 
15547
15533
  zova-module-rest-resource@5.1.49: {}
15548
15534
 
15549
- zova-suite-a-zova@5.1.152(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3)):
15550
- dependencies:
15551
- zova-module-a-api: 5.1.22
15552
- zova-module-a-app: 5.1.26
15553
- zova-module-a-bean: 5.1.33
15554
- zova-module-a-behavior: 5.1.26
15555
- zova-module-a-behaviors: 5.1.22
15556
- zova-module-a-boundary: 5.1.22
15557
- zova-module-a-command: 5.1.34
15558
- zova-module-a-fetch: 5.1.25
15559
- zova-module-a-form: 5.1.49(vue@3.5.39(typescript@5.9.3))
15560
- zova-module-a-icon: 5.1.27
15561
- zova-module-a-interceptor: 5.1.31
15562
- zova-module-a-logger: 5.1.28
15563
- zova-module-a-meta: 5.1.22
15564
- zova-module-a-model: 5.1.35(vue@3.5.39(typescript@5.9.3))
15565
- zova-module-a-openapi: 5.1.50
15566
- zova-module-a-router: 5.1.34
15567
- zova-module-a-routerstack: 5.1.27
15568
- zova-module-a-routertabs: 5.1.34
15569
- zova-module-a-ssr: 5.1.38
15570
- zova-module-a-ssrhmr: 5.1.23
15571
- zova-module-a-ssrserver: 5.1.26
15572
- zova-module-a-style: 5.1.35
15573
- zova-module-a-table: 5.1.38(vue@3.5.39(typescript@5.9.3))
15574
- zova-module-a-zod: 5.1.37
15575
- zova-module-a-zova: 5.1.103(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
15576
- transitivePeerDependencies:
15577
- - '@vue/composition-api'
15578
- - debug
15579
- - supports-color
15580
- - typescript
15581
- - vue
15582
-
15583
15535
  zova-suite-a-zova@5.1.153(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3)):
15584
15536
  dependencies:
15585
15537
  zova-module-a-api: 5.1.22
@@ -15590,13 +15542,13 @@ snapshots:
15590
15542
  zova-module-a-boundary: 5.1.22
15591
15543
  zova-module-a-command: 5.1.34
15592
15544
  zova-module-a-fetch: 5.1.25
15593
- zova-module-a-form: 5.1.49(vue@3.5.39(typescript@5.9.3))
15545
+ zova-module-a-form: 5.1.50(vue@3.5.39(typescript@5.9.3))
15594
15546
  zova-module-a-icon: 5.1.27
15595
15547
  zova-module-a-interceptor: 5.1.31
15596
15548
  zova-module-a-logger: 5.1.28
15597
15549
  zova-module-a-meta: 5.1.22
15598
- zova-module-a-model: 5.1.35(vue@3.5.39(typescript@5.9.3))
15599
- zova-module-a-openapi: 5.1.50
15550
+ zova-module-a-model: 5.1.36(vue@3.5.39(typescript@5.9.3))
15551
+ zova-module-a-openapi: 5.1.51
15600
15552
  zova-module-a-router: 5.1.34
15601
15553
  zova-module-a-routerstack: 5.1.27
15602
15554
  zova-module-a-routertabs: 5.1.34
@@ -15648,17 +15600,6 @@ snapshots:
15648
15600
  - typescript
15649
15601
  - vue
15650
15602
 
15651
- zova@5.1.153(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3)):
15652
- dependencies:
15653
- zova-core: 5.1.88(patch_hash=144450bd7a567a6067e5857c0cf4c780981b7e90bc48745c09e1696a9b6f1b97)(typescript@5.9.3)
15654
- zova-suite-a-zova: 5.1.152(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
15655
- transitivePeerDependencies:
15656
- - '@vue/composition-api'
15657
- - debug
15658
- - supports-color
15659
- - typescript
15660
- - vue
15661
-
15662
15603
  zova@5.1.154(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3)):
15663
15604
  dependencies:
15664
15605
  zova-core: 5.1.88(patch_hash=144450bd7a567a6067e5857c0cf4c780981b7e90bc48745c09e1696a9b6f1b97)(typescript@5.9.3)
@@ -1,6 +1,7 @@
1
1
  export default {
2
2
  Available: 'Available',
3
3
  Category: 'Category',
4
+ CreateProduct: 'Create product',
4
5
  Description: 'Description',
5
6
  DescriptionHtml: 'Product description (HTML)',
6
7
  DescriptionMarkdown: 'Product description (Markdown)',
@@ -15,6 +16,8 @@ export default {
15
16
  Unpublished: 'Unpublished',
16
17
  Sku: 'SKU',
17
18
  SkuAttributeName: 'SKU attribute name',
19
+ UpdateProduct: 'Update product',
20
+ ViewProduct: 'Product details',
18
21
  SkuAttributeValue: 'SKU attribute value',
19
22
  SkuAttributes: 'SKU attributes',
20
23
  SkuCode: 'SKU code',
@@ -1,6 +1,7 @@
1
1
  export default {
2
2
  Available: '可用库存',
3
3
  Category: '分类',
4
+ CreateProduct: '新建商品',
4
5
  Description: '描述',
5
6
  DescriptionHtml: '商品描述(HTML)',
6
7
  DescriptionMarkdown: '商品描述(Markdown)',
@@ -15,6 +16,8 @@ export default {
15
16
  Unpublished: '未发布',
16
17
  Sku: 'SKU',
17
18
  SkuAttributeName: 'SKU 属性名',
19
+ UpdateProduct: '编辑商品',
20
+ ViewProduct: '商品详情',
18
21
  SkuAttributeValue: 'SKU 属性值',
19
22
  SkuAttributes: 'SKU 属性',
20
23
  SkuCode: 'SKU 编码',
@@ -11,6 +11,7 @@ import { ModelProduct } from '../model/product.ts';
11
11
  export interface IDtoOptionsProductCreate extends IDecoratorDtoOptions<'productContentForm'> {}
12
12
 
13
13
  @Dto<IDtoOptionsProductCreate>({
14
+ openapi: { title: $locale('CreateProduct') },
14
15
  fields: {
15
16
  productContentForm: $makeMetadata(
16
17
  ZovaRender.fieldSource('productContentForm.descriptionMarkdown'),
@@ -19,6 +20,7 @@ export interface IDtoOptionsProductCreate extends IDecoratorDtoOptions<'productC
19
20
  },
20
21
  blocks: [
21
22
  ZovaRender.block('basic-pageentry:blockPageEntry', {
23
+ pageTitleKey: 'title',
22
24
  blocks: [
23
25
  ZovaRender.block('basic-pageentry:blockForm', {
24
26
  blocks: [
@@ -11,6 +11,7 @@ import { ModelProduct } from '../model/product.ts';
11
11
  export interface IDtoOptionsProductUpdate extends IDecoratorDtoOptions<'productContentForm'> {}
12
12
 
13
13
  @Dto<IDtoOptionsProductUpdate>({
14
+ openapi: { title: $locale('UpdateProduct') },
14
15
  fields: {
15
16
  productContentForm: $makeMetadata(
16
17
  ZovaRender.fieldSource('productContentForm.descriptionMarkdown'),
@@ -19,6 +20,7 @@ export interface IDtoOptionsProductUpdate extends IDecoratorDtoOptions<'productC
19
20
  },
20
21
  blocks: [
21
22
  ZovaRender.block('basic-pageentry:blockPageEntry', {
23
+ pageTitleKey: 'title',
22
24
  blocks: [
23
25
  ZovaRender.block('basic-pageentry:blockForm', {
24
26
  blocks: [
@@ -11,6 +11,7 @@ import { ModelProduct } from '../model/product.ts';
11
11
  export interface IDtoOptionsProductView extends IDecoratorDtoOptions<'productContentForm'> {}
12
12
 
13
13
  @Dto<IDtoOptionsProductView>({
14
+ openapi: { title: $locale('ViewProduct') },
14
15
  fields: {
15
16
  productContentForm: $makeMetadata(
16
17
  ZovaRender.fieldSource('productContentForm.descriptionMarkdown'),
@@ -19,6 +20,7 @@ export interface IDtoOptionsProductView extends IDecoratorDtoOptions<'productCon
19
20
  },
20
21
  blocks: [
21
22
  ZovaRender.block('basic-pageentry:blockPageEntry', {
23
+ pageTitleKey: 'title',
22
24
  blocks: [
23
25
  ZovaRender.block('basic-pageentry:blockForm', {
24
26
  blocks: [
@@ -14,6 +14,7 @@ import { DtoDetailRecordSubjectResItem } from './detailRecordSubjectResItem.tsx'
14
14
  export interface IDtoOptionsRecordCreate extends IDecoratorDtoOptions {}
15
15
 
16
16
  @Dto<IDtoOptionsRecordCreate>({
17
+ openapi: { title: $locale('AddTrainingRecord') },
17
18
  blocks: [
18
19
  ZovaRender.block('basic-pageentry:blockPageEntry', {
19
20
  blocks: [
@@ -1,12 +1,11 @@
1
1
  import type { IDecoratorDtoOptions } from 'vona-module-a-web';
2
2
 
3
- import { $makeSchema, $resourceName, v } from 'vona-module-a-openapiutils';
3
+ import { $makeSchema, v } from 'vona-module-a-openapiutils';
4
4
  import { $Dto } from 'vona-module-a-orm';
5
5
  import { Dto } from 'vona-module-a-web';
6
6
  import z from 'zod';
7
7
  import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
8
8
 
9
- import { $locale } from '../.metadata/locales.ts';
10
9
  import { EntityRecord } from '../entity/record.tsx';
11
10
 
12
11
  export interface IDtoOptionsRecordSelectReq extends IDecoratorDtoOptions {}
@@ -16,12 +15,9 @@ export interface IDtoOptionsRecordSelectReq extends IDecoratorDtoOptions {}
16
15
  fields: {
17
16
  name: $makeSchema(v.optional(), z.string()),
18
17
  studentId: $makeSchema(
19
- v.title($locale('Student')),
20
- ZovaRender.field('basic-resource:formFieldResourcePicker', {
21
- resource: $resourceName('training-student:student'),
22
- }),
18
+ ZovaRender.field('basic-input:formFieldInput'),
23
19
  v.optional(),
24
- z.number(),
20
+ z.string(),
25
21
  ),
26
22
  createdAt: $makeSchema(
27
23
  ZovaRender.field('basic-date:formFieldDateRange'),
@@ -14,6 +14,7 @@ import { DtoDetailRecordSubjectResItem } from './detailRecordSubjectResItem.tsx'
14
14
  export interface IDtoOptionsRecordUpdate extends IDecoratorDtoOptions {}
15
15
 
16
16
  @Dto<IDtoOptionsRecordUpdate>({
17
+ openapi: { title: $locale('EditTrainingRecord') },
17
18
  blocks: [
18
19
  ZovaRender.block('basic-pageentry:blockPageEntry', {
19
20
  blocks: [
@@ -15,6 +15,7 @@ import { DtoDetailRecordSubjectView } from './detailRecordSubjectView.tsx';
15
15
  export interface IDtoOptionsRecordView extends IDecoratorDtoOptions {}
16
16
 
17
17
  @Dto<IDtoOptionsRecordView>({
18
+ openapi: { title: $locale('ViewTrainingRecord') },
18
19
  blocks: [
19
20
  ZovaRender.block('basic-pageentry:blockPageEntry', {
20
21
  blocks: [
@@ -42,7 +42,15 @@ export class EntityRecord extends EntityBase {
42
42
  @Api.field(
43
43
  v.title($locale('Student')),
44
44
  v.required(),
45
+ v.filter({
46
+ table: 'trainingStudent',
47
+ joinType: 'innerJoin',
48
+ joinOn: ['studentId', 'trainingStudent.id'],
49
+ originalName: 'name',
50
+ op: '_includesI_',
51
+ }),
45
52
  ZovaRender.order(2),
53
+ ZovaRender.column({ enableSorting: true }),
46
54
  ZovaRender.field('basic-resource:formFieldResourcePicker', {
47
55
  resource: $resourceName('training-student:student'),
48
56
  }),
@@ -1,14 +1,17 @@
1
1
  import type { DtoRecordCreate, DtoRecordUpdate } from 'vona-module-training-record';
2
2
  import type { DtoStudentCreate } from 'vona-module-training-student';
3
3
 
4
+ import { ZodMetadata } from '@cabloy/zod-openapi';
4
5
  import fse from 'fs-extra';
5
6
  import assert from 'node:assert';
6
7
  import os from 'node:os';
7
8
  import path from 'node:path';
8
9
  import { describe, it } from 'node:test';
9
10
  import { app } from 'vona-mock';
11
+ import { getTargetDecoratorRules } from 'vona-module-a-openapiutils';
10
12
 
11
13
  import { DtoDetailRecordSubjectResItem } from '../src/dto/detailRecordSubjectResItem.tsx';
14
+ import { DtoRecordSelectReq } from '../src/dto/recordSelectReq.tsx';
12
15
  import { DtoRecordSelectResItem } from '../src/dto/recordSelectResItem.tsx';
13
16
  import { DtoRecordView } from '../src/dto/recordView.tsx';
14
17
 
@@ -27,6 +30,38 @@ describe('record.test.ts', () => {
27
30
  assert.ok(subjectComponent?.properties?._lineNumber);
28
31
  assert.equal(subjectComponent.required?.includes('_lineNumber'), false);
29
32
 
33
+ const selectReqRules = getTargetDecoratorRules(DtoRecordSelectReq.prototype);
34
+ const studentIdMetadata = ZodMetadata.getOpenapiMetadata(selectReqRules.studentId!);
35
+ assert.equal(selectReqRules.studentId?.type, 'optional');
36
+ assert.deepEqual(studentIdMetadata?.filter, {
37
+ table: 'trainingStudent',
38
+ joinType: 'innerJoin',
39
+ joinOn: ['studentId', 'trainingStudent.id'],
40
+ originalName: 'name',
41
+ op: '_includesI_',
42
+ });
43
+
44
+ const controller = app.bean.onion.controller
45
+ .getOnionsEnabledCached()
46
+ .find(item => item.beanOptions.beanFullName === 'training-record.controller.record')
47
+ ?.beanOptions.beanClass;
48
+ if (!controller) throw new Error('training-record.controller.record not found');
49
+ const controllerApiJson = await app.bean.openapi.generateJsonOfControllerAction(
50
+ controller,
51
+ 'select',
52
+ 'V31',
53
+ );
54
+ const parameters = controllerApiJson.paths?.['/api/training/record']?.get?.parameters ?? [];
55
+ const studentIdParameter = parameters.find(parameter => parameter.name === 'studentId');
56
+ assert.ok(studentIdParameter);
57
+ assert.equal(studentIdParameter.in, 'query');
58
+ assert.equal(studentIdParameter.required, false);
59
+ assert.deepEqual(studentIdParameter.schema?.type, ['string', 'null']);
60
+ assert.equal(
61
+ parameters.some(parameter => parameter.name === 'studentName'),
62
+ false,
63
+ );
64
+
30
65
  for (const [DtoClass, hasTrainingRecordSubjects] of [
31
66
  [DtoRecordSelectResItem, false],
32
67
  [DtoRecordView, true],
@@ -49,6 +84,7 @@ describe('record.test.ts', () => {
49
84
  'id',
50
85
  'name',
51
86
  ]);
87
+ assert.equal(component.properties.studentId.rest.table.enableSorting, true);
52
88
  }
53
89
  });
54
90
  });
@@ -123,6 +159,21 @@ describe('record.test.ts', () => {
123
159
  assert.equal(String(recordItem!.studentId), String(studentId));
124
160
  assert.equal(String(recordItem!.student?.id), String(studentId));
125
161
  assert.equal(recordItem!.student?.name, studentData.name);
162
+
163
+ const filteredSelectRes: any = await app.bean.executor.performAction(
164
+ 'get',
165
+ '/training/record',
166
+ { query: { studentId: 'tude' } },
167
+ );
168
+ assert.equal(
169
+ filteredSelectRes.list.some((item: any) => String(item.id) === String(recordId)),
170
+ true,
171
+ );
172
+ assert.equal(
173
+ filteredSelectRes.list.every((item: any) => item.student?.name.includes('tude')),
174
+ true,
175
+ );
176
+
126
177
  assert.equal(recordItem!.dossierFiles?.length, 1);
127
178
  assert.equal(recordItem!.dossierFiles?.[0]?.filename, 'attendance.txt');
128
179
 
@@ -5,6 +5,9 @@ export default {
5
5
  StudentContent: 'Student Content',
6
6
  Level: 'Training Stage',
7
7
  BasicInformation: 'Basic Information',
8
+ AddStudent: 'Add Student',
9
+ EditStudent: 'Edit Student',
10
+ ViewStudent: 'View Student',
8
11
  StudentProfile: 'Student Profile',
9
12
  LevelAdvanced: 'Advanced Workshop',
10
13
  LevelBeginner: 'Foundation Track',
@@ -5,6 +5,9 @@ export default {
5
5
  StudentContent: '学生内容',
6
6
  Level: '培训阶段',
7
7
  BasicInformation: '基本信息',
8
+ AddStudent: '添加学生',
9
+ EditStudent: '编辑学生',
10
+ ViewStudent: '查看学生',
8
11
  StudentProfile: '学生资料',
9
12
  LevelAdvanced: '高级研修班',
10
13
  LevelBeginner: '基础班',
@@ -18,6 +18,7 @@ const studentContentField = $makeMetadata(
18
18
  export interface IDtoOptionsStudentCreate extends IDecoratorDtoOptions<'content'> {}
19
19
 
20
20
  @Dto<IDtoOptionsStudentCreate>({
21
+ openapi: { title: $locale('AddStudent') },
21
22
  blocks: [
22
23
  ZovaRender.block('basic-pageentry:blockPageEntry', {
23
24
  blocks: [
@@ -63,6 +63,7 @@ export class DtoStudentSelectResItem extends $Dto.get(() => ModelStudent) {
63
63
  @Api.field(
64
64
  v.title($locale('Operations')),
65
65
  ZovaRender.order(1, 'max'),
66
+ ZovaRender.column({ align: 'center', width: 360, fixed: 'right' }),
66
67
  ZovaRender.cell('basic-table:actionOperationsRow', {
67
68
  actions: [
68
69
  ZovaRender.tableActionRow('training-student:actionSummary', {
@@ -18,6 +18,7 @@ const studentContentField = $makeMetadata(
18
18
  export interface IDtoOptionsStudentUpdate extends IDecoratorDtoOptions<'content'> {}
19
19
 
20
20
  @Dto<IDtoOptionsStudentUpdate>({
21
+ openapi: { title: $locale('EditStudent') },
21
22
  blocks: [
22
23
  ZovaRender.block('basic-pageentry:blockPageEntry', {
23
24
  blocks: [
@@ -22,6 +22,7 @@ const studentContentField = $makeSchema(
22
22
  export interface IDtoOptionsStudentView extends IDecoratorDtoOptions<'_descriptionMarkdown'> {}
23
23
 
24
24
  @Dto<IDtoOptionsStudentView>({
25
+ openapi: { title: $locale('ViewStudent') },
25
26
  blocks: [
26
27
  ZovaRender.block('basic-pageentry:blockPageEntry', {
27
28
  blocks: [
@@ -19,11 +19,12 @@ export interface IEntityOptionsStudent extends IDecoratorEntityOptions {}
19
19
  @Entity<IEntityOptionsStudent>('trainingStudent', {
20
20
  openapi: { title: $locale('Student') },
21
21
  fields: {
22
- id: $makeMetadata(ZovaRender.order(1, 'core')),
22
+ id: $makeMetadata(ZovaRender.order(1, 'core'), ZovaRender.column({ width: 50, fixed: 'left' })),
23
23
  iid: $makeMetadata(ZovaRender.visible(false)),
24
24
  deleted: $makeMetadata(ZovaRender.visible(false)),
25
25
  createdAt: $makeMetadata(
26
26
  ZovaRender.order(-2, 'max'),
27
+ ZovaRender.column({ align: 'center', width: 180, enableSorting: true }),
27
28
  ZovaRender.field('basic-date:formFieldDate'),
28
29
  ZovaRender.cell('basic-date:date'),
29
30
  ),
@@ -40,6 +41,13 @@ export class EntityStudent extends EntityBase {
40
41
  v.required(),
41
42
  v.min(2),
42
43
  ZovaRender.order(1),
44
+ ZovaRender.column({
45
+ align: 'left',
46
+ width: 240,
47
+ fixed: 'left',
48
+ enableSorting: true,
49
+ sortDescFirst: true,
50
+ }),
43
51
  ZovaRender.cell('basic-table:actionView'),
44
52
  )
45
53
  name: string;
@@ -82,6 +90,7 @@ export class EntityStudent extends EntityBase {
82
90
  v.title($locale('Level')),
83
91
  v.required(),
84
92
  ZovaRender.order(5),
93
+ ZovaRender.column({ align: 'center', width: 140, enableSorting: true }),
85
94
  // Tutorial 3 built-in form renderer example. Keep it commented here for side-by-side comparison.
86
95
  // ZovaRender.field('basic-select:formFieldSelect', {
87
96
  // items: studentLevelItems,