@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.
- package/dist/scripts/generate-web-module/__tests__/container.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/container.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/container.spec.js +54 -0
- package/dist/scripts/generate-web-module/__tests__/container.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/data-service.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/data-service.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/data-service.spec.js +19 -0
- package/dist/scripts/generate-web-module/__tests__/data-service.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/editor.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/editor.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/editor.spec.js +35 -0
- package/dist/scripts/generate-web-module/__tests__/editor.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/fixtures.d.ts +4 -0
- package/dist/scripts/generate-web-module/__tests__/fixtures.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/fixtures.js +45 -0
- package/dist/scripts/generate-web-module/__tests__/fixtures.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/model-interface.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/model-interface.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/model-interface.spec.js +74 -0
- package/dist/scripts/generate-web-module/__tests__/model-interface.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/plumbing.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/plumbing.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/plumbing.spec.js +21 -0
- package/dist/scripts/generate-web-module/__tests__/plumbing.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/selector.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/selector.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/selector.spec.js +25 -0
- package/dist/scripts/generate-web-module/__tests__/selector.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.js +55 -0
- package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/generator.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/generator.js +14 -11
- package/dist/scripts/generate-web-module/generator.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/container.template.d.ts +5 -1
- package/dist/scripts/generate-web-module/templates/components/container.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/container.template.js +43 -63
- package/dist/scripts/generate-web-module/templates/components/container.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/content.template.d.ts +7 -4
- package/dist/scripts/generate-web-module/templates/components/content.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/content.template.js +103 -14
- package/dist/scripts/generate-web-module/templates/components/content.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/editor.template.d.ts +1 -1
- package/dist/scripts/generate-web-module/templates/components/editor.template.js +139 -150
- package/dist/scripts/generate-web-module/templates/components/editor.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/index.d.ts +0 -1
- package/dist/scripts/generate-web-module/templates/components/index.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/index.js +1 -3
- package/dist/scripts/generate-web-module/templates/components/index.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/list-container.template.js +2 -2
- package/dist/scripts/generate-web-module/templates/components/list.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/list.template.js +6 -1
- package/dist/scripts/generate-web-module/templates/components/list.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/selector.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/selector.template.js +48 -52
- package/dist/scripts/generate-web-module/templates/components/selector.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/interface.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/interface.template.js +38 -11
- package/dist/scripts/generate-web-module/templates/data/interface.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/model.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/model.template.js +83 -26
- package/dist/scripts/generate-web-module/templates/data/model.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/service.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/service.template.js +21 -1
- package/dist/scripts/generate-web-module/templates/data/service.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/index.d.ts +1 -1
- package/dist/scripts/generate-web-module/templates/index.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/index.js +1 -2
- package/dist/scripts/generate-web-module/templates/index.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/module.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/module.template.js +11 -3
- package/dist/scripts/generate-web-module/templates/module.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/table-hook.template.js +31 -1
- package/dist/scripts/generate-web-module/templates/table-hook.template.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.d.ts +0 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.js +0 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/relationship-key.d.ts +5 -0
- package/dist/scripts/generate-web-module/transformers/relationship-key.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/transformers/relationship-key.js +21 -0
- package/dist/scripts/generate-web-module/transformers/relationship-key.js.map +1 -0
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.js +2 -0
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.js.map +1 -1
- package/dist/scripts/generate-web-module/types/json-schema.interface.d.ts +21 -0
- package/dist/scripts/generate-web-module/types/json-schema.interface.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/types/template-data.interface.d.ts +17 -0
- package/dist/scripts/generate-web-module/types/template-data.interface.d.ts.map +1 -1
- package/package.json +1 -1
- package/scripts/generate-web-module/__tests__/container.spec.ts +58 -0
- package/scripts/generate-web-module/__tests__/data-service.spec.ts +18 -0
- package/scripts/generate-web-module/__tests__/editor.spec.ts +36 -0
- package/scripts/generate-web-module/__tests__/fixtures.ts +43 -0
- package/scripts/generate-web-module/__tests__/model-interface.spec.ts +77 -0
- package/scripts/generate-web-module/__tests__/plumbing.spec.ts +21 -0
- package/scripts/generate-web-module/__tests__/selector.spec.ts +24 -0
- package/scripts/generate-web-module/__tests__/table-module-list.spec.ts +59 -0
- package/scripts/generate-web-module/generator.ts +14 -13
- package/scripts/generate-web-module/templates/components/container.template.ts +51 -66
- package/scripts/generate-web-module/templates/components/content.template.ts +107 -15
- package/scripts/generate-web-module/templates/components/editor.template.ts +140 -152
- package/scripts/generate-web-module/templates/components/index.ts +0 -1
- package/scripts/generate-web-module/templates/components/list-container.template.ts +2 -2
- package/scripts/generate-web-module/templates/components/list.template.ts +6 -1
- package/scripts/generate-web-module/templates/components/selector.template.ts +48 -52
- package/scripts/generate-web-module/templates/data/interface.template.ts +44 -12
- package/scripts/generate-web-module/templates/data/model.template.ts +88 -28
- package/scripts/generate-web-module/templates/data/service.template.ts +23 -1
- package/scripts/generate-web-module/templates/index.ts +0 -1
- package/scripts/generate-web-module/templates/module.template.ts +13 -3
- package/scripts/generate-web-module/templates/table-hook.template.ts +31 -2
- package/scripts/generate-web-module/transformers/import-resolver.ts +0 -2
- package/scripts/generate-web-module/transformers/relationship-key.ts +18 -0
- package/scripts/generate-web-module/transformers/relationship-resolver.ts +2 -0
- package/scripts/generate-web-module/types/json-schema.interface.ts +9 -0
- package/scripts/generate-web-module/types/template-data.interface.ts +7 -0
- package/dist/scripts/generate-web-module/templates/components/details.template.d.ts +0 -14
- package/dist/scripts/generate-web-module/templates/components/details.template.d.ts.map +0 -1
- package/dist/scripts/generate-web-module/templates/components/details.template.js +0 -112
- package/dist/scripts/generate-web-module/templates/components/details.template.js.map +0 -1
- package/scripts/generate-web-module/templates/components/details.template.ts +0 -116
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { FrontendTemplateData, FrontendField } from "../types/template-data.interface";
|
|
8
|
-
import { toCamelCase } from "../transformers/name-transformer";
|
|
8
|
+
import { toCamelCase, pluralize } from "../transformers/name-transformer";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Generate the table structure hook file content
|
|
@@ -96,7 +96,7 @@ registerTableGenerator(Modules.${names.pascalCase}, use${names.pascalCase}TableS
|
|
|
96
96
|
* Generate field column map entries
|
|
97
97
|
*/
|
|
98
98
|
function generateFieldColumnEntries(data: FrontendTemplateData): string {
|
|
99
|
-
const { names, fields, extendsContent } = data;
|
|
99
|
+
const { names, fields, extendsContent, relationships } = data;
|
|
100
100
|
const entries: string[] = [];
|
|
101
101
|
|
|
102
102
|
// Name field (with link and tooltip for tldr if Content-extending)
|
|
@@ -183,8 +183,37 @@ function generateFieldColumnEntries(data: FrontendTemplateData): string {
|
|
|
183
183
|
enableSorting: false,
|
|
184
184
|
enableHiding: false,
|
|
185
185
|
}),`);
|
|
186
|
+
} else if (field.type === "date" || field.type === "datetime") {
|
|
187
|
+
entries.push(` [${names.pascalCase}Fields.${field.name}]: () =>
|
|
188
|
+
cellDate({
|
|
189
|
+
name: "${field.name}",
|
|
190
|
+
title: t(\`features.${names.camelCase}.fields.${field.name}.label\`),
|
|
191
|
+
}),`);
|
|
186
192
|
}
|
|
187
193
|
});
|
|
188
194
|
|
|
195
|
+
// Relationship columns (rendered when flagged for table display)
|
|
196
|
+
relationships
|
|
197
|
+
.filter((rel) => rel.showInTable)
|
|
198
|
+
.forEach((rel) => {
|
|
199
|
+
const key = rel.single
|
|
200
|
+
? toCamelCase(rel.alias || rel.variant || rel.name)
|
|
201
|
+
: pluralize(toCamelCase(rel.alias || rel.name));
|
|
202
|
+
const accessor = rel.single
|
|
203
|
+
? `${names.camelCase}.${key}?.name ?? ""`
|
|
204
|
+
: `${names.camelCase}.${key}.map((r) => r.name).join(", ")`;
|
|
205
|
+
entries.push(` [${names.pascalCase}Fields.${key}]: () => ({
|
|
206
|
+
id: "${key}",
|
|
207
|
+
accessorKey: "${key}",
|
|
208
|
+
header: t(\`generic.relationships.${key}.label\`),
|
|
209
|
+
cell: ({ row }: { row: TableContent<${names.pascalCase}Interface> }) => {
|
|
210
|
+
const ${names.camelCase}: ${names.pascalCase}Interface = row.original.jsonApiData;
|
|
211
|
+
return <span>{${accessor}}</span>;
|
|
212
|
+
},
|
|
213
|
+
enableSorting: false,
|
|
214
|
+
enableHiding: false,
|
|
215
|
+
}),`);
|
|
216
|
+
});
|
|
217
|
+
|
|
189
218
|
return entries.join("\n");
|
|
190
219
|
}
|
|
@@ -177,7 +177,6 @@ export interface ModuleFilePaths {
|
|
|
177
177
|
selector: string;
|
|
178
178
|
multiSelector: string;
|
|
179
179
|
list: string;
|
|
180
|
-
details: string;
|
|
181
180
|
content: string;
|
|
182
181
|
container: string;
|
|
183
182
|
listContainer: string;
|
|
@@ -220,7 +219,6 @@ export function buildFilePaths(
|
|
|
220
219
|
selector: `${basePath}/components/forms/${names.pascalCase}Selector.tsx`,
|
|
221
220
|
multiSelector: `${basePath}/components/forms/${names.pascalCase}MultiSelector.tsx`,
|
|
222
221
|
list: `${basePath}/components/lists/${names.pascalCase}List.tsx`,
|
|
223
|
-
details: `${basePath}/components/details/${names.pascalCase}Details.tsx`,
|
|
224
222
|
content: `${basePath}/components/details/${names.pascalCase}Content.tsx`,
|
|
225
223
|
container: `${basePath}/components/containers/${names.pascalCase}Container.tsx`,
|
|
226
224
|
listContainer: `${basePath}/components/containers/${names.pascalCase}ListContainer.tsx`,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FrontendRelationship } from "../types/template-data.interface";
|
|
2
|
+
import { toKebabCase, pluralize } from "./name-transformer";
|
|
3
|
+
|
|
4
|
+
/** JSON:API wire key for a relationship. Schema dtoKey wins; otherwise derive
|
|
5
|
+
* identically to the backend mapper so both sides of the wire agree. */
|
|
6
|
+
export function resolveRelationshipKey(rel: FrontendRelationship): string {
|
|
7
|
+
if (rel.dtoKey) return rel.dtoKey;
|
|
8
|
+
// NOTE: Author relationships are normally NOT serialized through this helper — the backend
|
|
9
|
+
// special-cases Author via contextKey/currentUser and the model template skips Author
|
|
10
|
+
// serialization, so callers must not rely on this helper for Author wire keys.
|
|
11
|
+
if (rel.variant) {
|
|
12
|
+
return rel.single ? rel.variant.toLowerCase() : pluralize(rel.variant.toLowerCase());
|
|
13
|
+
}
|
|
14
|
+
if (rel.alias) {
|
|
15
|
+
return rel.single ? toKebabCase(rel.alias) : pluralize(toKebabCase(rel.alias));
|
|
16
|
+
}
|
|
17
|
+
return rel.single ? rel.name.toLowerCase() : pluralize(rel.name.toLowerCase());
|
|
18
|
+
}
|
|
@@ -122,6 +122,8 @@ export function resolveRelationship(rel: JsonRelationshipDefinition, targetHasNa
|
|
|
122
122
|
modelKebab,
|
|
123
123
|
fields,
|
|
124
124
|
targetHasName: targetHasNameMap?.get(rel.name) ?? true, // Foundation entities default to true
|
|
125
|
+
dtoKey: rel.dtoKey ?? "",
|
|
126
|
+
showInTable: rel.showInTable === true,
|
|
125
127
|
};
|
|
126
128
|
}
|
|
127
129
|
|
|
@@ -13,6 +13,7 @@ export interface JsonFieldDefinition {
|
|
|
13
13
|
name: string;
|
|
14
14
|
type: string;
|
|
15
15
|
nullable: boolean;
|
|
16
|
+
readOnly?: boolean;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -29,6 +30,10 @@ export interface JsonRelationshipDefinition {
|
|
|
29
30
|
toNode: boolean; // Backend-specific, ignored in frontend
|
|
30
31
|
nullable: boolean;
|
|
31
32
|
fields?: JsonFieldDefinition[]; // Relationship property fields (stored on edges)
|
|
33
|
+
/** Explicit JSON:API wire key. When absent it is derived identically to the backend mapper. */
|
|
34
|
+
dtoKey?: string;
|
|
35
|
+
description?: string;
|
|
36
|
+
showInTable?: boolean;
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
/**
|
|
@@ -44,4 +49,8 @@ export interface JsonModuleDefinition {
|
|
|
44
49
|
relationships: JsonRelationshipDefinition[];
|
|
45
50
|
/** Explicitly set whether this module extends Content. If not set, auto-detects based on fields. */
|
|
46
51
|
extendsContent?: boolean;
|
|
52
|
+
featureId?: string;
|
|
53
|
+
displayProp?: string;
|
|
54
|
+
containerTabs?: { activity?: boolean; relations?: { module: string; listProp: string; directory: string }[] };
|
|
55
|
+
inclusions?: { related?: { endpoint: string; fields: string[] }[] };
|
|
47
56
|
}
|
|
@@ -30,6 +30,7 @@ export interface FrontendField {
|
|
|
30
30
|
formComponent: FormComponentType;
|
|
31
31
|
nullable: boolean;
|
|
32
32
|
isContentField: boolean; // Indicates BlockNoteEditor
|
|
33
|
+
readOnly?: boolean;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
/**
|
|
@@ -68,6 +69,8 @@ export interface FrontendRelationship {
|
|
|
68
69
|
modelKebab: string; // e.g., "user"
|
|
69
70
|
fields?: FrontendField[]; // Relationship property fields (stored on edges)
|
|
70
71
|
targetHasName: boolean; // Whether the target entity has a "name" field (or extends Content)
|
|
72
|
+
dtoKey: string; // resolved wire key; "" means derive at use-site
|
|
73
|
+
showInTable: boolean;
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
/**
|
|
@@ -153,6 +156,10 @@ export interface FrontendTemplateData {
|
|
|
153
156
|
|
|
154
157
|
// For service generation
|
|
155
158
|
relationshipServiceMethods: RelationshipServiceMethod[];
|
|
159
|
+
featureId?: string;
|
|
160
|
+
displayProp: string;
|
|
161
|
+
containerTabs: { activity: boolean; relations: { module: string; listProp: string; directory: string }[] };
|
|
162
|
+
relatedInclusions: { endpoint: string; fields: string[] }[];
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
/**
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Details Template
|
|
3
|
-
*
|
|
4
|
-
* Generates {Module}Details.tsx component for displaying item details.
|
|
5
|
-
*/
|
|
6
|
-
import { FrontendTemplateData } from "../../types/template-data.interface";
|
|
7
|
-
/**
|
|
8
|
-
* Generate the details component file content
|
|
9
|
-
*
|
|
10
|
-
* @param data - Frontend template data
|
|
11
|
-
* @returns Generated file content
|
|
12
|
-
*/
|
|
13
|
-
export declare function generateDetailsTemplate(data: FrontendTemplateData): string;
|
|
14
|
-
//# sourceMappingURL=details.template.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"details.template.d.ts","sourceRoot":"","sources":["../../../../../scripts/generate-web-module/templates/components/details.template.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAmC1E"}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Details Template
|
|
4
|
-
*
|
|
5
|
-
* Generates {Module}Details.tsx component for displaying item details.
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.generateDetailsTemplate = generateDetailsTemplate;
|
|
9
|
-
const name_transformer_1 = require("../../transformers/name-transformer");
|
|
10
|
-
/**
|
|
11
|
-
* Generate the details component file content
|
|
12
|
-
*
|
|
13
|
-
* @param data - Frontend template data
|
|
14
|
-
* @returns Generated file content
|
|
15
|
-
*/
|
|
16
|
-
function generateDetailsTemplate(data) {
|
|
17
|
-
const { names, fields, relationships, extendsContent } = data;
|
|
18
|
-
const attributeElements = generateAttributeElements(data);
|
|
19
|
-
return `"use client";
|
|
20
|
-
|
|
21
|
-
import { use${names.pascalCase}Context } from "@/features/${data.importTargetDir}/${names.kebabCase}/contexts/${names.pascalCase}Context";
|
|
22
|
-
import { AttributeElement, ContentTitle, ReactMarkdownContainer } from "@carlonicora/nextjs-jsonapi/components";
|
|
23
|
-
import { useSharedContext } from "@carlonicora/nextjs-jsonapi/contexts";
|
|
24
|
-
import { Modules } from "@carlonicora/nextjs-jsonapi/core";
|
|
25
|
-
import { useTranslations } from "next-intl";
|
|
26
|
-
|
|
27
|
-
function ${names.pascalCase}DetailsInternal() {
|
|
28
|
-
const { ${names.camelCase}, reload${names.pascalCase} } = use${names.pascalCase}Context();
|
|
29
|
-
const t = useTranslations();
|
|
30
|
-
const { title } = useSharedContext();
|
|
31
|
-
|
|
32
|
-
if (!${names.camelCase}) return null;
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div className="flex w-full flex-col gap-y-2">
|
|
36
|
-
<ContentTitle type={title.type} element={title.element} functions={title.functions} module={Modules.${names.pascalCase}} />
|
|
37
|
-
${attributeElements}
|
|
38
|
-
</div>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export default function ${names.pascalCase}Details() {
|
|
43
|
-
const { ${names.camelCase} } = use${names.pascalCase}Context();
|
|
44
|
-
if (!${names.camelCase}) return null;
|
|
45
|
-
|
|
46
|
-
return <${names.pascalCase}DetailsInternal />;
|
|
47
|
-
}
|
|
48
|
-
`;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Generate attribute elements for display fields
|
|
52
|
-
*/
|
|
53
|
-
function generateAttributeElements(data) {
|
|
54
|
-
const { names, fields, relationships, extendsContent } = data;
|
|
55
|
-
const elements = [];
|
|
56
|
-
// Show abstract if Content-extending
|
|
57
|
-
if (extendsContent) {
|
|
58
|
-
elements.push(` <AttributeElement
|
|
59
|
-
title={t(\`generic.abstract\`)}
|
|
60
|
-
value={<ReactMarkdownContainer size="small" content={${names.camelCase}.abstract} />}
|
|
61
|
-
/>`);
|
|
62
|
-
}
|
|
63
|
-
// Add custom fields (excluding name, tldr, abstract, content which are handled elsewhere)
|
|
64
|
-
const displayableFields = fields.filter((f) => !["name", "tldr", "abstract", "content", "id"].includes(f.name));
|
|
65
|
-
displayableFields.forEach((field) => {
|
|
66
|
-
if (field.type === "string") {
|
|
67
|
-
elements.push(` <AttributeElement
|
|
68
|
-
title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
|
|
69
|
-
value={${names.camelCase}.${field.name}}
|
|
70
|
-
/>`);
|
|
71
|
-
}
|
|
72
|
-
else if (field.type === "boolean") {
|
|
73
|
-
elements.push(` <AttributeElement
|
|
74
|
-
title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
|
|
75
|
-
value={${names.camelCase}.${field.name} ? t(\`generic.yes\`) : t(\`generic.no\`)}
|
|
76
|
-
/>`);
|
|
77
|
-
}
|
|
78
|
-
else if (field.type === "number") {
|
|
79
|
-
elements.push(` <AttributeElement
|
|
80
|
-
title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
|
|
81
|
-
value={${names.camelCase}.${field.name}?.toString()}
|
|
82
|
-
/>`);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
// Add relationship displays (basic - can be enhanced manually)
|
|
86
|
-
relationships
|
|
87
|
-
.filter((rel) => rel.variant !== "Author") // Skip author, usually shown in title
|
|
88
|
-
.forEach((rel) => {
|
|
89
|
-
const displayProp = rel.targetHasName ? "name" : "id";
|
|
90
|
-
if (rel.single) {
|
|
91
|
-
const propName = (0, name_transformer_1.toCamelCase)(rel.alias || rel.variant || rel.name);
|
|
92
|
-
elements.push(` {${names.camelCase}.${propName} && (
|
|
93
|
-
<AttributeElement
|
|
94
|
-
title={t(\`generic.relationships.${propName}.label\`)}
|
|
95
|
-
value={${names.camelCase}.${propName}.${displayProp}}
|
|
96
|
-
/>
|
|
97
|
-
)}`);
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
const effectiveMany = rel.alias || rel.name;
|
|
101
|
-
const propName = (0, name_transformer_1.pluralize)((0, name_transformer_1.toCamelCase)(effectiveMany));
|
|
102
|
-
elements.push(` {${names.camelCase}.${propName} && ${names.camelCase}.${propName}.length > 0 && (
|
|
103
|
-
<AttributeElement
|
|
104
|
-
title={t(\`entities.${(0, name_transformer_1.pluralize)(rel.name.toLowerCase())}\`, { count: 2 })}
|
|
105
|
-
value={${names.camelCase}.${propName}.map((item) => item.${displayProp}).join(", ")}
|
|
106
|
-
/>
|
|
107
|
-
)}`);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
return elements.join("\n");
|
|
111
|
-
}
|
|
112
|
-
//# sourceMappingURL=details.template.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"details.template.js","sourceRoot":"","sources":["../../../../../scripts/generate-web-module/templates/components/details.template.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Details Template
|
|
3
|
-
*
|
|
4
|
-
* Generates {Module}Details.tsx component for displaying item details.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { pluralize, toCamelCase } from "../../transformers/name-transformer";
|
|
8
|
-
import { FrontendTemplateData } from "../../types/template-data.interface";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Generate the details component file content
|
|
12
|
-
*
|
|
13
|
-
* @param data - Frontend template data
|
|
14
|
-
* @returns Generated file content
|
|
15
|
-
*/
|
|
16
|
-
export function generateDetailsTemplate(data: FrontendTemplateData): string {
|
|
17
|
-
const { names, fields, relationships, extendsContent } = data;
|
|
18
|
-
|
|
19
|
-
const attributeElements = generateAttributeElements(data);
|
|
20
|
-
|
|
21
|
-
return `"use client";
|
|
22
|
-
|
|
23
|
-
import { use${names.pascalCase}Context } from "@/features/${data.importTargetDir}/${names.kebabCase}/contexts/${names.pascalCase}Context";
|
|
24
|
-
import { AttributeElement, ContentTitle, ReactMarkdownContainer } from "@carlonicora/nextjs-jsonapi/components";
|
|
25
|
-
import { useSharedContext } from "@carlonicora/nextjs-jsonapi/contexts";
|
|
26
|
-
import { Modules } from "@carlonicora/nextjs-jsonapi/core";
|
|
27
|
-
import { useTranslations } from "next-intl";
|
|
28
|
-
|
|
29
|
-
function ${names.pascalCase}DetailsInternal() {
|
|
30
|
-
const { ${names.camelCase}, reload${names.pascalCase} } = use${names.pascalCase}Context();
|
|
31
|
-
const t = useTranslations();
|
|
32
|
-
const { title } = useSharedContext();
|
|
33
|
-
|
|
34
|
-
if (!${names.camelCase}) return null;
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<div className="flex w-full flex-col gap-y-2">
|
|
38
|
-
<ContentTitle type={title.type} element={title.element} functions={title.functions} module={Modules.${names.pascalCase}} />
|
|
39
|
-
${attributeElements}
|
|
40
|
-
</div>
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export default function ${names.pascalCase}Details() {
|
|
45
|
-
const { ${names.camelCase} } = use${names.pascalCase}Context();
|
|
46
|
-
if (!${names.camelCase}) return null;
|
|
47
|
-
|
|
48
|
-
return <${names.pascalCase}DetailsInternal />;
|
|
49
|
-
}
|
|
50
|
-
`;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Generate attribute elements for display fields
|
|
55
|
-
*/
|
|
56
|
-
function generateAttributeElements(data: FrontendTemplateData): string {
|
|
57
|
-
const { names, fields, relationships, extendsContent } = data;
|
|
58
|
-
const elements: string[] = [];
|
|
59
|
-
|
|
60
|
-
// Show abstract if Content-extending
|
|
61
|
-
if (extendsContent) {
|
|
62
|
-
elements.push(` <AttributeElement
|
|
63
|
-
title={t(\`generic.abstract\`)}
|
|
64
|
-
value={<ReactMarkdownContainer size="small" content={${names.camelCase}.abstract} />}
|
|
65
|
-
/>`);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Add custom fields (excluding name, tldr, abstract, content which are handled elsewhere)
|
|
69
|
-
const displayableFields = fields.filter((f) => !["name", "tldr", "abstract", "content", "id"].includes(f.name));
|
|
70
|
-
|
|
71
|
-
displayableFields.forEach((field) => {
|
|
72
|
-
if (field.type === "string") {
|
|
73
|
-
elements.push(` <AttributeElement
|
|
74
|
-
title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
|
|
75
|
-
value={${names.camelCase}.${field.name}}
|
|
76
|
-
/>`);
|
|
77
|
-
} else if (field.type === "boolean") {
|
|
78
|
-
elements.push(` <AttributeElement
|
|
79
|
-
title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
|
|
80
|
-
value={${names.camelCase}.${field.name} ? t(\`generic.yes\`) : t(\`generic.no\`)}
|
|
81
|
-
/>`);
|
|
82
|
-
} else if (field.type === "number") {
|
|
83
|
-
elements.push(` <AttributeElement
|
|
84
|
-
title={t(\`features.${names.camelCase}.fields.${field.name}.label\`)}
|
|
85
|
-
value={${names.camelCase}.${field.name}?.toString()}
|
|
86
|
-
/>`);
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Add relationship displays (basic - can be enhanced manually)
|
|
91
|
-
relationships
|
|
92
|
-
.filter((rel) => rel.variant !== "Author") // Skip author, usually shown in title
|
|
93
|
-
.forEach((rel) => {
|
|
94
|
-
const displayProp = rel.targetHasName ? "name" : "id";
|
|
95
|
-
if (rel.single) {
|
|
96
|
-
const propName = toCamelCase(rel.alias || rel.variant || rel.name);
|
|
97
|
-
elements.push(` {${names.camelCase}.${propName} && (
|
|
98
|
-
<AttributeElement
|
|
99
|
-
title={t(\`generic.relationships.${propName}.label\`)}
|
|
100
|
-
value={${names.camelCase}.${propName}.${displayProp}}
|
|
101
|
-
/>
|
|
102
|
-
)}`);
|
|
103
|
-
} else {
|
|
104
|
-
const effectiveMany = rel.alias || rel.name;
|
|
105
|
-
const propName = pluralize(toCamelCase(effectiveMany));
|
|
106
|
-
elements.push(` {${names.camelCase}.${propName} && ${names.camelCase}.${propName}.length > 0 && (
|
|
107
|
-
<AttributeElement
|
|
108
|
-
title={t(\`entities.${pluralize(rel.name.toLowerCase())}\`, { count: 2 })}
|
|
109
|
-
value={${names.camelCase}.${propName}.map((item) => item.${displayProp}).join(", ")}
|
|
110
|
-
/>
|
|
111
|
-
)}`);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
return elements.join("\n");
|
|
116
|
-
}
|