Skip to content

Commit 2f369b1

Browse files
committed
Namespace support + support to open more types of processes (and parameters) by default #178
1 parent 119c153 commit 2f369b1

16 files changed

+230
-166
lines changed

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ You can also build the files yourself and deploy them to any web host:
2323
You can use some query parameters to set initial state to the Editor.
2424

2525
* `server`: Set a openEO back-end to connect to by default, e.g. `https://earthengine.openeo.org`
26-
* `discover`: If you want to skip authentication and just show the capabiltiies of the back-end, simply set to `1`
27-
* `process`: Loads a process from a URL and shows it in the Model Builder.
26+
* `discover`: If you want to skip authentication and just show the capabiltiies of the back-end, simply set to `1`.
27+
* `process`: Loads a process from a URL and shows it in the Model Builder. You can also pass a single process name with an optional namespace to the parameter (format: `process@namespace`) to simply add a single process node for that process by default.
28+
* `namespaces`: Loads a additional process namespaces. Multiple namespaces can be separated by a comma (e.g. `vector,sar`).
29+
* `edit-node` Opens the parameter editor for a single process node on start-up. Must have the `process` parameter being set, otherwise will be ignored. You can set two types of values:
30+
* `1`: If only a single node is being added, opens this node without explicitly naming it.
31+
* Otherwise, the value must correspond to the node identifier without `#` at the beginning.
2832

2933
Example: <https://editor.openeo.org?server=https://earthengine.openeo.org&discover=1&process=https://raw.githubusercontent.com/Open-EO/openeo-earthengine-driver/master/tests/data/sample-processgraph.json>
3034

config.js

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ export default {
3434
'wmts'
3535
],
3636

37+
// Additional process namespaces to load by default
38+
processNamespaces: [],
39+
3740
// Key is the OIDC provider id, value is the client ID
3841
oidcClientIds: {},
3942

src/Page.vue

