Skip to content

Commit 86af583

Browse files
committed
#513-first-prototype-json-import
1 parent 383a1e9 commit 86af583

File tree

2 files changed

+132
-8
lines changed

2 files changed

+132
-8
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { GenerateGUID } from '@/core/model';
2+
3+
export type FieldType =
4+
| 'any'
5+
| 'array'
6+
| 'binData'
7+
| 'bool'
8+
| 'date'
9+
| 'dbPointer'
10+
| 'decimal'
11+
| 'double'
12+
| 'enum'
13+
| 'int'
14+
| 'javascript'
15+
| 'long'
16+
| 'maxKey'
17+
| 'minKey'
18+
| 'null'
19+
| 'object'
20+
| 'objectId'
21+
| 'regex'
22+
| 'string'
23+
| 'symbol'
24+
| 'timestamp'
25+
| 'undefined';
26+
27+
export interface FieldVm {
28+
id: string;
29+
PK: boolean;
30+
FK: boolean;
31+
name: string;
32+
type: FieldType;
33+
children?: FieldVm[];
34+
isCollapsed?: boolean;
35+
isArray?: boolean;
36+
isNN?: boolean;
37+
}
38+
39+
function inferMongoType(value: object | string | number | boolean | null | undefined): FieldType {
40+
if (value === null) return 'null';
41+
if (value === undefined) return 'undefined';
42+
if (Array.isArray(value)) return 'array';
43+
44+
if (typeof value === 'object') {
45+
if ('$oid' in value) return 'objectId';
46+
if ('$date' in value) return 'date';
47+
if ('$numberInt' in value) return 'int';
48+
if ('$numberLong' in value) return 'long';
49+
if ('$numberDouble' in value) return 'double';
50+
if ('$numberDecimal' in value) return 'decimal';
51+
if ('$regex' in value) return 'regex';
52+
if ('$timestamp' in value) return 'timestamp';
53+
return 'object';
54+
}
55+
56+
switch (typeof value) {
57+
case 'string': return 'string';
58+
case 'number': return 'double';
59+
case 'boolean': return 'bool';
60+
case 'symbol': return 'symbol';
61+
case 'function': return 'javascript';
62+
default: return 'any';
63+
}
64+
}
65+
66+
export function parseJsonToFieldVm(obj: Record<string, unknown>): FieldVm[] {
67+
const result: FieldVm[] = [];
68+
69+
for (const key of Object.keys(obj)) {
70+
const value = obj[key];
71+
const isArray = Array.isArray(value);
72+
const baseValue = isArray ? value[0] : value;
73+
74+
const type = inferMongoType(baseValue);
75+
76+
// Check if the field has isNN in the value or if it is _id
77+
const isNN = isObjectWithIsNN(value) ? value.isNN === true : key === '_id';
78+
79+
const field: FieldVm = {
80+
id: GenerateGUID(),
81+
PK: key === '_id',
82+
FK: false,
83+
name: key,
84+
type,
85+
isArray,
86+
isNN,
87+
};
88+
89+
const isPlainObject = (
90+
type === 'object' &&
91+
baseValue &&
92+
typeof baseValue === 'object' &&
93+
!('$oid' in baseValue || '$date' in baseValue || '$numberInt' in baseValue)
94+
);
95+
96+
if (isPlainObject) {
97+
field.children = parseJsonToFieldVm(baseValue);
98+
}
99+
100+
result.push(field);
101+
}
102+
103+
return result;
104+
}
105+
106+
// Function to check if an object has the isNN property
107+
function isObjectWithIsNN(value: unknown): value is { isNN: boolean } {
108+
return typeof value === 'object' && value !== null && 'isNN' in value;
109+
}

src/pods/import-collection/import-panel.pod.tsx

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as canvasVm from '@/core/providers/canvas-schema';
44
import * as editTableVm from '../edit-table/edit-table.vm';
55
import { doMapOrCreateTable } from '../edit-table/edit-table.business';
66
import { mapEditTableVmToTableVm } from '../edit-table/edit-table.mapper';
7+
import { parseJsonToFieldVm } from './edit-table.business';
78

89
interface ImportPanelProps {
910
table?: canvasVm.TableVm;
@@ -14,9 +15,14 @@ interface ImportPanelProps {
1415

1516
const defaultJson = JSON.stringify(
1617
{
17-
_id: { $oid: '5f5f9b3b4b4b1f001f1b1f1b' },
18-
age: '30',
19-
name: 'John Doe',
18+
_id: { $oid: '67bdea3c01572368ed0b2d81' },
19+
room: 'ada-36567',
20+
content: '\nHello\n\nworld\n',
21+
expireAt: {
22+
$date: { $numberLong: '1740499516555' },
23+
isNN: true,
24+
},
25+
__v: { $numberInt: '0' },
2026
},
2127
null,
2228
2
@@ -31,9 +37,18 @@ export const ImportPanel: React.FC<ImportPanelProps> = props => {
3137
doMapOrCreateTable(relations, table)
3238
);
3339

34-
const handleSubmit = (table: editTableVm.TableVm) => {
35-
console.log(jsonContent);
36-
onSave(mapEditTableVmToTableVm(table));
40+
const handleSubmit = () => {
41+
try {
42+
const parsedJson = JSON.parse(jsonContent);
43+
const parsedFields = parseJsonToFieldVm(parsedJson);
44+
const newTable: editTableVm.TableVm = {
45+
...editTable,
46+
fields: parsedFields,
47+
};
48+
onSave(mapEditTableVmToTableVm(newTable));
49+
} catch (error) {
50+
setJsonError('El JSON no es válido');
51+
}
3752
};
3853

3954
const handleJsonContentChange = (
@@ -62,7 +77,7 @@ export const ImportPanel: React.FC<ImportPanelProps> = props => {
6277
Collection:
6378
<input
6479
type="text"
65-
value={table?.tableName}
80+
value={editTable.tableName}
6681
onChange={handleChangeTableName}
6782
onFocus={e => e.currentTarget.select()}
6883
/>
@@ -84,7 +99,7 @@ export const ImportPanel: React.FC<ImportPanelProps> = props => {
8499
<div className="two-buttons">
85100
<button
86101
className="button-secondary"
87-
onClick={() => handleSubmit(editTable)}
102+
onClick={handleSubmit}
88103
disabled={jsonError !== null}
89104
>
90105
Apply

0 commit comments

Comments
 (0)