@carlonicora/nextjs-jsonapi 1.110.0 → 1.111.0

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 (123) hide show
  1. package/dist/scripts/generate-web-module/__tests__/container.spec.d.ts +2 -0
  2. package/dist/scripts/generate-web-module/__tests__/container.spec.d.ts.map +1 -0
  3. package/dist/scripts/generate-web-module/__tests__/container.spec.js +54 -0
  4. package/dist/scripts/generate-web-module/__tests__/container.spec.js.map +1 -0
  5. package/dist/scripts/generate-web-module/__tests__/data-service.spec.d.ts +2 -0
  6. package/dist/scripts/generate-web-module/__tests__/data-service.spec.d.ts.map +1 -0
  7. package/dist/scripts/generate-web-module/__tests__/data-service.spec.js +19 -0
  8. package/dist/scripts/generate-web-module/__tests__/data-service.spec.js.map +1 -0
  9. package/dist/scripts/generate-web-module/__tests__/editor.spec.d.ts +2 -0
  10. package/dist/scripts/generate-web-module/__tests__/editor.spec.d.ts.map +1 -0
  11. package/dist/scripts/generate-web-module/__tests__/editor.spec.js +35 -0
  12. package/dist/scripts/generate-web-module/__tests__/editor.spec.js.map +1 -0
  13. package/dist/scripts/generate-web-module/__tests__/fixtures.d.ts +4 -0
  14. package/dist/scripts/generate-web-module/__tests__/fixtures.d.ts.map +1 -0
  15. package/dist/scripts/generate-web-module/__tests__/fixtures.js +45 -0
  16. package/dist/scripts/generate-web-module/__tests__/fixtures.js.map +1 -0
  17. package/dist/scripts/generate-web-module/__tests__/model-interface.spec.d.ts +2 -0
  18. package/dist/scripts/generate-web-module/__tests__/model-interface.spec.d.ts.map +1 -0
  19. package/dist/scripts/generate-web-module/__tests__/model-interface.spec.js +74 -0
  20. package/dist/scripts/generate-web-module/__tests__/model-interface.spec.js.map +1 -0
  21. package/dist/scripts/generate-web-module/__tests__/plumbing.spec.d.ts +2 -0
  22. package/dist/scripts/generate-web-module/__tests__/plumbing.spec.d.ts.map +1 -0
  23. package/dist/scripts/generate-web-module/__tests__/plumbing.spec.js +21 -0
  24. package/dist/scripts/generate-web-module/__tests__/plumbing.spec.js.map +1 -0
  25. package/dist/scripts/generate-web-module/__tests__/selector.spec.d.ts +2 -0
  26. package/dist/scripts/generate-web-module/__tests__/selector.spec.d.ts.map +1 -0
  27. package/dist/scripts/generate-web-module/__tests__/selector.spec.js +25 -0
  28. package/dist/scripts/generate-web-module/__tests__/selector.spec.js.map +1 -0
  29. package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.d.ts +2 -0
  30. package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.d.ts.map +1 -0
  31. package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.js +55 -0
  32. package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.js.map +1 -0
  33. package/dist/scripts/generate-web-module/generator.d.ts.map +1 -1
  34. package/dist/scripts/generate-web-module/generator.js +14 -11
  35. package/dist/scripts/generate-web-module/generator.js.map +1 -1
  36. package/dist/scripts/generate-web-module/templates/components/container.template.d.ts +5 -1
  37. package/dist/scripts/generate-web-module/templates/components/container.template.d.ts.map +1 -1
  38. package/dist/scripts/generate-web-module/templates/components/container.template.js +43 -63
  39. package/dist/scripts/generate-web-module/templates/components/container.template.js.map +1 -1
  40. package/dist/scripts/generate-web-module/templates/components/content.template.d.ts +7 -4
  41. package/dist/scripts/generate-web-module/templates/components/content.template.d.ts.map +1 -1
  42. package/dist/scripts/generate-web-module/templates/components/content.template.js +103 -14
  43. package/dist/scripts/generate-web-module/templates/components/content.template.js.map +1 -1
  44. package/dist/scripts/generate-web-module/templates/components/editor.template.d.ts +1 -1
  45. package/dist/scripts/generate-web-module/templates/components/editor.template.js +139 -150
  46. package/dist/scripts/generate-web-module/templates/components/editor.template.js.map +1 -1
  47. package/dist/scripts/generate-web-module/templates/components/index.d.ts +0 -1
  48. package/dist/scripts/generate-web-module/templates/components/index.d.ts.map +1 -1
  49. package/dist/scripts/generate-web-module/templates/components/index.js +1 -3
  50. package/dist/scripts/generate-web-module/templates/components/index.js.map +1 -1
  51. package/dist/scripts/generate-web-module/templates/components/list-container.template.js +2 -2
  52. package/dist/scripts/generate-web-module/templates/components/list.template.d.ts.map +1 -1
  53. package/dist/scripts/generate-web-module/templates/components/list.template.js +6 -1
  54. package/dist/scripts/generate-web-module/templates/components/list.template.js.map +1 -1
  55. package/dist/scripts/generate-web-module/templates/components/selector.template.d.ts.map +1 -1
  56. package/dist/scripts/generate-web-module/templates/components/selector.template.js +48 -52
  57. package/dist/scripts/generate-web-module/templates/components/selector.template.js.map +1 -1
  58. package/dist/scripts/generate-web-module/templates/data/interface.template.d.ts.map +1 -1
  59. package/dist/scripts/generate-web-module/templates/data/interface.template.js +38 -11
  60. package/dist/scripts/generate-web-module/templates/data/interface.template.js.map +1 -1
  61. package/dist/scripts/generate-web-module/templates/data/model.template.d.ts.map +1 -1
  62. package/dist/scripts/generate-web-module/templates/data/model.template.js +83 -26
  63. package/dist/scripts/generate-web-module/templates/data/model.template.js.map +1 -1
  64. package/dist/scripts/generate-web-module/templates/data/service.template.d.ts.map +1 -1
  65. package/dist/scripts/generate-web-module/templates/data/service.template.js +21 -1
  66. package/dist/scripts/generate-web-module/templates/data/service.template.js.map +1 -1
  67. package/dist/scripts/generate-web-module/templates/index.d.ts +1 -1
  68. package/dist/scripts/generate-web-module/templates/index.d.ts.map +1 -1
  69. package/dist/scripts/generate-web-module/templates/index.js +1 -2
  70. package/dist/scripts/generate-web-module/templates/index.js.map +1 -1
  71. package/dist/scripts/generate-web-module/templates/module.template.d.ts.map +1 -1
  72. package/dist/scripts/generate-web-module/templates/module.template.js +11 -3
  73. package/dist/scripts/generate-web-module/templates/module.template.js.map +1 -1
  74. package/dist/scripts/generate-web-module/templates/table-hook.template.js +31 -1
  75. package/dist/scripts/generate-web-module/templates/table-hook.template.js.map +1 -1
  76. package/dist/scripts/generate-web-module/transformers/import-resolver.d.ts +0 -1
  77. package/dist/scripts/generate-web-module/transformers/import-resolver.d.ts.map +1 -1
  78. package/dist/scripts/generate-web-module/transformers/import-resolver.js +0 -1
  79. package/dist/scripts/generate-web-module/transformers/import-resolver.js.map +1 -1
  80. package/dist/scripts/generate-web-module/transformers/relationship-key.d.ts +5 -0
  81. package/dist/scripts/generate-web-module/transformers/relationship-key.d.ts.map +1 -0
  82. package/dist/scripts/generate-web-module/transformers/relationship-key.js +21 -0
  83. package/dist/scripts/generate-web-module/transformers/relationship-key.js.map +1 -0
  84. package/dist/scripts/generate-web-module/transformers/relationship-resolver.d.ts.map +1 -1
  85. package/dist/scripts/generate-web-module/transformers/relationship-resolver.js +2 -0
  86. package/dist/scripts/generate-web-module/transformers/relationship-resolver.js.map +1 -1
  87. package/dist/scripts/generate-web-module/types/json-schema.interface.d.ts +21 -0
  88. package/dist/scripts/generate-web-module/types/json-schema.interface.d.ts.map +1 -1
  89. package/dist/scripts/generate-web-module/types/template-data.interface.d.ts +17 -0
  90. package/dist/scripts/generate-web-module/types/template-data.interface.d.ts.map +1 -1
  91. package/package.json +1 -1
  92. package/scripts/generate-web-module/__tests__/container.spec.ts +58 -0
  93. package/scripts/generate-web-module/__tests__/data-service.spec.ts +18 -0
  94. package/scripts/generate-web-module/__tests__/editor.spec.ts +36 -0
  95. package/scripts/generate-web-module/__tests__/fixtures.ts +43 -0
  96. package/scripts/generate-web-module/__tests__/model-interface.spec.ts +77 -0
  97. package/scripts/generate-web-module/__tests__/plumbing.spec.ts +21 -0
  98. package/scripts/generate-web-module/__tests__/selector.spec.ts +24 -0
  99. package/scripts/generate-web-module/__tests__/table-module-list.spec.ts +59 -0
  100. package/scripts/generate-web-module/generator.ts +14 -13
  101. package/scripts/generate-web-module/templates/components/container.template.ts +51 -66
  102. package/scripts/generate-web-module/templates/components/content.template.ts +107 -15
  103. package/scripts/generate-web-module/templates/components/editor.template.ts +140 -152
  104. package/scripts/generate-web-module/templates/components/index.ts +0 -1
  105. package/scripts/generate-web-module/templates/components/list-container.template.ts +2 -2
  106. package/scripts/generate-web-module/templates/components/list.template.ts +6 -1
  107. package/scripts/generate-web-module/templates/components/selector.template.ts +48 -52
  108. package/scripts/generate-web-module/templates/data/interface.template.ts +44 -12
  109. package/scripts/generate-web-module/templates/data/model.template.ts +88 -28
  110. package/scripts/generate-web-module/templates/data/service.template.ts +23 -1
  111. package/scripts/generate-web-module/templates/index.ts +0 -1
  112. package/scripts/generate-web-module/templates/module.template.ts +13 -3
  113. package/scripts/generate-web-module/templates/table-hook.template.ts +31 -2
  114. package/scripts/generate-web-module/transformers/import-resolver.ts +0 -2
  115. package/scripts/generate-web-module/transformers/relationship-key.ts +18 -0
  116. package/scripts/generate-web-module/transformers/relationship-resolver.ts +2 -0
  117. package/scripts/generate-web-module/types/json-schema.interface.ts +9 -0
  118. package/scripts/generate-web-module/types/template-data.interface.ts +7 -0
  119. package/dist/scripts/generate-web-module/templates/components/details.template.d.ts +0 -14
  120. package/dist/scripts/generate-web-module/templates/components/details.template.d.ts.map +0 -1
  121. package/dist/scripts/generate-web-module/templates/components/details.template.js +0 -112
  122. package/dist/scripts/generate-web-module/templates/components/details.template.js.map +0 -1
  123. package/scripts/generate-web-module/templates/components/details.template.ts +0 -116
