From 47254d241cd1afe8aa2381e98b6d6c22f79d360c Mon Sep 17 00:00:00 2001 From: Matthias Mohr Date: Tue, 10 Oct 2023 22:39:55 +0200 Subject: [PATCH 01/11] Create is not required for showing the work panels --- src/components/WorkPanelMixin.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/WorkPanelMixin.js b/src/components/WorkPanelMixin.js index 06686f8be..cce37dd4f 100644 --- a/src/components/WorkPanelMixin.js +++ b/src/components/WorkPanelMixin.js @@ -70,9 +70,6 @@ export default (namespace, singular, plural, loadInitially = true) => { else if (!this.supportsList) { table.setNoData("Sorry, listing stored " + plural + " is not supported by the server."); } - else if (!this.supportsCreate) { - table.setNoData("Sorry, this feature is not supported by the server."); - } else { var isUpdate = this.data.length > 0; if (!isUpdate) { From dd7845a3893ed8d8f0a698af62adee9fb100f01b Mon Sep 17 00:00:00 2001 From: Matthias Mohr Date: Tue, 10 Oct 2023 23:45:43 +0200 Subject: [PATCH 02/11] Async drag and drop for toolbar/viewer --- src/components/DiscoveryToolbar.vue | 41 +++++--------------- src/components/Viewer.vue | 11 +++--- src/components/VisualEditor.vue | 11 +++--- src/components/datatypes/SelectBox.vue | 1 - src/store/editor.js | 53 +++++++++++++++++++++++++- 5 files changed, 72 insertions(+), 45 deletions(-) diff --git a/src/components/DiscoveryToolbar.vue b/src/components/DiscoveryToolbar.vue index 98e2e1e71..4c4057134 100644 --- a/src/components/DiscoveryToolbar.vue +++ b/src/components/DiscoveryToolbar.vue @@ -94,7 +94,7 @@ export default { computed: { ...Utils.mapState(['collections', 'udfRuntimes']), ...Utils.mapState('editor', ['discoverySearchTerm']), - ...Utils.mapGetters(['supports', 'collectionDefaults', 'fileFormats', 'processes']), + ...Utils.mapGetters(['supports', 'fileFormats', 'processes']), supportsLoadCollection() { return this.processes.has('load_collection'); }, @@ -143,15 +143,17 @@ export default { } }, methods: { - ...Utils.mapMutations('editor', ['setDiscoverySearchTerm']), + ...Utils.mapMutations('editor', ['setDiscoverySearchTerm', 'setModelDnd']), ...Utils.mapActions(['loadProcess']), - async onDrag(event, type, data) { + onDrag(event, type, data) { + let fn = (loading) => this.setModelDnd({type, data, loading}); if (type === 'process') { - this.loadProcess(data); + fn(true); + this.loadProcess(data).then(() => fn(false)); + } + else { + fn(false); } - let node = this.getNode(type, data); - event.dataTransfer.setData("application/vnd.openeo-node", JSON.stringify(node)); - event.dataTransfer.setData("text/plain", JSON.stringify(node, null, 2)); }, showCollectionInfo(id) { this.broadcast('showCollection', id); @@ -175,31 +177,6 @@ export default { type: "output" }; this.broadcast('showModal', 'FileFormatModal', props); - }, - getNode(type, data) { - switch(type) { - case 'collection': - return { - process_id: 'load_collection', - arguments: this.collectionDefaults(data.id) - }; - case 'process': - return { - process_id: data.id, - namespace: data.namespace, - arguments: {} - }; - case 'udf': - return { - process_id: 'run_udf', - arguments: data - }; - case 'fileformat': - return { - process_id: 'save_result', - arguments: {format: data.name, options: {}} - }; - } } } } diff --git a/src/components/Viewer.vue b/src/components/Viewer.vue index a7c631fe7..225e4705a 100644 --- a/src/components/Viewer.vue +++ b/src/components/Viewer.vue @@ -70,13 +70,14 @@ export default { computed: { ...Utils.mapState(['connection']), ...Utils.mapState('editor', ['appMode']), + ...Utils.mapGetters('editor', ['getModelNodeFromDnD']), nextTabId() { return `viewer~${this.tabIdCounter}`; } }, methods: { ...Utils.mapActions(['describeCollection']), - ...Utils.mapMutations('editor', ['setViewerOptions']), + ...Utils.mapMutations('editor', ['setViewerOptions', 'setModelDnD']), isCollectionPreview(data) { return (data instanceof Service && Utils.isObject(data.attributes) && data.attributes.preview === true); }, @@ -278,11 +279,9 @@ export default { } }, async onDrop(event) { - var json = event.dataTransfer.getData("application/vnd.openeo-node"); - if (!json) { - return; - } - let node = JSON.parse(json); + const node = await this.getModelNodeFromDnD(); + this.setModelDnD(); + if (node.process_id === 'load_collection') { event.preventDefault(); let id = Utils.isObject(node.arguments) ? node.arguments.id : null; diff --git a/src/components/VisualEditor.vue b/src/components/VisualEditor.vue index 003278344..1ec988955 100644 --- a/src/components/VisualEditor.vue +++ b/src/components/VisualEditor.vue @@ -129,6 +129,7 @@ export default { ...Utils.mapState(['connection', 'collections']), ...Utils.mapGetters(['processes', 'supportsMath']), ...Utils.mapState('editor', ['initialNode']), + ...Utils.mapGetters('editor', ['getModelNodeFromDnD']), isMath() { return (this.supportsMath && this.processes.isMath(this.value)); } @@ -172,7 +173,7 @@ export default { this.canPaste = navigator && navigator.clipboard && typeof navigator.clipboard.readText === 'function'; }, methods: { - ...Utils.mapMutations('editor', ['setInitialNode']), + ...Utils.mapMutations('editor', ['setInitialNode', 'setModelDnD']), commit(value) { // Fix #115: Return the default value/null if no nodes are given if (typeof this.defaultValue !== 'undefined' && Utils.isObject(value) && Utils.size(value.process_graph) === 0) { @@ -209,11 +210,11 @@ export default { this.showHelpOverlay = false; event.preventDefault(); }, - onDrop(event) { - var editorNodeJson = event.dataTransfer.getData("application/vnd.openeo-node"); - if (editorNodeJson) { - let node = JSON.parse(editorNodeJson); + async onDrop(event) { + const node = await this.getModelNodeFromDnD(); + if (node) { this.insertProcess(node, event.pageX, event.pageY); + this.setModelDnD(); return event.preventDefault(); } diff --git a/src/components/datatypes/SelectBox.vue b/src/components/datatypes/SelectBox.vue index 2f321b696..0132cc83f 100644 --- a/src/components/datatypes/SelectBox.vue +++ b/src/components/datatypes/SelectBox.vue @@ -40,7 +40,6 @@ export default { } }, computed: { - ...Utils.mapGetters(['collectionDefaults']), selectOptions() { let state = []; switch(this.type) { diff --git a/src/store/editor.js b/src/store/editor.js index 320dca412..f7f9261e9 100644 --- a/src/store/editor.js +++ b/src/store/editor.js @@ -19,7 +19,8 @@ const getDefaultState = () => { openWizard: null, openWizardProps: {}, collectionPreview: null, - viewerOptions: {} + viewerOptions: {}, + modelDnD: null }; }; @@ -28,6 +29,53 @@ export default { state: getDefaultState(), getters: { hasProcess: state => Utils.isObject(state.process) && Utils.size(state.process) > 0 && Utils.size(state.process.process_graph), + getModelNodeFromDnD: (state, getters, rootState, rootGetters) => () => { + return new Promise((resolve, reject) => { + if (!state.modelDnD) { + resolve(null); + return; + } + const getterFn = () => { + switch(state.modelDnD.type) { + case 'collection': + return { + process_id: 'load_collection', + arguments: rootGetters.collectionDefaults(state.modelDnD.data.id) + }; + case 'process': + return { + process_id: state.modelDnD.data.id, + namespace: state.modelDnD.data.namespace, + arguments: {} + }; + case 'udf': + return { + process_id: 'run_udf', + arguments: state.modelDnD.data + }; + case 'fileformat': + return { + process_id: 'save_result', + arguments: {format: state.modelDnD.data.name, options: {}} + }; + default: + return null; + } + }; + if (state.modelDnD.loading) { + let id = setInterval(() => { + if (!state.modelDnD || state.modelDnD.loading) { + return; + } + clearInterval(id); + resolve(getterFn()); + }, 50); + } + else { + resolve(getterFn()); + } + }); + } }, actions: { async loadEpsgCodes(cx) { @@ -84,6 +132,9 @@ export default { } }, mutations: { + setModelDnd(state, obj = null) { + state.modelDnD = obj; + }, setDiscoverySearchTerm(state, searchTerm) { state.discoverySearchTerm = typeof searchTerm === 'string' ? searchTerm : ''; }, From 84d76f2b6fc22773a9314b8983e1962a4fd07576 Mon Sep 17 00:00:00 2001 From: Matthias Mohr Date: Wed, 25 Oct 2023 22:01:54 +0200 Subject: [PATCH 03/11] Fix UDP loading with authentication --- src/Page.vue | 6 +++++- src/components/ConnectForm.vue | 3 +++ src/components/wizards/SpectralIndices.vue | 2 +- src/components/wizards/UDP.vue | 6 +++++- .../wizards/tabs/ChooseProcessParameters.vue | 9 ++++++++- src/utils.js | 18 ++++++++++++++---- 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/Page.vue b/src/Page.vue index d79eead96..a1bbea05b 100644 --- a/src/Page.vue +++ b/src/Page.vue @@ -78,9 +78,13 @@ export default { }); } - if (Utils.param('discover') || resultUrl) { + const discover = Utils.param('discover'); + if (discover === "1" || resultUrl) { this.skipLogin = true; } + else if (discover === "0") { + this.skipLogin = false; + } // Count active requests axios.interceptors.request.use(config => { diff --git a/src/components/ConnectForm.vue b/src/components/ConnectForm.vue index 8fab30b58..01e2c9bba 100644 --- a/src/components/ConnectForm.vue +++ b/src/components/ConnectForm.vue @@ -406,6 +406,9 @@ export default { if (discover && !this.$config.skipLogin) { params.set('discover', 1); } + else if (!discover && this.$config.skipLogin) { + params.set('discover', 0); + } else { params.delete('discover'); } diff --git a/src/components/wizards/SpectralIndices.vue b/src/components/wizards/SpectralIndices.vue index 895b3bd29..2f197889e 100644 --- a/src/components/wizards/SpectralIndices.vue +++ b/src/components/wizards/SpectralIndices.vue @@ -90,7 +90,7 @@ export default { temporal_extent: null }; }, - created() { + beforeMount() { this.scale = this.processes.has('apply') && this.processes.has('linear_scale_range') ? false : null; }, computed: { diff --git a/src/components/wizards/UDP.vue b/src/components/wizards/UDP.vue index 4f0a0db2b..b1da29374 100644 --- a/src/components/wizards/UDP.vue +++ b/src/components/wizards/UDP.vue @@ -57,8 +57,12 @@ export default { }; } }, - async created() { + async beforeMount() { this.loading = true; + if (typeof this.process !== 'string' || this.process.length === 0) { + this.$emit('close', `Sorry, no process specified.`); + return; + } let [id, namespace] = Utils.extractUDPParams(this.process); try { this.processSpec = await this.loadProcess({id, namespace}); diff --git a/src/components/wizards/tabs/ChooseProcessParameters.vue b/src/components/wizards/tabs/ChooseProcessParameters.vue index f8f43909d..116845aab 100644 --- a/src/components/wizards/tabs/ChooseProcessParameters.vue +++ b/src/components/wizards/tabs/ChooseProcessParameters.vue @@ -1,6 +1,9 @@ @@ -8,6 +11,7 @@ + + \ No newline at end of file From 893d62a3f7c1d74fec1eb701c8f00fe017b6df66 Mon Sep 17 00:00:00 2001 From: Matthias Mohr Date: Fri, 3 Nov 2023 01:06:35 +0100 Subject: [PATCH 06/11] Allow to specify a URL in the UDP wizard --- src/components/modals/ImportProcessModal.vue | 7 +- src/components/modals/WizardModal.vue | 2 +- src/components/wizards/UDP.vue | 93 ++++++++++++++----- .../wizards/tabs/ChooseUserDefinedProcess.vue | 28 +++++- 4 files changed, 101 insertions(+), 29 deletions(-) diff --git a/src/components/modals/ImportProcessModal.vue b/src/components/modals/ImportProcessModal.vue index d6b770b75..49d2806cb 100644 --- a/src/components/modals/ImportProcessModal.vue +++ b/src/components/modals/ImportProcessModal.vue @@ -108,8 +108,11 @@ export default { if (!Utils.isObject(data)) { throw new Error('Process does not contain any data'); } - if (typeof data.id !== 'string' && !Utils.isObject(data.process_graph)) { - throw new Error('Process does not contain `id` or `process graph`'); + if (!Utils.hasText(data.id)) { + throw new Error('Process does not contain an id'); + } + if (!Utils.isObject(data.process_graph)) { + throw new Error('Process does not contain a process graph'); } return data; }, diff --git a/src/components/modals/WizardModal.vue b/src/components/modals/WizardModal.vue index c783b7268..0d7430c5f 100644 --- a/src/components/modals/WizardModal.vue +++ b/src/components/modals/WizardModal.vue @@ -1,5 +1,5 @@