Select Git revision
CentroidFunction.java
-
gmantele authored
ADQLObject has now a new function: getPosition(). To allow it, the parser and all ADQL query tree item have been modified to define this function properly. The parser is setting this position for all parsed items. The test class/main function "TestGetPositionInAllADQLObject" aims to check that after a parsing all items really have a defined position.
gmantele authoredADQLObject has now a new function: getPosition(). To allow it, the parser and all ADQL query tree item have been modified to define this function properly. The parser is setting this position for all parsed items. The test class/main function "TestGetPositionInAllADQLObject" aims to check that after a parsing all items really have a defined position.
uploadsManager.js 6.38 KiB
/*
* This file is part of vospace-ui
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import Vue from 'vue';
import client from 'api-client';
function resetArray(array) {
array.splice(0, array.length);
}
export default {
state: {
files: [], // array of selected files
progress: [], // array of upload progress percentages (for tracking upload progress)
cancellations: [], // array of axios cancel tokens (for aborting uploads)
deletionStatuses: [], // status of upload deletions (true if request is being aborted, false otherwise)
errors: [], // errors happened during downloads
creatingMetadata: false, // true when nodes metadata is being created (pre-upload phase)
uploadInProgress: false, // true when data is being uploaded
},
mutations: {
setFilesToUpload(state, files) {
state.files = files;
},
resetUploadState(state) {
resetArray(state.progress);
resetArray(state.cancellations);
resetArray(state.deletionStatuses);
resetArray(state.errors);
},
setDeletion(state, data) {
Vue.set(state.deletionStatuses, data.index, data.value);
},
setProgress(state, data) {
Vue.set(state.progress, data.index, data.percent);
},
setCreatingMetadata(state, value) {
state.creatingMetadata = value;
},
setUploadInProgress(state, value) {
state.uploadInProgress = value;
},
setPreUploadResults(state, preUploadResults) {
for (let result of preUploadResults) {
if (Object.keys(result).includes('request')) {
state.cancellations.push(result.source); // axios cancellation token
state.deletionStatuses.push(null);
state.errors.push(null);
} else {
state.cancellations.push(null);
state.deletionStatuses.push(null);
state.errors.push(result);
}
}
state.uploadInProgress = true;
},
setError(state, data) {
Vue.set(state.errors, data.index, data.error);
}
},
actions: {
upload({ state, rootState, commit, dispatch }, bvModal) {
// Progress bars initialization
for (let index = 0; index < state.files.length; index++) {
let file = state.files[index];
let reader = new FileReader();
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
let percent = (event.loaded / event.total) * 100;
commit('setProgress', { index, percent });
}
});
reader.readAsDataURL(file);
}
commit('setCreatingMetadata', true);
// Create nodes metadata and obtain upload URLs
dispatch('prepareUpload')
.then((preUploadResults) => {
commit('setCreatingMetadata', false);
let promises = [];
for (let result of preUploadResults) {
if (Object.keys(result).includes('request')) {
promises.push(result.request); // upload http promise
} else {
// fictitious promise for failed pre-upload event
promises.push(new Promise(resolve => resolve()));
}
}
commit('setPreUploadResults', preUploadResults);
// wait until all downloads have been completed (both successfully or not)
return Promise.allSettled(promises);
})
.then((responses) => {
let deletionPromises = [];
for (let index = 0; index < responses.length; index++) {
let error = state.errors[index];
let response = responses[index];
if (response.status === 'fulfilled' && error === null) {
commit('setProgress', { index, percent: 100 });
} else {
if (state.deletionStatuses[index] || error === null) {
// delete node metadata both when user aborted the upload and when it failed
deletionPromises.push(client.deleteNodes(['/' + rootState.path + '/' + state.files[index].name], true));
if (state.deletionStatuses[index] === null) {
// e.g. server became unreachable during the upload
commit('setError', { index, error: 'Unable to upload file' });
}
}
}
}
// if there are some deletion promises, wait them
return Promise.allSettled(deletionPromises);
})
.then(deletionResults => {
// verify if metadata of aborted uploads has been correctly removed
let resultIndex = 0;
for (let i = 0; i < state.deletionStatuses.length; i++) {
let deletionStatus = state.deletionStatuses[i];
if (deletionStatus !== null) {
let deletionResult = deletionResults[resultIndex];
if (deletionResult.status === 'fulfilled') {
commit('setDeletion', { index: i, value: false });
} else {
commit('setError', { index: i, error: 'Failed to delete node metadata. Manual cleanup may be required.' });
}
resultIndex++;
}
}
})
.finally(() => {
// Reload current node when all uploads completed
dispatch('setPath', rootState.path);
commit('setCreatingMetadata', false);
commit('setUploadInProgress', false);
let hasErrors = state.errors.filter(e => e !== null).length > 0;
if (!hasErrors) {
bvModal.hide('upload-files-modal');
}
});
},
prepareUpload({ state, rootState }) {
let names = [];
for (let file of state.files) {
names.push(file.name);
}
return new Promise((resolve, reject) => {
client.prepareForUpload(rootState.path, names)
.then(preUploadResponses => {
let uploads = [];
for (let i = 0; i < state.files.length; i++) {
let uploadUrl = preUploadResponses[i].url;
if (uploadUrl !== null) {
uploads.push(client.uploadFile(uploadUrl, state.files[i]));
} else {
uploads.push(preUploadResponses[i].error);
}
}
resolve(uploads);
})
.catch(error => reject(error));
});
},
cancelUpload({ state, commit }, index) {
commit('setDeletion', { index, value: true });
state.cancellations[index].cancel();
}
}
}