@@ -2,10 +2,15 @@
2
2
  /**
3
3
  * Container Template
4
4
  *
5
- * Generates {Module}Container.tsx component for displaying item detail page.
5
+ * Generates {Module}Container.tsx component for the item detail page.
6
+ *
7
+ * Emits a RoundPageContainer driven by a `tabs` array: a default "Details" tab
8
+ * rendering {Module}Content, one tab per configured relation list, and an
9
+ * optional "Activity" tab. The default export gates on delete permission.
6
10
  */
7
11
  Object.defineProperty(exports, "__esModule", { value: true });
8
12
  exports.generateContainerTemplate = generateContainerTemplate;
13
+ const name_transformer_1 = require("../../transformers/name-transformer");
9
14
  /**
10
15
  * Generate the container component file content
11
16
  *
@@ -13,80 +18,55 @@ exports.generateContainerTemplate = generateContainerTemplate;
13
18
  * @returns Generated file content
14
19
  */
15
20
  function generateContainerTemplate(data) {
16
- const { names, extendsContent } = data;
17
- // Content-extending modules get full tabs with relevant content/users
18
- if (extendsContent) {
19
- return generateContentContainerTemplate(data);
21
+ const { names, containerTabs } = data;
22
+ const camel = names.camelCase;
23
+ const relationImports = [];
24
+ const relationTabs = [];
25
+ for (const rel of containerTabs.relations) {
26
+ const relKebab = (0, name_transformer_1.toKebabCase)(rel.module);
27
+ const relPluralCamel = (0, name_transformer_1.pluralize)((0, name_transformer_1.toCamelCase)(rel.module));
28
+ relationImports.push(`import ${rel.module}List from "@/features/${rel.directory}/${relKebab}/components/lists/${rel.module}List";`);
29
+ relationTabs.push(` {\n key: Modules.${rel.module},\n label: t(\`entities.${relPluralCamel.toLowerCase()}\`, { count: 2 }),\n content: <${rel.module}List ${rel.listProp}={${camel}} />,\n },`);
20
30
  }
21
- // Non-content modules get simpler container
22
- return generateSimpleContainerTemplate(data);
23
- }
24
- /**
25
- * Generate container for Content-extending modules
26
- */
27
- function generateContentContainerTemplate(data) {
28
- const { names } = data;
31
+ const tabEntries = [
32
+ ` {\n label: "Details",\n content: <${names.pascalCase}Content ${camel}={${camel}} />,\n },`,
33
+ ...relationTabs,
34
+ ];
35
+ if (containerTabs.activity) {
36
+ tabEntries.push(` {\n label: "Activity",\n content: <ActivityFeed module={Modules.${names.pascalCase}} entityId={${camel}.id} />,\n },`);
37
+ }
38
+ const activityImport = containerTabs.activity
39
+ ? `import ActivityFeed from "@/features/activity/activity-feed/components/ActivityFeed";\n`
40
+ : "";
41
+ const relationImportBlock = relationImports.length ? `${relationImports.join("\n")}\n` : "";
29
42
  return `"use client";
30
43
 
31
- import ${names.pascalCase}Content from "@/features/${data.importTargetDir}/${names.kebabCase}/components/details/${names.pascalCase}Content";
32
- import ${names.pascalCase}Details from "@/features/${data.importTargetDir}/${names.kebabCase}/components/details/${names.pascalCase}Details";
44
+ ${activityImport}${relationImportBlock}import { ${names.pascalCase}Content } from "@/features/${data.importTargetDir}/${names.kebabCase}/components/details/${names.pascalCase}Content";
33
45
  import { use${names.pascalCase}Context } from "@/features/${data.importTargetDir}/${names.kebabCase}/contexts/${names.pascalCase}Context";
34
46
  import { ${names.pascalCase}Interface } from "@/features/${data.importTargetDir}/${names.kebabCase}/data/${names.pascalCase}Interface";
35
- import { RoundPageContainer } from "@carlonicora/nextjs-jsonapi/components";
36
- import { Modules } from "@carlonicora/nextjs-jsonapi/core";
47
+ import { RoundPageContainer, Tab } from "@carlonicora/nextjs-jsonapi/components";
48
+ import { useCurrentUserContext } from "@carlonicora/nextjs-jsonapi/contexts";
49
+ import { Action, Modules } from "@carlonicora/nextjs-jsonapi/core";
50
+ import { useTranslations } from "next-intl";
37
51
 
38
- type ${names.pascalCase}ContainerProps = {
39
- ${names.camelCase}: ${names.pascalCase}Interface;
40
- };
52
+ type ${names.pascalCase}ContainerProps = { ${camel}: ${names.pascalCase}Interface };
41
53
 
42
- function ${names.pascalCase}ContainerInternal({ ${names.camelCase} }: ${names.pascalCase}ContainerProps) {
43
- return (
44
- <RoundPageContainer module={Modules.${names.pascalCase}} details={<${names.pascalCase}Details />}>
45
- <${names.pascalCase}Content />
46
- </RoundPageContainer>
47
- );
48
- }
54
+ function ${names.pascalCase}ContainerInternal({ ${camel} }: ${names.pascalCase}ContainerProps) {
55
+ const t = useTranslations();
49
56
 
50
- export default function ${names.pascalCase}Container() {
51
- const { ${names.camelCase} } = use${names.pascalCase}Context();
52
- if (!${names.camelCase}) return null;
57
+ const tabs: Tab[] = [
58
+ ${tabEntries.join("\n")}
59
+ ];
53
60
 
54
- return <${names.pascalCase}ContainerInternal ${names.camelCase}={${names.camelCase}} />;
55
- }
56
- `;
57
- }
58
- /**
59
- * Generate container for non-Content modules
60
- */
61
- function generateSimpleContainerTemplate(data) {
62
- const { names } = data;
63
- return `"use client";
64
-
65
- import ${names.pascalCase}Details from "@/features/${data.importTargetDir}/${names.kebabCase}/components/details/${names.pascalCase}Details";
66
- import { use${names.pascalCase}Context } from "@/features/${data.importTargetDir}/${names.kebabCase}/contexts/${names.pascalCase}Context";
67
- import { ${names.pascalCase}Interface } from "@/features/${data.importTargetDir}/${names.kebabCase}/data/${names.pascalCase}Interface";
68
- import { RoundPageContainer } from "@carlonicora/nextjs-jsonapi/components";
69
- import { Modules } from "@carlonicora/nextjs-jsonapi/core";
70
-
71
- type ${names.pascalCase}ContainerProps = {
72
- ${names.camelCase}: ${names.pascalCase}Interface;
73
- };
74
-
75
- function ${names.pascalCase}ContainerInternal({ ${names.camelCase} }: ${names.pascalCase}ContainerProps) {
76
- return (
77
- <RoundPageContainer module={Modules.${names.pascalCase}} details={<${names.pascalCase}Details />}>
78
- <div className="flex w-full flex-col gap-y-4">
79
- {/* Add custom content sections here */}
80
- </div>
81
- </RoundPageContainer>
82
- );
61
+ return <RoundPageContainer module={Modules.${names.pascalCase}} id={${camel}.id} tabs={tabs} />;
83
62
  }
84
63
 
85
64
  export default function ${names.pascalCase}Container() {
86
- const { ${names.camelCase} } = use${names.pascalCase}Context();
87
- if (!${names.camelCase}) return null;
88
-
89
- return <${names.pascalCase}ContainerInternal ${names.camelCase}={${names.camelCase}} />;
65
+ const { hasPermissionToModule } = useCurrentUserContext();
66
+ const { ${camel} } = use${names.pascalCase}Context();
67
+ if (!${camel}) return null;
68
+ if (!hasPermissionToModule({ module: Modules.${names.pascalCase}, action: Action.Delete, data: ${camel} })) return null;
69
+ return <${names.pascalCase}ContainerInternal ${camel}={${camel}} />;
90
70
  }
91
71
  `;
92
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"container.template.js","sourceRoot":"","sources":["../../../../../scripts/generate-web-module/templates/components/container.template.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAUH,8DAUC;AAhBD;;;;;GAKG;AACH,SAAgB,yBAAyB,CAAC,IAA0B;IAClE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAEvC,sEAAsE;IACtE,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,gCAAgC,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAED,4CAA4C;IAC5C,OAAO,+BAA+B,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,SAAS,gCAAgC,CAAC,IAA0B;IAClE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAEvB,OAAO;;SAEA,KAAK,CAAC,UAAU,4BAA4B,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,uBAAuB,KAAK,CAAC,UAAU;SAC1H,KAAK,CAAC,UAAU,4BAA4B,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,uBAAuB,KAAK,CAAC,UAAU;cACrH,KAAK,CAAC,UAAU,8BAA8B,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,aAAa,KAAK,CAAC,UAAU;WACrH,KAAK,CAAC,UAAU,gCAAgC,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,SAAS,KAAK,CAAC,UAAU;;;;OAIpH,KAAK,CAAC,UAAU;IACnB,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,UAAU;;;WAG7B,KAAK,CAAC,UAAU,uBAAuB,KAAK,CAAC,SAAS,OAAO,KAAK,CAAC,UAAU;;0CAE9C,KAAK,CAAC,UAAU,eAAe,KAAK,CAAC,UAAU;SAChF,KAAK,CAAC,UAAU;;;;;0BAKC,KAAK,CAAC,UAAU;YAC9B,KAAK,CAAC,SAAS,WAAW,KAAK,CAAC,UAAU;SAC7C,KAAK,CAAC,SAAS;;YAEZ,KAAK,CAAC,UAAU,qBAAqB,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;;CAEnF,CAAC;AACF,CAAC;AAED;;GAEG;AACH,SAAS,+BAA+B,CAAC,IAA0B;IACjE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAEvB,OAAO;;SAEA,KAAK,CAAC,UAAU,4BAA4B,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,uBAAuB,KAAK,CAAC,UAAU;cACrH,KAAK,CAAC,UAAU,8BAA8B,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,aAAa,KAAK,CAAC,UAAU;WACrH,KAAK,CAAC,UAAU,gCAAgC,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,SAAS,KAAK,CAAC,UAAU;;;;OAIpH,KAAK,CAAC,UAAU;IACnB,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,UAAU;;;WAG7B,KAAK,CAAC,UAAU,uBAAuB,KAAK,CAAC,SAAS,OAAO,KAAK,CAAC,UAAU;;0CAE9C,KAAK,CAAC,UAAU,eAAe,KAAK,CAAC,UAAU;;;;;;;;0BAQ/D,KAAK,CAAC,UAAU;YAC9B,KAAK,CAAC,SAAS,WAAW,KAAK,CAAC,UAAU;SAC7C,KAAK,CAAC,SAAS;;YAEZ,KAAK,CAAC,UAAU,qBAAqB,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;;CAEnF,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"container.template.js","sourceRoot":"","sources":["../../../../../scripts/generate-web-module/templates/components/container.template.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAWH,8DA+DC;AAxED,0EAA0F;AAG1F;;;;;GAKG;AACH,SAAgB,yBAAyB,CAAC,IAA0B;IAClE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC;IAE9B,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,SAAS,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,IAAA,8BAAW,EAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,cAAc,GAAG,IAAA,4BAAS,EAAC,IAAA,8BAAW,EAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,eAAe,CAAC,IAAI,CAClB,UAAU,GAAG,CAAC,MAAM,yBAAyB,GAAG,CAAC,SAAS,IAAI,QAAQ,qBAAqB,GAAG,CAAC,MAAM,QAAQ,CAC9G,CAAC;QACF,YAAY,CAAC,IAAI,CACf,6BAA6B,GAAG,CAAC,MAAM,gCAAgC,cAAc,CAAC,WAAW,EAAE,uCAAuC,GAAG,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAQ,KAAK,KAAK,eAAe,CAClM,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAa;QAC3B,mDAAmD,KAAK,CAAC,UAAU,WAAW,KAAK,KAAK,KAAK,eAAe;QAC5G,GAAG,YAAY;KAChB,CAAC;IAEF,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CACb,iFAAiF,KAAK,CAAC,UAAU,eAAe,KAAK,kBAAkB,CACxI,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ;QAC3C,CAAC,CAAC,yFAAyF;QAC3F,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5F,OAAO;;EAEP,cAAc,GAAG,mBAAmB,YAAY,KAAK,CAAC,UAAU,8BAA8B,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,uBAAuB,KAAK,CAAC,UAAU;cAChK,KAAK,CAAC,UAAU,8BAA8B,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,aAAa,KAAK,CAAC,UAAU;WACrH,KAAK,CAAC,UAAU,gCAAgC,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,SAAS,KAAK,CAAC,UAAU;;;;;;OAMpH,KAAK,CAAC,UAAU,sBAAsB,KAAK,KAAK,KAAK,CAAC,UAAU;;WAE5D,KAAK,CAAC,UAAU,uBAAuB,KAAK,OAAO,KAAK,CAAC,UAAU;;;;EAI5E,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;;;+CAGwB,KAAK,CAAC,UAAU,SAAS,KAAK;;;0BAGnD,KAAK,CAAC,UAAU;;YAE9B,KAAK,WAAW,KAAK,CAAC,UAAU;SACnC,KAAK;iDACmC,KAAK,CAAC,UAAU,kCAAkC,KAAK;YAC5F,KAAK,CAAC,UAAU,qBAAqB,KAAK,KAAK,KAAK;;CAE/D,CAAC;AACF,CAAC"}
@@ -1,15 +1,18 @@
1
1
  /**
2
2
  * Content Template
3
3
  *
4
- * Generates {Module}Content.tsx component for displaying BlockNote content.
5
- * Only generated for Content-extending modules.
4
+ * Generates {Module}Content.tsx the prop-driven body rendered inside the
5
+ * container's "Details" tab. Always emitted (returns a string):
6
+ * - Content-extending modules render the BlockNote content.
7
+ * - Other modules render an AttributeElement layout of their fields and
8
+ * relationships.
6
9
  */
7
10
  import { FrontendTemplateData } from "../../types/template-data.interface";
8
11
  /**
9
12
  * Generate the content display component file content
10
13
  *
11
14
  * @param data - Frontend template data
12
- * @returns Generated file content or null if not Content-extending
15
+ * @returns Generated file content (always a string)
13
16
  */
14
- export declare function generateContentTemplate(data: FrontendTemplateData): string | null;
17
+ export declare function generateContentTemplate(data: FrontendTemplateData): string;
15
18
  //# sourceMappingURL=content.template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content.template.d.ts","sourceRoot":"","sources":["../../../../../scripts/generate-web-module/templates/components/content.template.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,GAAG,IAAI,CAwBjF"}
1
+ {"version":3,"file":"content.template.d.ts","sourceRoot":"","sources":["../../../../../scripts/generate-web-module/templates/components/content.template.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAmD1E"}
@@ -2,38 +2,127 @@
2
2
  /**
3
3
  * Content Template
4
4
  *
5
- * Generates {Module}Content.tsx component for displaying BlockNote content.
6
- * Only generated for Content-extending modules.
5
+ * Generates {Module}Content.tsx the prop-driven body rendered inside the
6
+ * container's "Details" tab. Always emitted (returns a string):
7
+ * - Content-extending modules render the BlockNote content.
8
+ * - Other modules render an AttributeElement layout of their fields and
9
+ * relationships.
7
10
  */
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.generateContentTemplate = generateContentTemplate;
13
+ const name_transformer_1 = require("../../transformers/name-transformer");
10
14
  /**
11
15
  * Generate the content display component file content
12
16
  *
13
17
  * @param data - Frontend template data
14
- * @returns Generated file content or null if not Content-extending
18
+ * @returns Generated file content (always a string)
15
19
  */
16
20
  function generateContentTemplate(data) {
17
21
  const { names, extendsContent } = data;
18
- // Only generate for Content-extending modules
19
- if (!extendsContent) {
20
- return null;
21
- }
22
- return `"use client";
22
+ const camel = names.camelCase;
23
+ // Content-extending modules render their BlockNote body, prop-driven.
24
+ if (extendsContent) {
25
+ return `"use client";
23
26
 
24
- import { use${names.pascalCase}Context } from "@/features/${data.importTargetDir}/${names.kebabCase}/contexts/${names.pascalCase}Context";
25
- import { BlockNoteEditorContainer } from "@carlonicora/nextjs-jsonapi/components";
26
- import { Card } from "@carlonicora/nextjs-jsonapi/components";
27
+ import { ${names.pascalCase}Interface } from "@/features/${data.importTargetDir}/${names.kebabCase}/data/${names.pascalCase}Interface";
28
+ import { BlockNoteEditorContainer, Card } from "@carlonicora/nextjs-jsonapi/components";
27
29
 
28
- export default function ${names.pascalCase}Content() {
29
- const { ${names.camelCase} } = use${names.pascalCase}Context();
30
+ type ${names.pascalCase}ContentProps = { ${camel}: ${names.pascalCase}Interface };
30
31
 
32
+ export function ${names.pascalCase}Content({ ${camel} }: ${names.pascalCase}ContentProps) {
31
33
  return (
32
34
  <Card className="flex w-full flex-col p-4">
33
- <BlockNoteEditorContainer id={${names.camelCase}.id} type="${names.camelCase}" initialContent={${names.camelCase}.content} />
35
+ <BlockNoteEditorContainer id={${camel}.id} type="${camel}" initialContent={${camel}.content} />
34
36
  </Card>
35
37
  );
36
38
  }
37
39
  `;
40
+ }
41
+ // Non-content modules render an AttributeElement layout of their fields.
42
+ const attributeElements = generateAttributeElements(data);
43
+ return `"use client";
44
+
45
+ import { ${names.pascalCase}Interface } from "@/features/${data.importTargetDir}/${names.kebabCase}/data/${names.pascalCase}Interface";
46
+ import { AttributeElement } from "@carlonicora/nextjs-jsonapi/components";
47
+ import { useTranslations } from "next-intl";
48
+
49
+ type ${names.pascalCase}ContentProps = { ${camel}: ${names.pascalCase}Interface };
50
+
51
+ export function ${names.pascalCase}Content({ ${camel} }: ${names.pascalCase}ContentProps) {
52
+ const t = useTranslations();
53
+
54
+ return (
55
+ <div className="flex flex-col gap-y-8">
56
+ <div className="flex flex-col gap-y-3">
57
+ <h3 className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
58
+ {t(\`features.${names.camelCase}.sections.details\`)}
59
+ </h3>
60
+ <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
61
+ ${attributeElements}
62
+ </div>
63
+ </div>
64
+ </div>
65
+ );
66
+ }
67
+ `;
68
+ }
69
+ /**
70
+ * Generate attribute elements for display fields and relationships.
71
+ *
72
+ * Ported from the (removed) details template, but accessing the entity via the
73
+ * `camelCase` prop instead of context.
74
+ */
75
+ function generateAttributeElements(data) {
76
+ const { names, fields, relationships } = data;
77
+ const camel = names.camelCase;
78
+ const elements = [];
79
+ // Add custom fields (excluding name, tldr, abstract, content which are handled elsewhere)
80
+ const displayableFields = fields.filter((f) => !["name", "tldr", "abstract", "content", "id"].includes(f.name));
81
+ displayableFields.forEach((field) => {
82
+ if (field.type === "string") {
83
+ elements.push(` <AttributeElement
84
+ title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
85
+ value={${camel}.${field.name}}
86
+ />`);
87
+ }
88
+ else if (field.type === "boolean") {
89
+ elements.push(` <AttributeElement
90
+ title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
91
+ value={${camel}.${field.name} ? t(\`generic.yes\`) : t(\`generic.no\`)}
92
+ />`);
93
+ }
94
+ else if (field.type === "number") {
95
+ elements.push(` <AttributeElement
96
+ title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
97
+ value={${camel}.${field.name}?.toString()}
98
+ />`);
99
+ }
100
+ });
101
+ // Add relationship displays (basic - can be enhanced manually)
102
+ relationships
103
+ .filter((rel) => rel.variant !== "Author") // Skip author, usually shown in title
104
+ .forEach((rel) => {
105
+ const displayProp = rel.targetHasName ? "name" : "id";
106
+ if (rel.single) {
107
+ const propName = (0, name_transformer_1.toCamelCase)(rel.alias || rel.variant || rel.name);
108
+ elements.push(` {${camel}.${propName} && (
109
+ <AttributeElement
110
+ title={t(\`generic.relationships.${propName}.label\`)}
111
+ value={${camel}.${propName}.${displayProp}}
112
+ />
113
+ )}`);
114
+ }
115
+ else {
116
+ const effectiveMany = rel.alias || rel.name;
117
+ const propName = (0, name_transformer_1.pluralize)((0, name_transformer_1.toCamelCase)(effectiveMany));
118
+ elements.push(` {${camel}.${propName} && ${camel}.${propName}.length > 0 && (
119
+ <AttributeElement
120
+ title={t(\`entities.${(0, name_transformer_1.pluralize)(rel.name.toLowerCase())}\`, { count: 2 })}
121
+ value={${camel}.${propName}.map((item) => item.${displayProp}).join(", ")}
122
+ />
123
+ )}`);
124
+ }
125
+ });
126
+ return elements.join("\n");
38
127
  }
39
128
  //# sourceMappingURL=content.template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"content.template.js","sourceRoot":"","sources":["../../../../../scripts/generate-web-module/templates/components/content.template.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAUH,0DAwBC;AA9BD;;;;;GAKG;AACH,SAAgB,uBAAuB,CAAC,IAA0B;IAChE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAEvC,8CAA8C;IAC9C,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;;cAEK,KAAK,CAAC,UAAU,8BAA8B,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,aAAa,KAAK,CAAC,UAAU;;;;0BAItG,KAAK,CAAC,UAAU;YAC9B,KAAK,CAAC,SAAS,WAAW,KAAK,CAAC,UAAU;;;;sCAIhB,KAAK,CAAC,SAAS,cAAc,KAAK,CAAC,SAAS,qBAAqB,KAAK,CAAC,SAAS;;;;CAIrH,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"content.template.js","sourceRoot":"","sources":["../../../../../scripts/generate-web-module/templates/components/content.template.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAWH,0DAmDC;AA5DD,0EAA6E;AAG7E;;;;;GAKG;AACH,SAAgB,uBAAuB,CAAC,IAA0B;IAChE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC;IAE9B,sEAAsE;IACtE,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO;;WAEA,KAAK,CAAC,UAAU,gCAAgC,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,SAAS,KAAK,CAAC,UAAU;;;OAGpH,KAAK,CAAC,UAAU,oBAAoB,KAAK,KAAK,KAAK,CAAC,UAAU;;kBAEnD,KAAK,CAAC,UAAU,aAAa,KAAK,OAAO,KAAK,CAAC,UAAU;;;sCAGrC,KAAK,cAAc,KAAK,qBAAqB,KAAK;;;;CAIvF,CAAC;IACA,CAAC;IAED,yEAAyE;IACzE,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAE1D,OAAO;;WAEE,KAAK,CAAC,UAAU,gCAAgC,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,SAAS,SAAS,KAAK,CAAC,UAAU;;;;OAIpH,KAAK,CAAC,UAAU,oBAAoB,KAAK,KAAK,KAAK,CAAC,UAAU;;kBAEnD,KAAK,CAAC,UAAU,aAAa,KAAK,OAAO,KAAK,CAAC,UAAU;;;;;;;0BAOjD,KAAK,CAAC,SAAS;;;EAGvC,iBAAiB;;;;;;CAMlB,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,SAAS,yBAAyB,CAAC,IAA0B;IAC3D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,0FAA0F;IAC1F,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhH,iBAAiB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAClC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC;kCACc,KAAK,CAAC,SAAS,WAAW,KAAK,CAAC,IAAI;qBACjD,KAAK,IAAI,KAAK,CAAC,IAAI;aAC3B,CAAC,CAAC;QACX,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,CAAC;kCACc,KAAK,CAAC,SAAS,WAAW,KAAK,CAAC,IAAI;qBACjD,KAAK,IAAI,KAAK,CAAC,IAAI;aAC3B,CAAC,CAAC;QACX,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnC,QAAQ,CAAC,IAAI,CAAC;kCACc,KAAK,CAAC,SAAS,WAAW,KAAK,CAAC,IAAI;qBACjD,KAAK,IAAI,KAAK,CAAC,IAAI;aAC3B,CAAC,CAAC;QACX,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,+DAA+D;IAC/D,aAAa;SACV,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,sCAAsC;SAChF,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,WAAW,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QACtD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,IAAA,8BAAW,EAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YACnE,QAAQ,CAAC,IAAI,CAAC,cAAc,KAAK,IAAI,QAAQ;;iDAEJ,QAAQ;uBAClC,KAAK,IAAI,QAAQ,IAAI,WAAW;;aAE1C,CAAC,CAAC;QACT,CAAC;aAAM,CAAC;YACN,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC;YAC5C,MAAM,QAAQ,GAAG,IAAA,4BAAS,EAAC,IAAA,8BAAW,EAAC,aAAa,CAAC,CAAC,CAAC;YACvD,QAAQ,CAAC,IAAI,CAAC,cAAc,KAAK,IAAI,QAAQ,OAAO,KAAK,IAAI,QAAQ;;oCAEzC,IAAA,4BAAS,EAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;uBAC9C,KAAK,IAAI,QAAQ,uBAAuB,WAAW;;aAE7D,CAAC,CAAC;QACT,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Editor Template
3
3
  *
4
- * Generates {Module}Editor.tsx dialog-based form component.
4
+ * Generates {Module}Editor.tsx form component using the EditorSheet wrapper.
5
5
  */
6
6
  import { FrontendTemplateData } from "../../types/template-data.interface";
7
7
  /**