Skip to content

Commit 64d0ea9

Browse files
authored
fix: Fixed SearchableSelect valid input behaviour and state handling (#117, RDFA-496)
* fixed searchable select valid input state handling + enumEntry dialog accessDisplayData mismatch * review changes: $state overhead removed * review changes: changed behaviour to display invalid inputs as violations * review changes: returns violation message + fixed code duplication * test changes: fixed ontology dialog not saving * merge conflict: namespace validation now also respects valid IRI inputs
1 parent 7a91471 commit 64d0ea9

21 files changed

Lines changed: 208 additions & 108 deletions

frontend/src/lib/GraphExport.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
ontologyJSON.uuid,
8989
ontologyJSON.namespace,
9090
ontologyJSON.entries,
91+
namespaces,
9192
);
9293
}
9394
});

frontend/src/lib/components/SearchableSelect.svelte

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
label,
2323
placeholder = "",
2424
value,
25-
callOnValidChange = () => {},
25+
callOnChange = () => {},
2626
//accessDisplayData: how an option is displayed
2727
accessDisplayData = value => {
2828
return value;
@@ -41,24 +41,22 @@
4141
buttons = [],
4242
} = $props();
4343
44-
let lastSavedValue = value;
4544
let datalistID = crypto.randomUUID();
4645
4746
function verifyInput() {
4847
if (!value) {
4948
value = null;
50-
callOnValidChange(value);
49+
callOnChange(value);
5150
return;
5251
}
5352
for (let optionObj of optionObjectList) {
5453
if (accessIdentifier(optionObj) === value) {
55-
lastSavedValue = accessDisplayData(optionObj);
56-
value = lastSavedValue;
57-
callOnValidChange(optionObj);
54+
value = accessDisplayData(optionObj);
55+
callOnChange(optionObj);
5856
return;
5957
}
6058
}
61-
value = lastSavedValue;
59+
callOnChange(value);
6260
}
6361
</script>
6462

