/* Vuex store, for centralized state management */ import Vue from 'vue'; import Vuex from 'vuex'; import client from 'api-client'; import main from './main'; Vue.use(Vuex); function updateArray(oldArr, newArr) { // empty the array oldArr.splice(0, oldArr.length); // fill again for (let i = 0; i < newArr.length; i++) { oldArr.push(newArr[i]); } } export default new Vuex.Store({ state: { path: '', loading: true, nodesLoading: false, asyncButtonEnabled: false, deleteButtonEnabled: false, jobs: [], jobsLoading: true, lastJobsCheckTime: null, user: 'anonymous', nodesToDelete: [], writable: false, nodeToShare: { path: null, groupRead: null, groupWrite: null } }, mutations: { setLoading(state, loading) { state.loading = loading; }, setPath(state, value) { if (!value) { value = ''; } state.path = value; }, setNodesLoading(state, value) { state.nodesLoading = value; }, setAsyncButtonEnabled(state, value) { state.asyncButtonEnabled = value; }, setDeleteButtonEnabled(state, value) { state.deleteButtonEnabled = value; }, setJobs(state, jobs) { updateArray(state.jobs, jobs); }, addJob(state, job) { state.jobs.push(job); }, setJobsLoading(state, loading) { state.jobsLoading = loading; }, setUsername(state, username) { state.user = username; }, setNodesToDelete(state, paths) { updateArray(state.nodesToDelete, paths); }, setWritable(state, value) { state.writable = value; }, setNodeToShare(state, data) { state.nodeToShare.path = data.path; state.nodeToShare.groupRead = data.groupRead; state.nodeToShare.groupWrite = data.groupWrite; } }, actions: { setPath({ state, commit, dispatch }, path) { commit('setPath', path); commit('setNodesLoading', true); client.getNode(state.path) .then(res => { dispatch('setNodes', res); }) .finally(() => commit('setNodesLoading', false)); }, setNodes({ commit, dispatch }, res) { commit('setWritable', res.writable); document.getElementById('nodes').outerHTML = res.htmlTable; let checkboxes = document.querySelectorAll('#nodes input[type="checkbox"]'); for (let i = 0; i < checkboxes.length; i++) { checkboxes[i].addEventListener('change', function() { dispatch('computeButtonsVisibility'); }); } dispatch('computeButtonsVisibility'); }, computeButtonsVisibility({ commit }) { commit('setAsyncButtonEnabled', document.querySelectorAll('#nodes input.async:checked').length > 0); commit('setDeleteButtonEnabled', document.querySelectorAll('#nodes input.deletable:checked').length > 0); }, startAsyncRecallJob({ state, commit, dispatch }) { let asyncCheckboxes = document.querySelectorAll('#nodes input.async:checked'); let paths = []; for (let i = 0; i < asyncCheckboxes.length; i++) { paths.push(asyncCheckboxes[i].getAttribute('data-node')); } client.startAsyncRecallJob(paths) .then(job => { main.showInfo('Job queued'); commit('addJob', job); // Reload current node dispatch('setPath', state.path); }); }, checkJobs({ state, dispatch }) { if (state.jobs.filter(j => j.phase === 'QUEUED' || j.phase === 'PENDING' || j.phase === 'EXECUTING').length > 0 && !state.jobsLoading && (state.lastJobsCheckTime !== null && new Date().getTime() - state.lastJobsCheckTime > 5000)) { dispatch('loadJobs'); } }, loadJobs({ state, commit }) { commit('setJobsLoading', true); client.loadJobs() .then(jobs => { for (let previousJob of state.jobs) { for (let newJob of jobs) { if (newJob.id === previousJob.id && newJob.phase !== previousJob.phase) { switch (newJob.phase) { case 'EXECUTING': main.showInfo('Job started'); break; case 'COMPLETED': main.showInfo('Job completed'); break; case 'ERROR': main.showError('Job failed'); break; } } } } commit('setJobs', jobs); }) .finally(() => { commit('setJobsLoading', false); state.lastJobsCheckTime = new Date().getTime(); }); }, loadUserInfo({ commit }) { client.getUserInfo() .then(res => commit('setUsername', res.username)); }, createFolder({ state, dispatch }, newFolderName) { client.createFolder(state.path, newFolderName) .then(() => { // Reload current node dispatch('setPath', state.path); }); }, uploadFiles({ state, dispatch }, files) { let names = []; for (let file of files) { names.push(file.name); } client.prepareForUpload(state.path, names) .then(uploadUrls => { let uploads = []; for (let i = 0; i < files.length; i++) { uploads.push(client.uploadFile(uploadUrls[i], files[i])); } Promise.all(uploads).then(() => { // Reload current node when all uploads completed dispatch('setPath', state.path); }); }); }, deleteNodes({ state, dispatch }) { client.deleteNodes(state.nodesToDelete) .then(() => { // Reload current node dispatch('setPath', state.path); }); } } });