Skip to content

Commit 950fe03

Browse files
committed
wip
1 parent b943386 commit 950fe03

2 files changed

Lines changed: 173 additions & 38 deletions

File tree

apps/events/src/components/ConvertTypesData.tsx

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,80 @@
11
import { useState } from 'react';
2-
import { generateMappingFile, generateSchemaFile } from '../utils/convertTypesData';
2+
import { getTypesWithSchemaAndMapping } from '../utils/convertTypesData';
33
import { Button } from './ui/button';
44
import { Card, CardContent, CardHeader, CardTitle } from './ui/card';
55

66
export const ConvertTypesData = () => {
7-
const [schemaOutput, setSchemaOutput] = useState<string>('');
8-
const [mappingOutput, setMappingOutput] = useState<string>('');
7+
const [isGenerated, setIsGenerated] = useState(false);
8+
const [typesData, setTypesData] = useState<ReturnType<typeof getTypesWithSchemaAndMapping>>([]);
9+
const [activeTab, setActiveTab] = useState<Record<string, 'schema' | 'mapping'>>({});
910

10-
const handleGenerateSchema = () => {
11-
const schema = generateSchemaFile();
12-
setSchemaOutput(schema);
11+
const handleGenerate = () => {
12+
const data = getTypesWithSchemaAndMapping();
13+
setTypesData(data);
14+
setIsGenerated(true);
15+
// Set default active tab to schema for all types
16+
const defaultTabs: Record<string, 'schema' | 'mapping'> = {};
17+
for (const typeData of data) {
18+
defaultTabs[typeData.id] = 'schema';
19+
}
20+
setActiveTab(defaultTabs);
1321
};
1422

15-
const handleGenerateMapping = () => {
16-
const mapping = generateMappingFile();
17-
setMappingOutput(mapping);
18-
};
19-
20-
const handleGenerateBoth = () => {
21-
handleGenerateSchema();
22-
handleGenerateMapping();
23+
const toggleTab = (typeId: string) => {
24+
setActiveTab((prev) => ({
25+
...prev,
26+
[typeId]: prev[typeId] === 'schema' ? 'mapping' : 'schema',
27+
}));
2328
};
2429

2530
return (
2631
<div className="space-y-4">
2732
<div className="flex gap-2">
28-
<Button onClick={handleGenerateSchema}>Generate Schema</Button>
29-
<Button onClick={handleGenerateMapping}>Generate Mapping</Button>
30-
<Button onClick={handleGenerateBoth}>Generate Both</Button>
33+
<Button onClick={handleGenerate}>Generate All Types</Button>
3134
</div>
3235

33-
{schemaOutput && (
34-
<Card>
35-
<CardHeader>
36-
<CardTitle>Generated Schema</CardTitle>
37-
</CardHeader>
38-
<CardContent>
39-
<pre className="bg-gray-100 p-4 rounded text-sm overflow-auto max-h-96">{schemaOutput}</pre>
40-
</CardContent>
41-
</Card>
42-
)}
36+
{isGenerated && (
37+
<div className="grid gap-4">
38+
{typesData.map((typeData) => (
39+
<Card key={typeData.id}>
40+
<CardHeader>
41+
<CardTitle className="flex items-center justify-between">
42+
<div className="flex items-center gap-2">
43+
<span>{typeData.name}</span>
44+
<span className="text-sm text-gray-500 font-normal">({typeData.properties.length} properties)</span>
45+
</div>
46+
<span className="text-sm text-gray-500 font-normal">ID: {typeData.id}</span>
47+
</CardTitle>
48+
</CardHeader>
49+
<CardContent>
50+
<div className="space-y-4">
51+
<div className="flex gap-2">
52+
<Button
53+
variant={activeTab[typeData.id] === 'schema' ? 'default' : 'outline'}
54+
onClick={() => toggleTab(typeData.id)}
55+
className="flex-1"
56+
>
57+
Schema
58+
</Button>
59+
<Button
60+
variant={activeTab[typeData.id] === 'mapping' ? 'default' : 'outline'}
61+
onClick={() => toggleTab(typeData.id)}
62+
className="flex-1"
63+
>
64+
Mapping
65+
</Button>
66+
</div>
4367

44-
{mappingOutput && (
45-
<Card>
46-
<CardHeader>
47-
<CardTitle>Generated Mapping</CardTitle>
48-
</CardHeader>
49-
<CardContent>
50-
<pre className="bg-gray-100 p-4 rounded text-sm overflow-auto max-h-96">{mappingOutput}</pre>
51-
</CardContent>
52-
</Card>
68+
<div className="bg-gray-100 p-4 rounded text-sm overflow-auto max-h-96">
69+
<pre className="whitespace-pre-wrap">
70+
{activeTab[typeData.id] === 'mapping' ? typeData.mapping : typeData.schema}
71+
</pre>
72+
</div>
73+
</div>
74+
</CardContent>
75+
</Card>
76+
))}
77+
</div>
5378
)}
5479
</div>
5580
);

apps/events/src/utils/convertTypesData.ts

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { typesData } from '../data/typesData';
44
// Type definitions for the data structure
55
interface Property {
66
id: string;
7-
dataType: 'TEXT' | 'NUMBER' | 'RELATION' | 'CHECKBOX' | 'DATE' | 'POINT' | 'URL';
7+
dataType: string;
88
relationValueTypes: Array<{
99
id: string;
1010
name: string;
@@ -40,6 +40,15 @@ interface MappingEntry {
4040
relations?: Record<string, string>;
4141
}
4242

43+
interface TypeWithSchemaAndMapping {
44+
id: string;
45+
name: string;
46+
className: string;
47+
properties: Property[];
48+
schema: string;
49+
mapping: string;
50+
}
51+
4352
// Helper function to convert dataType to Type
4453
function dataTypeToType(
4554
dataType: string,
@@ -93,6 +102,21 @@ function createClassName(typeName: string): string {
93102
.join('');
94103
}
95104

105+
// Helper function to convert string to camelCase
106+
function toCamelCase(str: string): string {
107+
return str
108+
.split(' ')
109+
.map((word, index) => {
110+
if (index === 0) {
111+
// First word should be lowercase
112+
return word.toLowerCase();
113+
}
114+
// Subsequent words should be capitalized
115+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
116+
})
117+
.join('');
118+
}
119+
96120
export function convertTypesDataToSchemaAndMapping() {
97121
const schemaEntries: string[] = [];
98122
const mappingEntries: Record<string, MappingEntry> = {};
@@ -117,7 +141,7 @@ export function convertTypesDataToSchemaAndMapping() {
117141
const mappingRelations: Record<string, string> = {};
118142

119143
for (const property of type.properties) {
120-
const propertyName = property.entity.name.toLowerCase().replace(/\s+/g, '');
144+
const propertyName = toCamelCase(property.entity.name);
121145

122146
if (property.dataType === 'RELATION') {
123147
const targetClassName = getRelationTargetClassName(property.relationValueTypes);
@@ -204,3 +228,89 @@ ${mappingEntries}
204228
};
205229
`;
206230
}
231+
232+
// Function to generate schema for a single type
233+
export function generateSchemaForType(type: TypeData): string {
234+
const className = createClassName(type.name);
235+
236+
const properties: string[] = [];
237+
238+
for (const property of type.properties) {
239+
const propertyName = toCamelCase(property.entity.name);
240+
241+
if (property.dataType === 'RELATION') {
242+
const targetClassName = getRelationTargetClassName(property.relationValueTypes);
243+
if (targetClassName) {
244+
const targetClass = createClassName(targetClassName);
245+
properties.push(` ${propertyName}: Type.Relation(${targetClass})`);
246+
}
247+
} else {
248+
const typeInstance = dataTypeToType(property.dataType);
249+
const typeName = typeInstance.name.endsWith('$') ? typeInstance.name.slice(0, -1) : typeInstance.name;
250+
properties.push(` ${propertyName}: Type.${typeName}`);
251+
}
252+
}
253+
254+
return `export class ${className} extends Entity.Class<${className}>('${className}')({
255+
${properties.join(',\n')}
256+
}) {}`;
257+
}
258+
259+
// Function to generate mapping for a single type
260+
export function generateMappingForType(type: TypeData): string {
261+
const className = createClassName(type.name);
262+
263+
const mappingProperties: Record<string, string> = {};
264+
const mappingRelations: Record<string, string> = {};
265+
266+
for (const property of type.properties) {
267+
const propertyName = toCamelCase(property.entity.name);
268+
269+
if (property.dataType === 'RELATION') {
270+
const targetClassName = getRelationTargetClassName(property.relationValueTypes);
271+
if (targetClassName) {
272+
mappingRelations[propertyName] = `Id.Id('${property.id}')`;
273+
}
274+
} else {
275+
mappingProperties[propertyName] = `Id.Id('${property.id}')`;
276+
}
277+
}
278+
279+
const properties = Object.entries(mappingProperties)
280+
.map(([key, value]) => ` ${key}: ${value}`)
281+
.join(',\n');
282+
283+
const relations = Object.entries(mappingRelations)
284+
.map(([key, value]) => ` ${key}: ${value}`)
285+
.join(',\n');
286+
287+
return ` ${className}: {
288+
typeIds: [Id.Id('${type.id}')],
289+
properties: {
290+
${properties}
291+
},
292+
${
293+
relations
294+
? ` relations: {
295+
${relations}
296+
},`
297+
: ''
298+
}
299+
}`;
300+
}
301+
302+
// Function to get all types with their individual schema and mapping
303+
export function getTypesWithSchemaAndMapping(): TypeWithSchemaAndMapping[] {
304+
return typesData.types.map((type) => {
305+
const className = createClassName(type.name);
306+
307+
return {
308+
id: type.id,
309+
name: type.name,
310+
className,
311+
properties: type.properties,
312+
schema: generateSchemaForType(type),
313+
mapping: generateMappingForType(type),
314+
};
315+
});
316+
}

0 commit comments

Comments
 (0)