Skip to content

Commit

Permalink
Handle parameters with multiple schemas of similar types correctly, h…
Browse files Browse the repository at this point in the history
…andle `additionalProperties: false` correctly in ObjectEditor
  • Loading branch information
m-mohr committed May 25, 2024
1 parent f3bb70e commit 2a88c4b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 24 deletions.
47 changes: 32 additions & 15 deletions src/components/ParameterDataTypes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
<select name="dataType" :value="selectedType" @input="onSelectType" :disabled="!editable">
<template v-if="selectableTypes.length > 1">
<optgroup v-for="group in selectableTypes" :key="group.name" :label="group.name">
<option v-for="type in group.types" :key="type.dataType()" :value="type.dataType()">{{ type | dataTypeTitle }}</option>
<option v-for="(type, key) in group.types" :key="key" :value="key">{{ type | dataTypeTitle }}</option>
</optgroup>
</template>
<template v-else>
<option v-for="type in selectableTypes[0].types" :key="type.dataType()" :value="type.dataType()">{{ type | dataTypeTitle }}</option>
<option v-for="(type, key) in selectableTypes[0].types" :key="key" :value="key">{{ type | dataTypeTitle }}</option>
</template>
</select>
</div>
Expand Down Expand Up @@ -225,7 +225,7 @@ export default {
}
else {
for(let type of this.parameter.schemas) {
let name = type.dataType();
const name = this.getUniqueKey(allowed, type.dataType());
allowed[name] = type;
}
}
Expand All @@ -238,8 +238,8 @@ export default {
if (s.any === false) {
continue;
}
let name = s.subtype || s.type;
let schema = Object.assign({}, API_TYPES[name], s);
const name = s.subtype || s.type;
const schema = Object.assign({}, API_TYPES[name], s);
map[name] = new ProcessDataType(schema, this.parameter);
}
return map;
Expand All @@ -249,12 +249,10 @@ export default {
for(let type in this.allowedTypes) {
let schema = this.allowedTypes[type];
let group = schema.group();
if (!Array.isArray(grouped[group])) {
grouped[group] = [schema];
}
else {
grouped[group].push(schema);
if (!Utils.isObject(grouped[group])) {
grouped[group] = {};
}
grouped[group][type] = schema;
}
let groups = TYPE_GROUPS
.map(group => ({
Expand All @@ -263,6 +261,16 @@ export default {
}))
.filter(group => group.types.length !== 0);
return groups;
},
detectableTypes() {
const detectable = {};
for(let key in this.allowedTypes) {
let type = this.allowedTypes[key];
if (!type.schema.noAutoDetect) {
detectable[key] = type;
}
}
return detectable;
}
},
watch: {
Expand Down Expand Up @@ -290,6 +298,15 @@ export default {
}
},
methods: {
getUniqueKey(obj, basename) {
let name = basename;
let index = 2;
while (obj[name]) {
name = basename + String(index);
index++;
}
return name;
},
async isValueInvalid(value, schema) {
let schema2 = Utils.deepClone(schema);
// Allow from_node and from_parameter in values, see https://github.com/Open-EO/openeo-web-editor/issues/179
Expand All @@ -312,13 +329,14 @@ export default {
* @return {string[]} - Returns matching indices (as strings!).
*/
async getTypeForValue(types, value) {
var validTypes = [];
for(var type of types) {
const validTypes = [];
for(let key in types) {
let type = types[key];
try {
if (await this.isValueInvalid(value, type.schema)) {
continue;
}
validTypes.push(type.dataType());
validTypes.push(key);
} catch (error) {}
}
return validTypes;
Expand All @@ -342,8 +360,7 @@ export default {
}
}
else {
let detectableTypes = Object.values(this.allowedTypes).filter(type => !type.schema.noAutoDetect);
let types = await this.getTypeForValue(detectableTypes, this.state);
let types = await this.getTypeForValue(this.detectableTypes, this.state);
if (types.length === 0) {
await this.setSelected('json');
}
Expand Down
13 changes: 6 additions & 7 deletions src/components/datatypes/FileFormatOptionsEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import ParameterDataTypes from '../ParameterDataTypes.vue';
import Utils from '../../utils.js';
import Description from '@openeo/vue-components/components/Description.vue';
import { ProcessParameter } from '@openeo/js-commons';
import { ProcessParameter, ProcessDataType } from '@openeo/js-commons';
export default {
name: 'FileFormatOptionsEditor',
Expand Down Expand Up @@ -69,16 +69,15 @@ export default {
schema.examples = [schema.example];
delete schema.example;
}
parameters.push(new ProcessParameter({
const parameter = new ProcessParameter({
name: name,
description: schema.description,
schema: [
{subtype: 'undefined', not: {}},
schema
],
schema,
optional: !schema.required,
default: schema.default
}));
});
parameter.schemas.push(new ProcessDataType({subtype: 'undefined', not: {}}, parameter));
parameters.push(parameter);
}
return parameters;
},
Expand Down
7 changes: 5 additions & 2 deletions src/components/datatypes/ObjectEditor.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<div :class="{editor: true, array: !isObject, object: isObject}">
<div class="buttons">
<button type="button" class="addBtn" v-if="editable" :disabled="count >= maxCount" @click="add()"><i class="fas fa-plus"></i> Add</button>
<FullscreenButton :element="() => this.$el" />
<button type="button" class="addBtn" v-if="editable && additionalProperties" :disabled="count >= maxCount" @click="add()"><i class="fas fa-plus"></i> Add</button>
<FullscreenButton v-if="additionalProperties" :element="() => this.$el" />
</div>
<div v-if="!elements.length" class="empty description">
<i class="fas fa-info-circle"></i>
Expand Down Expand Up @@ -77,6 +77,9 @@ export default {
minCount() {
return (this.isObject ? this.schema.schema.minProperties : this.schema.schema.minItems) || 0;
},
additionalProperties() {
return this.isObject && this.schema.schema.additionalProperties !== false;
},
prefill() {
let schema = this.schema.schema;
if (this.isObject && Utils.isObject(schema.properties)) {
Expand Down

0 comments on commit 2a88c4b

Please sign in to comment.