Skip to content

Commit 365f4d9

Browse files
author
Yevhen Zavhorodnii
committed
Allow to change objects and array of strings and objects
1 parent 3584123 commit 365f4d9

File tree

2 files changed

+117
-19
lines changed

2 files changed

+117
-19
lines changed

server/static/js/edit-model.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ $(document).ready(function() {
145145
}
146146

147147
function openPropertyEditor(nodeData, id, schema) {
148-
const classEditor = new EditorGenerator(nodeData, schema, id);
148+
149+
const classEditor = new EditorGenerator(nodeData, schema, $('#' + id));
149150
// TODO: do not hard code hidden properties
150151
classEditor.generateEditor(['communication_links', 'data_assets_processed', 'data_assets_stored',
151152
'data_assets_sent', 'data_assets_received', 'data_assets', 'technical_assets',

server/static/js/property-editor.js

Lines changed: 115 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
11
class EditorGenerator {
2-
constructor(object, schema, formContainerId) {
2+
constructor(object, schema, formContainer) {
33
this.object = object;
44
this.schema = schema;
5-
this.formContainer = $('#' + formContainerId);
5+
this.formContainer = formContainer;
66
}
77

8-
generateEditor(ignoreFields) {
8+
generateEditor(ignoreFields = []) {
99
this.formContainer.empty();
1010

1111
for (const [key, property] of Object.entries(this.schema)) {
1212
if (ignoreFields.includes(key)) {
1313
continue;
1414
}
1515

16-
const label = $('<label>').text(key).addClass('property-editor-label');
16+
const label = $('<label>')
17+
.text(key)
18+
.addClass('property-editor-label');
1719
let input;
18-
19-
let propertyType = property.type;
20-
if (Array.isArray(property.type)) {
21-
propertyType = property.type[0];
22-
if (propertyType === 'array') {
23-
propertyType = 'arrayOf ' + property.items.type;
24-
}
25-
}
20+
const propertyType = Array.isArray(property.type) ? property.type[0] : property.type;
2621

2722
switch (propertyType) {
2823
case 'string':
@@ -32,17 +27,14 @@ class EditorGenerator {
3227
.val(this.object[key] || '')
3328
.on('change', () => {
3429
this.object[key] = input.val();
35-
});;
36-
37-
// Use jQuery UI datepicker
30+
});
3831
input.datepicker();
3932
} else if (property.enum) {
4033
input = $('<select>')
4134
.addClass('property-editor-input')
4235
.on('change', () => {
4336
this.object[key] = input.val();
4437
});
45-
4638
property.enum.forEach((option) => {
4739
input.append($('<option>').val(option).text(option));
4840
});
@@ -52,7 +44,7 @@ class EditorGenerator {
5244
.val(this.object[key] || '')
5345
.on('change', () => {
5446
this.object[key] = input.val();
55-
});;
47+
});
5648
}
5749
break;
5850

@@ -77,8 +69,113 @@ class EditorGenerator {
7769
});
7870
break;
7971

72+
case 'object': {
73+
const subContainer = $('<div>').addClass('property-editor-object').hide();
74+
const toggleButton = $('<span>')
75+
.text('>')
76+
.addClass('property-editor-toggle')
77+
.on('click', () => {
78+
subContainer.toggle();
79+
toggleButton.text(toggleButton.text() === '>' ? 'v' : '>');
80+
});
81+
82+
const subObject = this.object[key] || {};
83+
const subSchema = property.properties || {};
84+
85+
const subEditor = new EditorGenerator(subObject, subSchema, '');
86+
subEditor.formContainer = subContainer; // Set the container manually
87+
subEditor.generateEditor();
88+
89+
this.object[key] = subObject;
90+
91+
input = $('<div>')
92+
.append(toggleButton, label, subContainer);
93+
break;
94+
}
95+
96+
case 'array': {
97+
const arrayContainer = $('<div>').addClass('property-editor-array');
98+
const arrayItems = this.object[key] || [];
99+
const itemSchema = property.items || {};
100+
101+
const renderArrayItems = () => {
102+
arrayContainer.empty();
103+
104+
arrayItems.forEach((item, index) => {
105+
const itemContainer = $('<div>').addClass('array-item');
106+
const deleteButton = $('<button>')
107+
.text('x')
108+
.addClass('array-item-delete')
109+
.on('click', () => {
110+
arrayItems.splice(index, 1);
111+
renderArrayItems();
112+
});
113+
114+
if (itemSchema.type === 'object' || itemSchema.properties) {
115+
// Handle array of objects
116+
const subEditor = new EditorGenerator(arrayItems[index], itemSchema.properties, '');
117+
subEditor.formContainer = itemContainer; // Set the container manually
118+
subEditor.generateEditor();
119+
} else if (itemSchema.type === 'string') {
120+
// Handle array of strings
121+
const input = $('<input type="text">')
122+
.addClass('property-editor-input')
123+
.val(item || '')
124+
.on('change', () => {
125+
arrayItems[index] = input.val();
126+
});
127+
itemContainer.append(input);
128+
} else if (itemSchema.type === 'number' || itemSchema.type === 'integer') {
129+
// Handle array of numbers
130+
const input = $('<input type="number">')
131+
.addClass('property-editor-input')
132+
.val(item !== undefined ? item : '')
133+
.on('input', () => {
134+
arrayItems[index] = parseFloat(input.val());
135+
});
136+
itemContainer.append(input);
137+
} else {
138+
// Fallback for unsupported item types
139+
itemContainer.append(
140+
$('<label>')
141+
.text('Unsupported item type: ' + (itemSchema.type || 'unknown'))
142+
.addClass('property-editor-label')
143+
);
144+
}
145+
146+
itemContainer.append(deleteButton);
147+
arrayContainer.append(itemContainer);
148+
});
149+
};
150+
151+
const addButton = $('<button>')
152+
.text('Add')
153+
.on('click', () => {
154+
if (itemSchema.type === 'object') {
155+
arrayItems.push({});
156+
} else if (itemSchema.type === 'string') {
157+
arrayItems.push('');
158+
} else if (itemSchema.type === 'number' || itemSchema.type === 'integer') {
159+
arrayItems.push(0); // Default value for numbers
160+
} else {
161+
console.warn('Unsupported item type for addition:', itemSchema.type);
162+
return;
163+
}
164+
renderArrayItems();
165+
});
166+
167+
renderArrayItems();
168+
input = $('<div>')
169+
.append(arrayContainer, addButton);
170+
171+
this.object[key] = arrayItems;
172+
break;
173+
}
174+
80175
default:
81-
input = $('<label>').text('Unsupported type ' + propertyType).addClass('property-editor-label');
176+
input = $('<label>')
177+
.text('Unsupported type ' + propertyType)
178+
.addClass('property-editor-label');
82179
}
83180

84181
const fieldContainer = $('<div>').addClass('property-editor-field');

0 commit comments

Comments
 (0)