diff --git a/server/index.js b/server/index.js index a5169d3af..ddb4a6658 100644 --- a/server/index.js +++ b/server/index.js @@ -381,7 +381,9 @@ app.route(ROUTE_PREFIX + '/rename').post(function (req, res) { // file does not exist, so we can rename the product. fs.rename(PRODUCT_PATH, NEW_PATH, async (err) => { if (err) { - res.status(500).send({ status: 'Internal Server Error' }); + res.status(500).send({ + status: 'Internal Server Error' + }); logger('WARNING', 'Error occured while renaming a Storylines product.' + err); return; } else { @@ -390,7 +392,10 @@ app.route(ROUTE_PREFIX + '/rename').post(function (req, res) { fs.rmSync(NEW_PATH + `/${oldId}_fr.json`); // Delete and then re-initialize the Git repo to remove previous history. - fs.rmSync(NEW_PATH + `/.git`, { recursive: true, force: true }); + fs.rmSync(NEW_PATH + `/.git`, { + recursive: true, + force: true + }); const git = simpleGit(NEW_PATH); await git.init(); @@ -402,7 +407,9 @@ app.route(ROUTE_PREFIX + '/rename').post(function (req, res) { const configPath = NEW_PATH + `/ramp-config/`; fs.readdir(configPath, (err, files) => { if (err) { - res.status(500).send({ status: 'Internal Server Error' }); + res.status(500).send({ + status: 'Internal Server Error' + }); logger('WARNING', 'Error occured while changing map names.' + err); return; } @@ -422,7 +429,9 @@ app.route(ROUTE_PREFIX + '/rename').post(function (req, res) { } }); } else { - res.status(500).send({ status: 'Internal Server Error' }); + res.status(500).send({ + status: 'Internal Server Error' + }); logger('WARNING', 'Error occured while renaming a Storylines product.', error); return; } @@ -536,9 +545,9 @@ async function commitToRepo(path, username, initial) { versionNumber = Number(versionNumber) + 1; } // Commit the files for this storyline to its repo. - await git - .add('./*') - .commit(`Add product version ${versionNumber} on ${date} at ${time}`, { '--author': `"${username} <>"` }); + await git.add('./*').commit(`Add product version ${versionNumber} on ${date} at ${time}`, { + '--author': `"${username} <>"` + }); const log = await git.log(); const commitsAfter = log.total; return commitsAfter > commitsBefore; @@ -617,7 +626,12 @@ wss.on('connection', (ws) => { const { uuid, lock } = message; if (!uuid) { - ws.send(JSON.stringify({ status: 'fail', message: 'UUID not provided.' })); + ws.send( + JSON.stringify({ + status: 'fail', + message: 'UUID not provided.' + }) + ); } logger('INFO', `${msg}`); // User wants to lock storyline since they are about to load/edit it. @@ -627,7 +641,12 @@ wss.on('connection', (ws) => { // Someone else is currently accessing this storyline, do not allow the user to lock! if (currentLock && ws.uuid !== uuid) { logger('INFO', `A client failed to lock the storyline ${uuid}.`); - ws.send(JSON.stringify({ status: 'fail', message: 'Another user has locked this storyline.' })); + ws.send( + JSON.stringify({ + status: 'fail', + message: 'Another user has locked this storyline.' + }) + ); } // Lock the storyline for this user. No-one else can access it until the user is done with it. // Send the secret key back to the client so that they can now get/save the storyline by passing in the @@ -660,7 +679,7 @@ wss.on('connection', (ws) => { logger('INFO', `A client successfully unlocked the storyline ${uuid}.`); delete lockedUuids[uuid]; delete ws.uuid; - ws.send(JSON.stringify({ status: 'success' })); + //ws.send(JSON.stringify({ status: "success" })); broadcastToClients({ type: 'unlock', diff --git a/src/components/metadata-editor.vue b/src/components/metadata-editor.vue index 2e7458975..8a50cd7c0 100644 --- a/src/components/metadata-editor.vue +++ b/src/components/metadata-editor.vue @@ -1265,64 +1265,78 @@ export default class MetadataEditorV extends Vue { const convertedFrench = JSON.stringify(frenchConfig, null, 4); // First, hit the Express server `rename` endpoint to perform the `rename` syscall on the file system. - await axios - .post(this.apiUrl + `/rename`, { - user: this.user, - previousUuid: prevUuid, - newUuid: this.changeUuid, - configs: { en: convertedEnglish, fr: convertedFrench } - }) - .then(async (res: AxiosResponse) => { - // Once the server has processed the renaming, update the UUID in the database if not in dev mode. - if (import.meta.env.VITE_APP_NET_API_URL !== undefined) { - await axios.post(import.meta.env.VITE_APP_NET_API_URL + '/api/version/update', { - uuid: prevUuid, - changeUuid: this.changeUuid - }); - } + // Before doing so, we lock the new uuid, to ensure it is not already locked or does not already exist + this.lockStore.unlockStoryline(); // Unlock storyline using old UUID + this.lockStore + .lockStoryline(this.changeUuid) + .then(async () => { + await axios + .post(this.apiUrl + `/rename`, { + user: this.user, + previousUuid: prevUuid, + newUuid: this.changeUuid, + configs: { en: convertedEnglish, fr: convertedFrench } + }) + .then(async (res: AxiosResponse) => { + // Once the server has processed the renaming, update the UUID in the database if not in dev mode. + if (import.meta.env.VITE_APP_NET_API_URL) { + await axios.post(import.meta.env.VITE_APP_NET_API_URL + '/api/version/update', { + uuid: prevUuid, + changeUuid: this.changeUuid + }); + } - // After the server and database have been updated, re-build configFileStructure, - // save the new config files to the server and fetch the new Git history. - if (this.configFileStructure?.zip) { - // Remove the current configuration files from the ZIP folder. - this.configFileStructure?.zip.remove(enFile.name); - this.configFileStructure?.zip.remove(frFile.name); - - // Re-add the configuration files to the ZIP with the new UUID. - this.configFileStructure?.zip.file(`${this.changeUuid}_en.json`, convertedEnglish); - this.configFileStructure?.zip.file(`${this.changeUuid}_fr.json`, convertedFrench); - - // Iterate through the RAMP configuration files and rename them using the new UUID. - const configPromises: Promise[] = []; - this.configFileStructure?.zip.folder('ramp-config/')?.forEach((relativePath, file) => { - configPromises.push(this.renameMapConfig(file.name, prevUuid)); - }); + // After the server and database have been updated, re-build configFileStructure, + // save the new config files to the server and fetch the new Git history. + if (this.configFileStructure?.zip) { + // Remove the current configuration files from the ZIP folder. + this.configFileStructure?.zip.remove(enFile.name); + this.configFileStructure?.zip.remove(frFile.name); + + // Re-add the configuration files to the ZIP with the new UUID. + this.configFileStructure?.zip.file(`${this.changeUuid}_en.json`, convertedEnglish); + this.configFileStructure?.zip.file(`${this.changeUuid}_fr.json`, convertedFrench); - // Wait for map configuration files to be renamed. - await Promise.all(configPromises); + // Iterate through the RAMP configuration files and rename them using the new UUID. + const configPromises: Promise[] = []; + this.configFileStructure?.zip.folder('ramp-config/')?.forEach((relativePath, file) => { + configPromises.push(this.renameMapConfig(file.name, prevUuid)); + }); - this.uuid = this.changeUuid; + // Wait for map configuration files to be renamed. + await Promise.all(configPromises); - // Reset source counts. - this.sourceCounts = {}; + this.uuid = this.changeUuid; - this.configFileStructureHelper(this.configFileStructure.zip).then(() => { - this.fetchHistory(); - this.renameMode = this.processingRename = false; + // Reset source counts. + this.sourceCounts = {}; + + this.configFileStructureHelper(this.configFileStructure.zip).then(() => { + this.fetchHistory(); + this.renameMode = this.processingRename = false; + }); + } + }) + .catch((err) => { + /** If the server returns a 500 error for whatever reason (most likely due to file in use), + * roll back the UUID to the previous value and display an error message. + */ + if (err.status === 500) { + Message.error(this.$t('editor.warning.renameFailed')); + this.uuid = prevUuid; + this.processingRename = false; + console.log(this.configFileStructure); + return; + } }); - } }) - .catch((err) => { - /** If the server returns a 500 error for whatever reason (most likely due to file in use), - * roll back the UUID to the previous value and display an error message. - */ - if (err.status === 500) { - Message.error(this.$t('editor.warning.renameFailed')); - this.uuid = prevUuid; - this.processingRename = false; - console.log(this.configFileStructure); - return; - } + .catch(() => { + Message.error(this.$t('editor.warning.renameFailed')); + this.uuid = prevUuid; + this.processingRename = false; + console.log(this.configFileStructure); + this.lockStore.lockStoryline(this.uuid); // Lock original uuid again, since we previously unlocked it + return; }); } }