frontend/src/lib/models/reactive/mapper/map-dto-to-reactive-object.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ import { ReactiveClass } from "$lib/models/reactive/models/reactive-class.svelte
2020
/**
2121
* Maps a class DTO to a ReactiveClass instance
2222
* @param {Object} classDto - The class data transfer object from the API
23-
* @param {Array} classes - Array of existing classes for resolving references
23+
* @param {Array} context - Mixed context data required for resolving references (e.g. classes, namespaces, etc.)
2424
* @param {function} getClassByUuid - A function that returns the class with the given uuid
2525
* @returns {ReactiveClass} The reactive class instance
2626
*/
27-
export function mapClassDtoToReactiveClass(classDto, classes, getClassByUuid) {
27+
export function mapClassDtoToReactiveClass(classDto, context, getClassByUuid) {
2828
let superClass = null;
2929
if (classDto.superClass) {
30-
superClass = classes.find(
30+
superClass = context.classes.find(
3131
cls =>
3232
cls.prefix + cls.label ===
3333
classDto.superClass.prefix + classDto.superClass.label,
@@ -39,7 +39,7 @@ export function mapClassDtoToReactiveClass(classDto, classes, getClassByUuid) {
3939
);
4040
const associations = mapAssociationDtoListToReactiveAssociationList(
4141
classDto.associationPairs,
42-
classes,
42+
context.classes,
4343
);
4444

4545
const enumEntries = mapEnumEntryListToReactiveEnumEntryList(
@@ -57,7 +57,7 @@ export function mapClassDtoToReactiveClass(classDto, classes, getClassByUuid) {
5757
associations,
5858
enumEntries,
5959
getClassByUuid,
60-
classes,
60+
context,
6161
);
6262
}
6363

frontend/src/lib/models/reactive/models/ontology/reactive-ontology.svelte.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,21 @@ import {
2424
} from "$lib/models/reactive/validity-rules/validityFunctions.js";
2525

2626
export class ReactiveOntology {
27-
constructor(uuid = null, namespace = "", entries = []) {
27+
constructor(uuid = null, namespace = "", entries = [], namespaces = []) {
2828
this.uuid = new ReactiveValueWrapper(uuid, isInvalidUuid);
29-
this.namespace = new ReactiveValueWrapper(
30-
namespace,
31-
isInvalidNamespace,
29+
this.namespace = new ReactiveValueWrapper(namespace, namespace =>
30+
isInvalidNamespace(namespace, namespaces),
3231
);
3332
this.entries = new ReactiveObjectsArrayWrapper(
3433
entries,
3534
ReactiveOntologyEntry,
3635
);
3736
}
3837

38+
static empty(namespaces = []) {
39+
return new ReactiveOntology(null, "", [], namespaces);
40+
}
41+
3942
/**
4043
* The UUID of this ontology
4144
* @type {ReactiveValueWrapper<string>}

frontend/src/lib/models/reactive/models/reactive-association.svelte.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { ReactiveValueWrapper } from "$lib/models/reactive/reactive-wrappers/rea
1818
import {
1919
isInvalidMultiplicityLowerBound,
2020
isInvalidMultiplicityUpperBound,
21-
isInvalidNamespace,
2221
isInvalidTarget,
2322
isInvalidUuid,
2423
} from "$lib/models/reactive/validity-rules/validityFunctions.js";
@@ -50,10 +49,7 @@ export class ReactiveAssociation {
5049
// Set top-level properties
5150
this.uuid = new ReactiveValueWrapper(uuid, isInvalidUuid);
5251
this.label = new ReactiveValueWrapper(label);
53-
this.namespace = new ReactiveValueWrapper(
54-
namespace,
55-
isInvalidNamespace,
56-
);
52+
this.namespace = new ReactiveValueWrapper(namespace);
5753
this.domain = new ReactiveValueWrapper(domain, isInvalidUuid);
5854
this.target = new ReactiveValueWrapper(target, isInvalidTarget);
5955
this.multiplicityLowerBound = new ReactiveValueWrapper(
@@ -79,10 +75,7 @@ export class ReactiveAssociation {
7975
this.inverse = {
8076
uuid: new ReactiveValueWrapper(inverseUuid, isInvalidUuid),
8177
label: new ReactiveValueWrapper(inverseLabel),
82-
namespace: new ReactiveValueWrapper(
83-
inverseNamespace,
84-
isInvalidNamespace,
85-
),
78+
namespace: new ReactiveValueWrapper(inverseNamespace),
8679
multiplicityLowerBound: new ReactiveValueWrapper(
8780
inverseLowerBound,
8881
lowerBound =>

frontend/src/lib/models/reactive/models/reactive-attribute.svelte.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ import {
2020
isInvalidLabel,
2121
isInvalidMultiplicityLowerBound,
2222
isInvalidMultiplicityUpperBound,
23-
isInvalidNamespace,
2423
isInvalidUuid,
25-
isInvalidDatatypeUri,
2624
} from "$lib/models/reactive/validity-rules/validityFunctions.js";
2725

2826
export class ReactiveAttribute {
@@ -39,10 +37,7 @@ export class ReactiveAttribute {
3937
} = {}) {
4038
this.uuid = new ReactiveValueWrapper(uuid, isInvalidUuid);
4139
this.label = new ReactiveValueWrapper(label, isInvalidLabel);
42-
this.namespace = new ReactiveValueWrapper(
43-
namespace,
44-
isInvalidNamespace,
45-
);
40+
this.namespace = new ReactiveValueWrapper(namespace);
4641
this.multiplicityLowerBound = new ReactiveValueWrapper(
4742
multiplicityLowerBound,
4843
lowerBound =>
@@ -59,10 +54,7 @@ export class ReactiveAttribute {
5954
this.multiplicityLowerBound.value,
6055
),
6156
);
62-
this.datatype = new ReactiveValueWrapper(
63-
datatype,
64-
isInvalidDatatypeUri,
65-
);
57+
this.datatype = new ReactiveValueWrapper(datatype);
6658
this.comment = new ReactiveValueWrapper(comment);
6759
this.fixedValue = new ReactiveValueWrapper(fixedValue);
6860
this.defaultValue = new ReactiveValueWrapper(defaultValue);

frontend/src/lib/models/reactive/models/reactive-class.svelte.js

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import {
2929
isInvalidNamespace,
3030
isInvalidStereotype,
3131
isInvalidUuid,
32+
isInvalidPackage,
33+
isInvalidSuperClass,
34+
isInvalidDatatypeUri,
3235
} from "$lib/models/reactive/validity-rules/validityFunctions.js";
3336

3437
function initializeStereotypeViolationChecks(stereotype, stereotypesArray) {
@@ -37,23 +40,57 @@ function initializeStereotypeViolationChecks(stereotype, stereotypesArray) {
3740
);
3841
}
3942

43+
function initializeAttributeViolationChecks(
44+
attribute,
45+
attributesArray,
46+
namespaces,
47+
datatypes,
48+
) {
49+
attribute.label.violationChecks.push(label =>
50+
hasUniqueIRI(label, attribute.namespace.value, attributesArray),
51+
);
52+
53+
attribute.namespace.violationChecks.push(namespace =>
54+
isInvalidNamespace(namespace, namespaces),
55+
);
56+
57+
attribute.datatype.violationChecks.push(datatype =>
58+
isInvalidDatatypeUri(datatype, datatypes),
59+
);
60+
}
61+
4062
function initializeAssociationViolationChecks(
4163
association,
4264
associationsArray,
4365
getClassByUuid,
66+
compareNamespaces,
4467
) {
4568
association.label.violationChecks.push(() =>
4669
isInvalidAssociationLabel(association, associationsArray),
4770
);
4871
association.inverse.label.violationChecks.push(() =>
4972
isInvalidInverseAssociationLabel(association, getClassByUuid),
5073
);
74+
association.namespace.violationChecks.push(namespace =>
75+
isInvalidNamespace(namespace, compareNamespaces),
76+
);
77+
association.inverse.namespace.violationChecks.push(namespace =>
78+
isInvalidNamespace(namespace, compareNamespaces),
79+
);
5180
}
5281

53-
function initializeUniqueLabelChecks(reactiveObject, enumEntriesArray) {
54-
reactiveObject.label.violationChecks.push(label =>
82+
function initializeEnumEntryViolationChecks(
83+
enumEntry,
84+
enumEntriesArray,
85+
namespaces,
86+
) {
87+
enumEntry.label.violationChecks.push(label =>
5588
hasUniqueLabel(label, enumEntriesArray),
5689
);
90+
91+
enumEntry.namespace.violationChecks.push(namespace =>
92+
isInvalidNamespace(namespace, namespaces),
93+
);
5794
}
5895

5996
export class ReactiveClass {
@@ -69,20 +106,22 @@ export class ReactiveClass {
69106
associations = [],
70107
enumEntries = [],
71108
getClassByUuid = () => undefined,
72-
compareClasses = [],
109+
context = [],
73110
) {
74-
compareClasses = compareClasses.filter(c => c.uuid !== uuid);
111+
let compareClasses = context.classes.filter(c => c.uuid !== uuid);
75112
this.uuid = new ReactiveValueWrapper(uuid, isInvalidUuid);
76-
this.namespace = new ReactiveValueWrapper(
77-
namespace,
78-
isInvalidNamespace,
113+
this.namespace = new ReactiveValueWrapper(namespace, namespace =>
114+
isInvalidNamespace(namespace, context.namespaces),
79115
);
80116
this.label = new ReactiveValueWrapper(label, label =>
81117
isInvalidClassLabel(label, this.namespace.value, compareClasses),
82118
);
83119

84-
this.package = new ReactiveValueWrapper(pack);
85-
this.superClass = new ReactiveValueWrapper(superClass);
120+
this.package = new ReactiveValueWrapper(pack, isInvalidPackage);
121+
this.superClass = new ReactiveValueWrapper(
122+
superClass,
123+
isInvalidSuperClass,
124+
);
86125
this.comment = new ReactiveValueWrapper(comment);
87126
this.stereotypes = new ReactiveObjectsArrayWrapper(
88127
stereotypes,
@@ -92,15 +131,13 @@ export class ReactiveClass {
92131
this.attributes = new ReactiveObjectsArrayWrapper(
93132
attributes,
94133
ReactiveAttribute,
95-
(reactiveObject, entriesArray) => {
96-
reactiveObject.label.violationChecks.push(label =>
97-
hasUniqueIRI(
98-
label,
99-
reactiveObject.namespace.value,
100-
entriesArray,
101-
),
102-
);
103-
},
134+
(attribute, attributesArray) =>
135+
initializeAttributeViolationChecks(
136+
attribute,
137+
attributesArray,
138+
context.namespaces,
139+
context.datatypes,
140+
),
104141
);
105142
this.associations = new ReactiveObjectsArrayWrapper(
106143
associations,
@@ -110,12 +147,18 @@ export class ReactiveClass {
110147
association,
111148
associationsArray,
112149
getClassByUuid,
150+
context.namespaces,
113151
),
114152
);
115153
this.enumEntries = new ReactiveObjectsArrayWrapper(
116154
enumEntries,
117155
ReactiveEnumEntry,
118-
initializeUniqueLabelChecks,
156+
(enumEntry, enumEntriesArray) =>
157+
initializeEnumEntryViolationChecks(
158+
enumEntry,
159+
enumEntriesArray,
160+
context.namespaces,
161+
),
119162
);
120163
}
121164

frontend/src/lib/models/reactive/models/reactive-enum-entry.svelte.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import { ReactiveValueWrapper } from "$lib/models/reactive/reactive-wrappers/reactive-value-wrapper.svelte.js";
1919
import {
2020
isInvalidLabel,
21-
isInvalidNamespace,
2221
isInvalidUuid,
2322
} from "$lib/models/reactive/validity-rules/validityFunctions.js";
2423

@@ -31,10 +30,7 @@ export class ReactiveEnumEntry {
3130
stereotype = null,
3231
} = {}) {
3332
this.uuid = new ReactiveValueWrapper(uuid, isInvalidUuid);
34-
this.namespace = new ReactiveValueWrapper(
35-
namespace,
36-
isInvalidNamespace,
37-
);
33+
this.namespace = new ReactiveValueWrapper(namespace);
3834
this.label = new ReactiveValueWrapper(label, isInvalidLabel);
3935
this.comment = new ReactiveValueWrapper(comment);
4036
this.stereotype = new ReactiveValueWrapper(stereotype);

frontend/src/lib/models/reactive/models/reactive-package.svelte.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ export class ReactivePackage {
2828
label = "",
2929
namespace = "",
3030
comment = null,
31+
compareNamespaces = [],
3132
} = {}) {
3233
this.uuid = new ReactiveValueWrapper(uuid, isInvalidUuid);
3334
this.label = new ReactiveValueWrapper(label, isInvalidLabel);
34-
this.namespace = new ReactiveValueWrapper(
35-
namespace,
36-
isInvalidNamespace,
35+
this.namespace = new ReactiveValueWrapper(namespace, namespace =>
36+
isInvalidNamespace(namespace, compareNamespaces),
3737
);
3838
this.comment = new ReactiveValueWrapper(comment);
3939
}

0 commit comments

Comments
 (0)