Browse Source

feat: added ability to convert multiple accounts at once

Kristian Vos 4 years ago
parent
commit
f961272c13

+ 50 - 10
backend/logic/account.js

@@ -86,20 +86,21 @@ module.exports = class extends coreClass {
 			try { await this._validateHook(); } catch { return; }
 			if (!accountId) return reject(new Error("Account ID invalid."));
 
-			let oldAccount = await this.getById(accountId);
+			let oldAccount;
+			try { oldAccount = await this.getById(accountId); } catch { return reject("Couldn't get account."); }
+
+			let latestVersion;
+			try { latestVersion = (await this.accountSchemaModule.getLatest()).version; } catch { return reject("Couldn't get latest schema.");  }
 
-			const latestVersion = (await this.accountSchemaModule.getLatest()).version;
 			if (oldAccount.version === latestVersion) return reject(new Error("Account is already up-to-date"));
 
 			let convertSchema;
-			try {
-				convertSchema = await this.convertSchemaModule.getForVersion(oldAccount.version);
-			} catch(err) {
-				reject(err);
-			}
-
-			let oldSchema = await this.accountSchemaModule.getByVersion(convertSchema.versionFrom);
-			let newSchema = await this.accountSchemaModule.getByVersion(convertSchema.versionTo);
+			try { convertSchema = await this.convertSchemaModule.getForVersion(oldAccount.version); } catch(err) { reject(err); }
+
+			let oldSchema;
+			try { oldSchema = await this.accountSchemaModule.getByVersion(convertSchema.versionFrom); } catch  { return reject("Couldn't get from schema."); }
+			let newSchema;
+			try { newSchema = await this.accountSchemaModule.getByVersion(convertSchema.versionTo) } catch { return reject("Couldn't get new schema"); }
 			
 			let defaultNewObjects = {};
 			let newAccount = {
@@ -175,4 +176,43 @@ module.exports = class extends coreClass {
 			resolve(newAccount);
 		});
 	}
+
+	async migrateAccounts(accountIds) {
+		return new Promise(async (resolve, reject) => {
+			try { await this._validateHook(); } catch { return; }
+
+			let successful = 0;
+			let failed = 0;
+
+			async.eachLimit(
+				accountIds,
+				10,
+				(accountId, next) => {
+					this.getMigratedAccount(accountId).then(account => {
+						if (!account) {
+							failed++;
+							return next();
+						}
+
+						this.editById(accountId, account).then(() => {
+							successful++;
+							return next();
+						}).catch(err => {
+							failed++;
+							return next();
+						});
+					}).catch(err => {
+						failed++;
+						return next();
+					});
+				},
+				(err) => {
+					resolve({
+						successful,
+						failed
+					});
+				}
+			);
+		});
+	}
 }

+ 15 - 0
backend/logic/io/namespaces/account.js

@@ -45,6 +45,21 @@ module.exports = {
 		});
 	},
 
+	"migrateAccounts": (cb, accountIds) => {
+		accountModule.migrateAccounts(accountIds).then(res => {
+			cb({
+				status: "success",
+				failed: res.failed,
+				successful: res.successful
+			});
+		}).catch(err => {
+			cb({
+				status: "failure",
+				message: err.message
+			});
+		});
+	},
+
 	"add": (cb, account) => {
 		accountModule.add(account).then(() => {
 			console.log("Added account!");

+ 50 - 0
frontend/vue/pages/ConvertAccounts.vue

@@ -12,6 +12,9 @@
 			:sort-order="sortOrder"
 			:data="localData"
 		>
+			<div slot="select-slot" slot-scope="props">
+				<div tabindex="0" name="name" class="checkbox" @click="toggleCheckbox(props.data.accountId)" v-on:keyup.enter="toggleCheckbox(props.data.accountId)" v-on:keyup.space="toggleCheckbox(props.data.accountId)" :class="{ checked: selectedAccounts.indexOf(props.data.accountId) !== -1 }"></div>
+			</div>
 			<div slot="actions-slot" slot-scope="props">
 				<router-link
 					:to="`/convert/${props.data.accountId}`"
@@ -21,6 +24,9 @@
 				</router-link>
 			</div>
 		</data-table>
+		<br/>
+		<br/>
+		<button @click="convertAccounts()" v-if="!convertingAccounts" class="button">Migrate accounts</button>
 	</main>
 </template>
 
@@ -34,7 +40,13 @@ export default {
 	data: () => {
 		return {
 			accounts: [],
+			selectedAccounts: [],
+			convertingAccounts: false,
 			fields: [
+				{
+					name: "select-slot",
+					displayName: ""
+				},
 				{
 					name: "name",
 					displayName: "Name"
@@ -78,6 +90,19 @@ export default {
 				console.log(res);
 				alert(res.status);
 			});
+		},
+		convertAccounts() {
+			this.convertingAccounts = true;
+			this.socket.emit("account.migrateAccounts", this.selectedAccounts, (res) => {
+				console.log(res);
+				alert(`Migrated accounts. Successful: ${res.successful}; failed: ${res.failed}`);
+				location.reload();
+			});
+		},
+		toggleCheckbox(accountId) {
+			const selectedAccountIndex = this.selectedAccounts.indexOf(accountId);
+			if (selectedAccountIndex === -1) this.selectedAccounts.push(accountId);
+			else this.selectedAccounts.splice(selectedAccountIndex, 1);
 		}
 	},
 	mounted() {
@@ -94,5 +119,30 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+.checkbox {
+	height: 32px;
+	width: 32px;
+	background-color: white;
+	border: .5px #464646 solid;
+	border-radius: 3px;
+	cursor: pointer;
+	position: relative;
+	box-sizing: border-box;
+
+	&.disabled {
+		cursor:auto;
+	}
+}
 
+.checkbox.checked::after {
+	content: "";
+	width: 26px;
+	height: 26px;
+	left: 2px;
+	top: 2px;
+	display: inline-block;
+	position: absolute;
+	border-radius: 3px;
+	background-color: #69B862;
+}
 </style>