Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
m-mohr committed Mar 19, 2024
2 parents 5a20210 + 145af2b commit cfd7d8a
Show file tree
Hide file tree
Showing 19 changed files with 437 additions and 131 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openeo/web-editor",
"version": "0.12.4",
"version": "0.12.5",
"apiVersions": [
"1.0.0-rc.2",
"1.0.0",
Expand Down Expand Up @@ -36,6 +36,10 @@
"type": "git",
"url": "https://github.com/Open-EO/openeo-web-editor.git"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/m-mohr"
},
"scripts": {
"build:database": "node src/build-database.js",
"start": "npm run build:database && npx vue-cli-service serve",
Expand Down
6 changes: 5 additions & 1 deletion src/Page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
3 changes: 3 additions & 0 deletions src/components/ConnectForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
Expand Down
41 changes: 9 additions & 32 deletions src/components/DiscoveryToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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');
},
Expand Down Expand Up @@ -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);
Expand All @@ -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: {}}
};
}
}
}
}
Expand Down
52 changes: 12 additions & 40 deletions src/components/JobPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import EventBusMixin from './EventBusMixin';
import WorkPanelMixin from './WorkPanelMixin';
import SyncButton from './SyncButton.vue';
import Utils from '../utils.js';
import { AbortController, Job } from '@openeo/js-client';
import { Job } from '@openeo/js-client';
import { cancellableRequest, showCancellableRequestError, CancellableRequestError } from './cancellableRequest';
const WorkPanelMixinInstance = WorkPanelMixin('jobs', 'batch job', 'batch jobs');
Expand All @@ -39,8 +40,7 @@ export default {
data() {
return {
watchers: {},
jobUpdater: null,
runId: 0
jobUpdater: null
};
},
mounted() {
Expand Down Expand Up @@ -145,48 +145,20 @@ export default {
await this.queueJob(job);
},
async executeProcess() {
let abortController = new AbortController();
let snotifyConfig = {
timeout: 0,
type: 'async',
buttons: [{
text: 'Cancel',
action: toast => {
abortController.abort();
this.$snotify.remove(toast.id, true);
}
}]
const callback = async (abortController) => {
const result = await this.connection.computeResult(this.process, null, null, abortController);
this.broadcast('viewSyncResult', result);
};
let toast;
try {
this.runId++;
let message = "A process is currently executed synchronously...";
let title = `Run #${this.runId}`;
let endlessPromise = () => new Promise(() => {}); // Pass a promise to snotify that never resolves as we manually close the toast
toast = this.$snotify.async(message, title, endlessPromise, snotifyConfig);
let result = await this.connection.computeResult(this.process, null, null, abortController);
this.broadcast('viewSyncResult', result);
} catch(error) {
if (axios.isCancel(error)) {
// Do nothing, we expected the cancellation
}
else if (typeof error.message === 'string' && Utils.isObject(error.response) && [400,500].includes(error.response.status)) {
this.broadcast('viewLogs', [{
id: error.id,
code: error.code,
level: 'error',
message: error.message,
links: error.links || []
}]);
Utils.error(this, "Synchronous processing failed. Please see the logs for details.", "Processing Error");
await cancellableRequest(this, callback, 'Run');
} catch (error) {
if (error instanceof CancellableRequestError) {
showCancellableRequestError(this, error);
}
else {
Utils.exception(this, error, "Server Error");
}
} finally {
if (toast) {
this.$snotify.remove(toast.id, true);
Utils.exception(this, error);
}
}
},
jobCreated(job) {
Expand Down
11 changes: 5 additions & 6 deletions src/components/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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);
},
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 6 additions & 5 deletions src/components/VisualEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
}
Expand Down
3 changes: 0 additions & 3 deletions src/components/WorkPanelMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
76 changes: 76 additions & 0 deletions src/components/cancellableRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { AbortController } from '@openeo/js-client';
import Utils from '../utils';

export class CancellableRequestError extends Error {
constructor(message, title = null, cause = null, close = true, isError = true) {
super(message, {cause});
this.title = title;
this.close = close;
this.isError = isError;
}
}

export function showCancellableRequestError(vm, error) {
if (error instanceof CancellableRequestError) {
if (error.isError) {
Utils.error(vm, error.message, error.title);
}
else {
Utils.ok(vm, error.message, error.title);
}
}
}

let runIds = {};
export async function cancellableRequest(vm, callback, entity) {
if (!runIds[entity]) {
runIds[entity] = 1;
}
else {
runIds[entity]++;
}

const abortController = new AbortController();
const snotifyConfig = Object.assign({}, vm.$config.snotifyDefaults, {
timeout: 0,
type: 'async',
buttons: [{
text: 'Cancel',
action: () => {
abortController.abort();
}
}]
});

let toast;
const toastTitle = `${entity} #${runIds[entity]}`;
try {
const message = `Processing in progress, please wait...`;
// Pass a promise to snotify that never resolves as we manually close the toast
const endlessPromise = () => new Promise(() => {});
toast = vm.$snotify.async(message, toastTitle, endlessPromise, snotifyConfig);

await callback(abortController);
} catch(error) {
if (axios.isCancel(error)) {
throw new CancellableRequestError(`Cancelled successfully`, toastTitle, error, false, false);
}
else if (typeof error.message === 'string' && Utils.isObject(error.response) && [400,500].includes(error.response.status)) {
vm.broadcast('viewLogs', [{
id: error.id,
code: error.code,
level: 'error',
message: error.message,
links: error.links || []
}]);
Utils.error(vm, `${entity} failed. Please see the logs for details.`, toastTitle);
}
else {
throw new CancellableRequestError(error.message, toastTitle, error, false);
}
} finally {
if (toast) {
vm.$snotify.remove(toast.id, true);
}
}
}
4 changes: 2 additions & 2 deletions src/components/datatypes/SelectBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export default {
}
},
computed: {
...Utils.mapGetters(['collectionDefaults']),
selectOptions() {
let state = [];
switch(this.type) {
Expand Down Expand Up @@ -213,7 +212,8 @@ export default {
return (this.type === 'file-paths');
},
taggable() {
return (this.type === 'year');
let freeInputIfEmpty = ['band-name', 'collection-id', 'job-id', 'input-format', 'output-format'];
return (this.type === 'year' || (this.selectOptions.length === 0 && freeInputIfEmpty.includes(this.type)));
},
preselect() {
if (this.multiple) {
Expand Down
7 changes: 5 additions & 2 deletions src/components/modals/ImportProcessModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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;
},
Expand Down
Loading

0 comments on commit cfd7d8a

Please sign in to comment.