Skip to content

Commit f59dd6b

Browse files
authored
Feature/schema diagram adjust node title logic (#722)
* extract string to identifier utility * update test to include missing case * update reference changing code to fix missing case * adjust code to extracted utils * create more suitable identifier for extracted elements * make identifiers shown in schema diagram more consistent: use title/generated name only when no other suitable name exists. When the property is editable/extracted, then always show real name * update tests to new schema diagram logic * apply formatting changes --------- Co-authored-by: Logende <[email protected]>
1 parent d8c90fc commit f59dd6b

16 files changed

Lines changed: 316 additions & 80 deletions

meta_configurator/src/components/dialogs/csvimport/csvImportTypes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import {ref, type Ref} from 'vue';
22
import {jsonPointerToPathTyped} from '@/utility/pathUtils';
33
import type {Path} from '@/utility/path';
4-
import {userStringToIdentifier} from '@/components/dialogs/csvimport/importCsvUtils';
4+
import {stringToIdentifier} from '@/utility/stringToIdentifier';
55

66
export class CsvImportColumnMappingData {
77
constructor(public index: number, public name: string, pathBeforeRowIndex: Ref<string>) {
88
this.pathBeforeRowIndex = pathBeforeRowIndex;
9-
this.pathAfterRowIndex = ref(userStringToIdentifier(this.name, false));
9+
this.pathAfterRowIndex = ref(stringToIdentifier(this.name, false));
1010
this.titleInSchema = ref(this.name);
1111
}
1212

meta_configurator/src/components/dialogs/csvimport/importCsvUtils.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ import {
1616
import {type CsvError, parse} from 'csv-parse/browser/esm';
1717
import type {JsonSchemaType} from '@/schema/jsonSchemaType';
1818
import {identifyArraysInJson} from '@/utility/arrayPathUtils';
19+
import {stringToIdentifier} from '@/utility/stringToIdentifier';
1920

2021
export function requestUploadFileToRef(resultString: Ref<string>, resultTableName: Ref<string>) {
2122
const {open, onChange} = useFileDialog();
2223

2324
onChange((files: FileList | null) => {
2425
if (files && files.length > 0) {
25-
resultTableName.value = userStringToIdentifier(files[0].name, true); // Get the name of the first file
26+
resultTableName.value = stringToIdentifier(files[0].name, true); // Get the name of the first file
2627
readFileContentToStringRef(files, resultString);
2728
}
2829
});
@@ -138,19 +139,6 @@ export const decimalSeparatorOptions: LabelledValue[] = [
138139
},
139140
];
140141

141-
export function userStringToIdentifier(input: string, cutExtension: boolean = false): string {
142-
if (cutExtension) {
143-
input = input.replace(/\.[^/.]+$/, '');
144-
}
145-
146-
// remove special characters, trim whitespaces outside and replace whitespaces inside with underscores. Also transform to lower case.
147-
return input
148-
.replace(/[^a-zA-Z0-9 ]/g, '')
149-
.trim()
150-
.replace(/\s/g, '_')
151-
.toLowerCase();
152-
}
153-
154142
// note that this function does not look for a table within a table
155143
export function detectPossibleTablesInJson(json: any, path: Path = []): Path[] {
156144
return identifyArraysInJson(json, path, false, true);

meta_configurator/src/components/panels/schema-diagram/SchemaEnumNode.vue

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import InputText from 'primevue/inputtext';
1111
import Button from 'primevue/button';
1212
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome';
1313
import {isSubSchemaDefinedInDefinitions} from '@/schema/schemaReadingUtils';
14+
import {getObjectDisplayName} from '../../../schema/graph-representation/schemaGraphConstructor';
1415
1516
const props = defineProps<{
1617
data: SchemaEnumNodeData;
@@ -30,7 +31,7 @@ const emit = defineEmits<{
3031
(e: 'delete_element', objectData: SchemaElementData): void;
3132
}>();
3233
33-
const enumName = ref(props.data.name);
34+
const enumName = ref(props.data.name || '');
3435
3536
function clickedNode() {
3637
emit('select_element', props.data.absolutePath);
@@ -53,6 +54,11 @@ function updateEnumName() {
5354
if (newName.length == 0) {
5455
return;
5556
}
57+
if (!props.data.name) {
58+
throw new Error(
59+
'Enum name is not defined. This should not happen. Only enum with a name should allow edits of the name. Please report this issue.'
60+
);
61+
}
5662
emit('update_enum_name', props.data, props.data.name, newName);
5763
}
5864
@@ -89,7 +95,14 @@ function addEnumItem() {
8995

9096
<div v-if="!isEnumEditable() || !isDefinedInDefinitions()">
9197
<b>
92-
{{ props.data.name }}
98+
{{
99+
getObjectDisplayName(
100+
props.data.name,
101+
props.data.title,
102+
props.data.fallbackDisplayName,
103+
isDefinedInDefinitions()
104+
)
105+
}}
93106
</b>
94107

95108
<Button

meta_configurator/src/components/panels/schema-diagram/SchemaObjectNode.vue

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {AttributeTypeChoice} from '@/schema/graph-representation/typeUtils'
1414
import Button from 'primevue/button';
1515
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome';
1616
import {isSubSchemaDefinedInDefinitions} from '@/schema/schemaReadingUtils';
17+
import {getObjectDisplayName} from '@/schema/graph-representation/schemaGraphConstructor';
1718
1819
const props = defineProps<{
1920
data: SchemaObjectNodeData;
@@ -48,7 +49,8 @@ const emit = defineEmits<{
4849
(e: 'add_attribute', objectData: SchemaObjectNodeData): void;
4950
}>();
5051
51-
const objectName = ref(props.data.name);
52+
const objectName = ref(props.data.name || '');
53+
5254
const settings = useSettings();
5355
5456
function isObjectEditable() {
@@ -88,6 +90,11 @@ function updateObjectName() {
8890
if (newName.length == 0) {
8991
return;
9092
}
93+
if (!props.data.name) {
94+
throw new Error(
95+
'Object name is not defined. This should not happen. Only objects with a name should allow edits of the name. Please report this issue.'
96+
);
97+
}
9198
emit('update_object_name', props.data, props.data.name, newName);
9299
}
93100
function updateAttributeName(
@@ -147,7 +154,14 @@ function isAttributeHighlighted() {
147154

148155
<div v-if="!isNameEditable() || !isDefinedInDefinitions()">
149156
<b>
150-
{{ props.data.name }}
157+
{{
158+
getObjectDisplayName(
159+
props.data.name,
160+
props.data.title,
161+
props.data.fallbackDisplayName,
162+
isDefinedInDefinitions()
163+
)
164+
}}
151165
</b>
152166
<Button
153167
v-if="isExtractable()"

meta_configurator/src/components/panels/schema-diagram/VueFlowPanel.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {findAvailableSchemaId} from '@/schema/schemaReadingUtils';
3838
import {
3939
addSchemaEnum,
4040
addSchemaObject,
41+
createIdentifierForExtractedElement,
4142
extractInlinedSchemaElement,
4243
} from '@/schema/schemaManipulationUtils';
4344
import {schemaGraphToVueFlowGraph} from '@/components/panels/schema-diagram/schemaDiagramTypes';
@@ -274,10 +275,15 @@ function updateObjectOrEnumName(objectData: SchemaElementData, oldName: string,
274275
}
275276
276277
function extractInlinedElement(elementData: SchemaObjectNodeData | SchemaEnumNodeData) {
278+
const newIdentifier = createIdentifierForExtractedElement(
279+
elementData.name,
280+
elementData.title,
281+
elementData.fallbackDisplayName
282+
);
277283
const newElementId = extractInlinedSchemaElement(
278284
elementData.absolutePath,
279285
schemaData,
280-
elementData.name
286+
newIdentifier
281287
);
282288
elementData.absolutePath = newElementId;
283289
selectElement(newElementId);

meta_configurator/src/schema/graph-representation/__tests__/schemaGraphConstructorArrays.test.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {EdgeType, SchemaGraph, SchemaObjectNodeData} from '../schemaGraphTypes';
44
import {
55
generateAttributeEdges,
66
generateObjectAttributes,
7-
generateObjectTitle,
7+
generateObjectFallbackDisplayName,
88
identifyAllObjects,
99
isSchemaThatDeservesANode,
1010
} from '../schemaGraphConstructor';
@@ -123,21 +123,25 @@ describe('test schema graph constructor with objects and attributes, without adv
123123
expect(rootNode.attributes.length).toEqual(6);
124124

125125
expect(rootNode.attributes[0].name).toEqual('propertyArrayToSimple');
126+
expect(rootNode.attributes[0].title).toEqual(undefined);
126127
expect(rootNode.attributes[0].absolutePath).toEqual(['properties', 'propertyArrayToSimple']);
127128
expect(rootNode.attributes[0].deprecated).toBeFalsy();
128129
expect(rootNode.attributes[0].required).toBeFalsy();
129130

130131
expect(rootNode.attributes[1].name).toEqual('propertyArrayToComplex');
132+
expect(rootNode.attributes[1].title).toEqual(undefined);
131133
expect(rootNode.attributes[1].absolutePath).toEqual(['properties', 'propertyArrayToComplex']);
132134
expect(rootNode.attributes[1].deprecated).toBeFalsy();
133135
expect(rootNode.attributes[1].required).toBeFalsy();
134136

135137
expect(rootNode.attributes[2].name).toEqual('propertyArrayToRefSimple');
138+
expect(rootNode.attributes[2].title).toEqual(undefined);
136139
expect(rootNode.attributes[2].absolutePath).toEqual(['properties', 'propertyArrayToRefSimple']);
137140
expect(rootNode.attributes[2].deprecated).toBeFalsy();
138141
expect(rootNode.attributes[2].required).toBeFalsy();
139142

140143
expect(rootNode.attributes[3].name).toEqual('propertyArrayToRefComplexWithTitle');
144+
expect(rootNode.attributes[3].title).toEqual(undefined);
141145
expect(rootNode.attributes[3].absolutePath).toEqual([
142146
'properties',
143147
'propertyArrayToRefComplexWithTitle',
@@ -146,11 +150,13 @@ describe('test schema graph constructor with objects and attributes, without adv
146150
expect(rootNode.attributes[3].required).toBeFalsy();
147151

148152
expect(rootNode.attributes[4].name).toEqual('propertyRefToArraySimple');
153+
expect(rootNode.attributes[4].title).toEqual(undefined);
149154
expect(rootNode.attributes[4].absolutePath).toEqual(['properties', 'propertyRefToArraySimple']);
150155
expect(rootNode.attributes[4].deprecated).toBeFalsy();
151156
expect(rootNode.attributes[4].required).toBeFalsy();
152157

153158
expect(rootNode.attributes[5].name).toEqual('propertyRefToArrayComplex');
159+
expect(rootNode.attributes[5].title).toEqual(undefined);
154160
expect(rootNode.attributes[5].absolutePath).toEqual([
155161
'properties',
156162
'propertyRefToArrayComplex',
@@ -178,7 +184,7 @@ describe('test schema graph constructor with objects and attributes, without adv
178184

179185
const attrPropArrayRefComplexWithTitle = rootNode.attributes[3];
180186
// array to ref of complex type
181-
expect(attrPropArrayRefComplexWithTitle.typeDescription).toEqual('person[]');
187+
expect(attrPropArrayRefComplexWithTitle.typeDescription).toEqual('PersonTitle[]');
182188

183189
const attrPropRefToArraySimple = rootNode.attributes[4];
184190
// reference to array of booleans
@@ -189,7 +195,7 @@ describe('test schema graph constructor with objects and attributes, without adv
189195
expect(attrPropRefToArrayComplex.typeDescription).toEqual('arrayObjectProperty');
190196
});
191197

192-
it('generate object title', () => {
198+
it('generate object fallback display name', () => {
193199
const objectNodeCount = Array.from(defs.values()).filter(node =>
194200
isSchemaThatDeservesANode(node.schema)
195201
).length;
@@ -198,7 +204,7 @@ describe('test schema graph constructor with objects and attributes, without adv
198204
// We care about titles of nodes that define objects only
199205
const rootNode = defs.get('')!;
200206
expect(
201-
generateObjectTitle(
207+
generateObjectFallbackDisplayName(
202208
rootNode.absolutePath,
203209
rootNode.hasUserDefinedName,
204210
rootNode.schema,
@@ -208,7 +214,7 @@ describe('test schema graph constructor with objects and attributes, without adv
208214

209215
const propArrayComplexItem = defs.get('properties.propertyArrayToComplex.items')!;
210216
expect(
211-
generateObjectTitle(
217+
generateObjectFallbackDisplayName(
212218
propArrayComplexItem.absolutePath,
213219
propArrayComplexItem.hasUserDefinedName,
214220
propArrayComplexItem.schema,
@@ -218,7 +224,7 @@ describe('test schema graph constructor with objects and attributes, without adv
218224

219225
const defsArrayPropItem = defs.get('$defs.arrayObjectProperty.items')!;
220226
expect(
221-
generateObjectTitle(
227+
generateObjectFallbackDisplayName(
222228
defsArrayPropItem.absolutePath,
223229
defsArrayPropItem.hasUserDefinedName,
224230
defsArrayPropItem.schema,
@@ -228,7 +234,7 @@ describe('test schema graph constructor with objects and attributes, without adv
228234

229235
const defsArrayObjectPropItem = defs.get('$defs.arrayObjectProperty.items')!;
230236
expect(
231-
generateObjectTitle(
237+
generateObjectFallbackDisplayName(
232238
defsArrayObjectPropItem.absolutePath,
233239
defsArrayObjectPropItem.hasUserDefinedName,
234240
defsArrayObjectPropItem.schema,
@@ -238,7 +244,12 @@ describe('test schema graph constructor with objects and attributes, without adv
238244

239245
const person = defs.get('$defs.person')!;
240246
expect(
241-
generateObjectTitle(person.absolutePath, person.hasUserDefinedName, person.schema, schema)
247+
generateObjectFallbackDisplayName(
248+
person.absolutePath,
249+
person.hasUserDefinedName,
250+
person.schema,
251+
schema
252+
)
242253
).toEqual('person');
243254
});
244255

meta_configurator/src/schema/graph-representation/__tests__/schemaGraphConstructorBasicFeatures.test.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {EdgeType, SchemaGraph, SchemaObjectNodeData} from '../schemaGraphTypes';
55
import {
66
generateAttributeEdges,
77
generateObjectAttributes,
8-
generateObjectTitle,
8+
generateObjectFallbackDisplayName,
99
identifyObjects,
1010
isSchemaThatDeservesANode,
1111
} from '../schemaGraphConstructor';
@@ -95,31 +95,37 @@ describe('test schema graph constructor with objects and attributes, without adv
9595
rootNode.attributes = generateObjectAttributes(rootNode.absolutePath, rootNode.schema, defs);
9696
expect(rootNode.attributes.length).toEqual(6);
9797
expect(rootNode.attributes[0].name).toEqual('propertySimple');
98+
expect(rootNode.attributes[0].title).toEqual(undefined);
9899
expect(rootNode.attributes[0].absolutePath).toEqual(['properties', 'propertySimple']);
99100
expect(rootNode.attributes[0].deprecated).toBeTruthy();
100101
expect(rootNode.attributes[0].required).toBeFalsy();
101102

102103
expect(rootNode.attributes[1].name).toEqual('propertyObject');
104+
expect(rootNode.attributes[1].title).toEqual(undefined);
103105
expect(rootNode.attributes[1].absolutePath).toEqual(['properties', 'propertyObject']);
104106
expect(rootNode.attributes[1].deprecated).toBeFalsy();
105107
expect(rootNode.attributes[1].required).toBeTruthy();
106108

107109
expect(rootNode.attributes[2].name).toEqual('propertyObjectWithTitle');
110+
expect(rootNode.attributes[2].title).toEqual(undefined);
108111
expect(rootNode.attributes[2].absolutePath).toEqual(['properties', 'propertyObjectWithTitle']);
109112
expect(rootNode.attributes[2].deprecated).toBeFalsy();
110113
expect(rootNode.attributes[2].required).toBeFalsy();
111114

112115
expect(rootNode.attributes[3].name).toEqual('propertyRefToSimple');
116+
expect(rootNode.attributes[3].title).toEqual(undefined);
113117
expect(rootNode.attributes[3].absolutePath).toEqual(['properties', 'propertyRefToSimple']);
114118
expect(rootNode.attributes[3].deprecated).toBeFalsy();
115119
expect(rootNode.attributes[3].required).toBeFalsy();
116120

117121
expect(rootNode.attributes[4].name).toEqual('propertyRefToComplex');
122+
expect(rootNode.attributes[4].title).toEqual(undefined);
118123
expect(rootNode.attributes[4].absolutePath).toEqual(['properties', 'propertyRefToComplex']);
119124
expect(rootNode.attributes[4].deprecated).toBeFalsy();
120125
expect(rootNode.attributes[4].required).toBeFalsy();
121126

122127
expect(rootNode.attributes[5].name).toEqual('propertyRefToNestedObject');
128+
expect(rootNode.attributes[5].title).toEqual(undefined);
123129
expect(rootNode.attributes[5].absolutePath).toEqual([
124130
'properties',
125131
'propertyRefToNestedObject',
@@ -140,7 +146,6 @@ describe('test schema graph constructor with objects and attributes, without adv
140146
expect(attrPropComplex.typeDescription).toEqual('propertyObject');
141147

142148
const attrPropComplexWithTitle = rootNode.attributes[2];
143-
// if the object has a title, we use it. Otherwise, we use the attribute name in the schema
144149
expect(attrPropComplexWithTitle.typeDescription).toEqual('propertyObjectWithTitle');
145150

146151
const attrPropRefSimple = rootNode.attributes[3];
@@ -165,7 +170,7 @@ describe('test schema graph constructor with objects and attributes, without adv
165170
// We care about titles of nodes that define objects only
166171
const rootNode = defs.get('')!;
167172
expect(
168-
generateObjectTitle(
173+
generateObjectFallbackDisplayName(
169174
rootNode.absolutePath,
170175
rootNode.hasUserDefinedName,
171176
rootNode.schema,
@@ -175,7 +180,7 @@ describe('test schema graph constructor with objects and attributes, without adv
175180

176181
const propComplex = defs.get('properties.propertyObject')!;
177182
expect(
178-
generateObjectTitle(
183+
generateObjectFallbackDisplayName(
179184
propComplex.absolutePath,
180185
propComplex.hasUserDefinedName,
181186
propComplex.schema,
@@ -185,7 +190,7 @@ describe('test schema graph constructor with objects and attributes, without adv
185190

186191
const propComplexWithTitle = defs.get('properties.propertyObjectWithTitle')!;
187192
expect(
188-
generateObjectTitle(
193+
generateObjectFallbackDisplayName(
189194
propComplexWithTitle.absolutePath,
190195
propComplexWithTitle.hasUserDefinedName,
191196
propComplexWithTitle.schema,
@@ -195,12 +200,17 @@ describe('test schema graph constructor with objects and attributes, without adv
195200

196201
const person = defs.get('$defs.person')!;
197202
expect(
198-
generateObjectTitle(person.absolutePath, person.hasUserDefinedName, person.schema, schema)
203+
generateObjectFallbackDisplayName(
204+
person.absolutePath,
205+
person.hasUserDefinedName,
206+
person.schema,
207+
schema
208+
)
199209
).toEqual('person');
200210

201211
const personAddress = defs.get('$defs.person.properties.address')!;
202212
expect(
203-
generateObjectTitle(
213+
generateObjectFallbackDisplayName(
204214
personAddress.absolutePath,
205215
personAddress.hasUserDefinedName,
206216
personAddress.schema,

0 commit comments

Comments
 (0)