+10-26
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ import EventBusMixin from './components/EventBusMixin.vue';
2020
import Utils from './utils';
2121
import ConnectForm from './components/ConnectForm.vue';
2222
import axios from 'axios';
23-
import { UserProcess } from '@openeo/js-client';
24-
import { ProcessGraph } from '@openeo/js-processgraphs';
2523
2624
// Making axios available globally for the OpenEO JS client
2725
window.axios = axios;
@@ -57,6 +55,10 @@ export default {
5755
};
5856
},
5957
created() {
58+
this.addProcessNamespacesToRequest(Utils.param('namespaces'));
59+
this.setInitialProcess(Utils.param('process'));
60+
this.setInitialNode(Utils.param('edit-node'));
61+
6062
if (Utils.param('discover')) {
6163
this.skipLogin = true;
6264
}
@@ -100,12 +102,11 @@ export default {
100102
...Utils.mapState(['activeRequests']),
101103
...Utils.mapGetters(['isDiscovered']),
102104
...Utils.mapState('editor', ['hightestModalZIndex']),
103-
...Utils.mapGetters('userProcesses', {getProcessById: 'getAllById'})
104105
},
105106
methods: {
106-
...Utils.mapActions(['describeAccount', 'describeCollection']),
107-
...Utils.mapMutations(['startActiveRequest', 'endActiveRequest']),
108-
...Utils.mapActions('userProcesses', {readUserProcess: 'read'}),
107+
...Utils.mapActions(['describeAccount', 'describeCollection', 'loadProcess']),
108+
...Utils.mapMutations(['startActiveRequest', 'endActiveRequest', 'addProcessNamespacesToRequest']),
109+
...Utils.mapMutations('editor', ['setInitialProcess', 'setInitialNode']),
109110
setTitle(subtitle) {
110111
var title = `${this.$config.serviceName} ${this.$config.appName}`;
111112
if (subtitle) {
@@ -144,26 +145,9 @@ export default {
144145
}
145146
},
146147
async showProcess(process) {
147-
// Convert process id into process
148-
if (typeof process === 'string') {
149-
process = this.getProcessById(process);
150-
}
151-
152-
if (!process.native) {
153-
try {
154-
let udp = await this.readUserProcess({data: process});
155-
process = udp.toJSON();
156-
} catch(error) {
157-
Utils.exception(this, error, "Load Process Error: " + process.id);
158-
return;
159-
}
160-
}
161-
162-
if (process instanceof ProcessGraph || process instanceof UserProcess) {
163-
process = process.toJSON();
164-
}
165-
166-
this.showModal('ProcessModal', {process});
148+
this.showModal('ProcessModal', {
149+
process: await this.loadProcess(process)
150+
});
167151
},
168152
showProcessParameter(parameter, udp = true) {
169153
this.showModal('ProcessParameterModal', {

src/components/DiscoveryToolbar.vue

+11-11
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
</template>
1616
</Collections>
1717

18-
<Processes class="category" :processes="processes" :searchTerm="searchTerm" :offerDetails="false" :collapsed="collapsed">
18+
<Processes class="category" :processes="allProcesses" :searchTerm="searchTerm" :offerDetails="false" :collapsed="collapsed">
1919
<template #summary="{ item }">
2020
<div class="discovery-entity" draggable="true" @dragstart="onDrag($event, 'process', item)">
2121
<div class="discovery-info" @click="showProcess(item)">
22-
<i v-if="!item.native" class="custom-process fas fa-xs fa-sitemap" title="Custom Process"></i>
22+
<i v-if="item.namespace === 'user'" class="custom-process fas fa-xs fa-sitemap" title="Custom Process"></i>
23+
<i v-else-if="item.namespace !== 'backend'" class="custom-process fas fa-xs fa-tag" :title="`Process from namespace '${item.namespace}'`"></i>
2324
<strong :title="item.id">{{ item.id }}</strong>
2425
<small v-if="item.summary" :title="item.summary">{{ item.summary }}</small>
2526
</div>
@@ -91,24 +92,22 @@ export default {
9192
};
9293
},
9394
computed: {
94-
...Utils.mapState(['predefinedProcesses', 'collections', 'udfRuntimes']),
95-
...Utils.mapState('userProcesses', ['userProcesses']),
96-
...Utils.mapGetters(['supports', 'collectionDefaults', 'fileFormats']),
97-
...Utils.mapGetters('userProcesses', {getProcessById: 'getAllById'}),
95+
...Utils.mapState(['collections', 'udfRuntimes']),
96+
...Utils.mapGetters(['supports', 'collectionDefaults', 'fileFormats', 'processes']),
9897
supportsLoadCollection() {
99-
return !!this.getProcessById('load_collection');
98+
return this.processes.has('load_collection');
10099
},
101100
supportsRunUdf() {
102-
return !!this.getProcessById('run_udf');
101+
return this.processes.has('run_udf');
103102
},
104103
supportsSaveResult() {
105-
return !!this.getProcessById('save_result');
104+
return this.processes.has('save_result');
106105
},
107106
hasUdfRuntimes() {
108107
return Utils.size(this.udfRuntimes);
109108
},
110-
processes() {
111-
return this.predefinedProcesses.concat(this.userProcesses);
109+
allProcesses() {
110+
return this.processes.all();
112111
}
113112
},
114113
watch: {
@@ -160,6 +159,7 @@ export default {
160159
case 'process':
161160
return {
162161
process_id: data.id,
162+
namespace: data.namespace,
163163
arguments: {}
164164
};
165165
case 'udf':

src/components/Editor.vue

+2-10
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,8 @@ export default {
7272
mounted() {
7373
this.updateTab();
7474
},
75-
computed: {
76-
...Utils.mapGetters('userProcesses', {getProcessById: 'getAllById'})
77-
},
7875
methods: {
79-
...Utils.mapActions('userProcesses', {readUserProcess: 'read'}),
76+
...Utils.mapActions(['loadProcess']),
8077
showModel() {
8178
this.error = null;
8279
this.modelValue = this.value;
@@ -111,12 +108,7 @@ export default {
111108
},
112109
async insertProcess(node) {
113110
try {
114-
// Fully load or update custom process
115-
let process = this.getProcessById(node.process_id);
116-
if (process != null && !process.native) {
117-
await this.readUserProcess({data: process});
118-
}
119-
// Add process to editor
111+
await this.loadProcess({id: node.process_id, namespace: node.namespace});
120112
this.activeEditor().insertProcess(node);
121113
} catch(error) {
122114
Utils.exception(this, error);

src/components/IDE.vue

+1-10
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,7 @@ export default {
9494
}
9595
}
9696
},
97-
async created() {
98-
try {
99-
await this.loadInitialProcess();
100-
} catch (error) {
101-
Utils.exception(this, error, "Loading process failed");
102-
}
103-
104-
},
105-
mounted() {
97+
async mounted() {
10698
this.listen('showDataForm', this.showDataForm);
10799
this.listen('editProcess', this.editProcess);
108100
@@ -123,7 +115,6 @@ export default {
123115
},
124116
methods: {
125117
...Utils.mapActions(['describeAccount']),
126-
...Utils.mapActions('editor', ['loadInitialProcess']),
127118
...Utils.mapMutations('editor', ['setContext', 'setProcess']),
128119
129120
resized(event) {

src/components/TextEditor.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export default {
7272
}
7373
},
7474
computed: {
75-
...Utils.mapGetters(['processRegistry']),
75+
...Utils.mapGetters(['processes']),
7676
languageString() {
7777
return typeof this.language === 'string' ? this.language.toLowerCase() : '';
7878
},
@@ -184,7 +184,7 @@ export default {
184184
if (value) {
185185
var process = JSON.parse(value);
186186
if (Utils.size(process) > 0) {
187-
var pg = new ProcessGraph(process, this.processRegistry);
187+
var pg = new ProcessGraph(process, this.processes);
188188
pg.allowEmpty();
189189
pg.parse();
190190
return this.emit(process);

src/components/VisualEditor.vue

+46-7
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@
3030
ref="blocks"
3131
:editable="editable"
3232
:id="id"
33-
:processes="processRegistry"
33+
:processes="processes"
3434
:collections="collections"
3535
:parent="parent"
3636
:parentSchema="parentSchema"
3737
:value="value"
3838
@input="commit"
3939
@error="errorHandler"
40-
@showProcess="id => emit('showProcess', id)"
40+
@showProcess="(id, namespace) => emit('showProcess', {id, namespace})"
4141
@showCollection="id => emit('showCollection', id)"
4242
@showParameter="param => emit('showProcessParameter', param)"
4343
@editParameter="editParameter"
@@ -57,6 +57,7 @@ import Utils from '../utils.js';
5757
import DiscoveryToolbar from './DiscoveryToolbar.vue';
5858
import EventBusMixin from './EventBusMixin.vue';
5959
import FullscreenButton from './FullscreenButton.vue';
60+
import { ProcessParameter } from '@openeo/js-commons';
6061
6162
export default {
6263
name: 'VisualEditor',
@@ -95,8 +96,8 @@ export default {
9596
},
9697
computed: {
9798
...Utils.mapState(['collections']),
98-
...Utils.mapGetters(['processRegistry']),
99-
...Utils.mapGetters('userProcesses', ['supportsMath', 'isMathProcess'])
99+
...Utils.mapGetters(['supportsMath', 'isMathProcess', 'processes']),
100+
...Utils.mapState('editor', ['initialNode']),
100101
},
101102
data() {
102103
return {
@@ -109,11 +110,29 @@ export default {
109110
};
110111
},
111112
watch: {
112-
value(value) {
113-
this.isMath = this.isMathProcess(value);
113+
value: {
114+
immediate: true,
115+
handler(value) {
116+
this.isMath = this.isMathProcess(value);
117+
118+
if (this.initialNode && Utils.isObject(value) && Utils.isObject(value.process_graph)) {
119+
try {
120+
let node = this.initialNode;
121+
if (node == "1" && Utils.size(value.process_graph)) {
122+
node = Object.keys(value.process_graph)[0];
123+
}
124+
this.openArgumentEditorForNode(node);
125+
} catch (error) {
126+
Utils.exception(this, error);
127+
} finally {
128+
this.setInitialNode(null);
129+
}
130+
}
131+
}
114132
}
115133
},
116134
methods: {
135+
...Utils.mapMutations('editor', ['setInitialNode']),
117136
commit(value) {
118137
// Fix #115: Return the default value/null if no nodes are given
119138
if (typeof this.defaultValue !== 'undefined' && Utils.isObject(value) && Utils.size(value.process_graph) === 0) {
@@ -462,6 +481,22 @@ export default {
462481
};
463482
this.emit('showModal', 'ExpressionModal', props, events);
464483
},
484+
openArgumentEditorForNode(nodeId) {
485+
let process = Utils.deepClone(this.value);
486+
let node = process.process_graph[nodeId];
487+
let processSpec = this.processes.get(node.process_id, node.namespace);
488+
this.openArgumentEditor(
489+
processSpec.parameters.map(p => new ProcessParameter(p)).filter(p => p.isEditable()),
490+
node.arguments,
491+
processSpec.id,
492+
true,
493+
null,
494+
data => {
495+
Object.assign(node, {arguments: data});
496+
this.commit(process);
497+
}
498+
);
499+
},
465500
openArgumentEditor(parameters, data, title = "Edit", editable = true, selectParameterName = null, saveCallback = null, parent = null) {
466501
let props = {
467502
title,
@@ -492,7 +527,11 @@ export default {
492527
insertProcess(node, x = null, y = null) {
493528
try {
494529
var pos = this.$refs.blocks.getPositionForPageXY(x, y);
495-
this.$refs.blocks.addProcess(node.process_id, node.arguments, pos);
530+
let namespace = node.namespace;
531+
if (namespace === 'backend' || namespace === 'user') {
532+
namespace = null;
533+
}
534+
this.$refs.blocks.addProcess(node.process_id, node.arguments, pos, namespace);
496535
} catch(error) {
497536
Utils.exception(this, error);
498537
}

0 commit comments

Comments
 (0)