Forráskód Böngészése

refactor: converted VueX settings store to Pinia store

Kristian Vos 2 éve
szülő
commit
89d492d3ec

+ 3 - 2
frontend/src/components/modals/RemoveAccount.vue

@@ -4,11 +4,13 @@ import { ref, onMounted } from "vue";
 import { useRoute } from "vue-router";
 import Toast from "toasters";
 import { useModalState } from "@/vuex_helpers";
+import { useSettingsStore } from "@/stores/settings";
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" }
 });
 
+const settingsStore = useSettingsStore();
 const route = useRoute();
 
 const store = useStore();
@@ -22,8 +24,7 @@ const { githubLinkConfirmed } = useModalState(
 	}
 );
 
-const isPasswordLinked = () => store.dispatch("settings/isPasswordLinked");
-const isGithubLinked = () => store.dispatch("settings/isGithubLinked");
+const { isPasswordLinked, isGithubLinked } = settingsStore;
 const closeCurrentModal = () =>
 	store.dispatch("modalVisibility/closeCurrentModal");
 

+ 11 - 12
frontend/src/pages/Settings/Tabs/Account.vue

@@ -10,6 +10,7 @@ import {
 import { useStore } from "vuex";
 import { useRoute } from "vue-router";
 import Toast from "toasters";
+import { useSettingsStore } from "@/stores/settings";
 
 import _validation from "@/validation";
 
@@ -20,6 +21,7 @@ const SaveButton = defineAsyncComponent(
 	() => import("@/components/SaveButton.vue")
 );
 
+const settingsStore = useSettingsStore();
 const store = useStore();
 const route = useRoute();
 
@@ -28,8 +30,7 @@ const { socket } = store.state.websockets;
 const saveButton = ref();
 
 const userId = computed(() => store.state.user.auth.userId);
-const originalUser = computed(() => store.state.settings.originalUser);
-const modifiedUser = computed(() => store.state.settings.modifiedUser);
+const { originalUser, modifiedUser } = settingsStore;
 
 const validation = reactive({
 	username: {
@@ -44,8 +45,7 @@ const validation = reactive({
 	}
 });
 
-const updateOriginalUser = payload =>
-	store.dispatch("settings/updateOriginalUser", payload);
+const { updateOriginalUser } = settingsStore;
 const openModal = payload =>
 	store.dispatch("modalVisibility/openModal", payload);
 
@@ -54,7 +54,7 @@ const onInput = inputName => {
 };
 
 const changeEmail = () => {
-	const email = modifiedUser.value.email.address;
+	const email = modifiedUser.email.address;
 	if (!_validation.isLength(email, 3, 254))
 		return new Toast("Email must have between 3 and 254 characters.");
 	if (
@@ -83,7 +83,7 @@ const changeEmail = () => {
 };
 
 const changeUsername = () => {
-	const { username } = modifiedUser.value;
+	const { username } = modifiedUser;
 
 	if (!_validation.isLength(username, 2, 32))
 		return new Toast("Username must have between 2 and 32 characters.");
@@ -123,10 +123,9 @@ const changeUsername = () => {
 };
 
 const saveChanges = () => {
-	const usernameChanged =
-		modifiedUser.value.username !== originalUser.value.username;
+	const usernameChanged = modifiedUser.username !== originalUser.username;
 	const emailAddressChanged =
-		modifiedUser.value.email.address !== originalUser.value.email.address;
+		modifiedUser.email.address !== originalUser.email.address;
 
 	if (usernameChanged) changeUsername();
 
@@ -158,7 +157,7 @@ onMounted(() => {
 });
 
 watch(
-	() => modifiedUser.value.username,
+	() => modifiedUser.username,
 	value => {
 		// const value = newModifiedUser.username;
 
@@ -168,7 +167,7 @@ watch(
 			validation.username.valid = false;
 		} else if (
 			!_validation.regex.azAZ09_.test(value) &&
-			value !== originalUser.value.username // Sometimes a username pulled from GitHub won't succeed validation
+			value !== originalUser.username // Sometimes a username pulled from GitHub won't succeed validation
 		) {
 			validation.username.message =
 				"Invalid format. Allowed characters: a-z, A-Z, 0-9 and _.";
@@ -185,7 +184,7 @@ watch(
 );
 
 watch(
-	() => modifiedUser.value.email.address,
+	() => modifiedUser.email.address,
 	value => {
 		// const value = newModifiedUser.email.address;
 

+ 14 - 18
frontend/src/pages/Settings/Tabs/Profile.vue

@@ -2,7 +2,7 @@
 import { defineAsyncComponent, ref, computed } from "vue";
 import { useStore } from "vuex";
 import Toast from "toasters";
-
+import { useSettingsStore } from "@/stores/settings";
 import validation from "@/validation";
 
 const ProfilePicture = defineAsyncComponent(
@@ -12,6 +12,7 @@ const SaveButton = defineAsyncComponent(
 	() => import("@/components/SaveButton.vue")
 );
 
+const settingsStore = useSettingsStore();
 const store = useStore();
 
 const { socket } = store.state.websockets;
@@ -19,17 +20,13 @@ const { socket } = store.state.websockets;
 const saveButton = ref();
 
 const userId = computed(() => store.state.user.auth.userId);
-const originalUser = computed(() => store.state.settings.originalUser);
-const modifiedUser = computed(() => store.state.settings.modifiedUser);
+const { originalUser, modifiedUser } = settingsStore;
 
-const updateOriginalUser = payload =>
-	store.dispatch("settings/updateOriginalUser", payload);
+const { updateOriginalUser } = settingsStore;
 
 const changeName = () => {
-	modifiedUser.value.name = modifiedUser.value.name
-		.replaceAll(/ +/g, " ")
-		.trim();
-	const { name } = modifiedUser.value;
+	modifiedUser.name = modifiedUser.name.replaceAll(/ +/g, " ").trim();
+	const { name } = modifiedUser;
 
 	if (!validation.isLength(name, 1, 64))
 		return new Toast("Name must have between 1 and 64 characters.");
@@ -63,7 +60,7 @@ const changeName = () => {
 };
 
 const changeLocation = () => {
-	const { location } = modifiedUser.value;
+	const { location } = modifiedUser;
 
 	if (!validation.isLength(location, 0, 50))
 		return new Toast("Location must have between 0 and 50 characters.");
@@ -93,7 +90,7 @@ const changeLocation = () => {
 };
 
 const changeBio = () => {
-	const { bio } = modifiedUser.value;
+	const { bio } = modifiedUser;
 
 	if (!validation.isLength(bio, 0, 200))
 		return new Toast("Bio must have between 0 and 200 characters.");
@@ -118,7 +115,7 @@ const changeBio = () => {
 };
 
 const changeAvatar = () => {
-	const { avatar } = modifiedUser.value;
+	const { avatar } = modifiedUser;
 
 	saveButton.value.status = "disabled";
 
@@ -140,13 +137,12 @@ const changeAvatar = () => {
 };
 
 const saveChanges = () => {
-	const nameChanged = modifiedUser.value.name !== originalUser.value.name;
-	const locationChanged =
-		modifiedUser.value.location !== originalUser.value.location;
-	const bioChanged = modifiedUser.value.bio !== originalUser.value.bio;
+	const nameChanged = modifiedUser.name !== originalUser.name;
+	const locationChanged = modifiedUser.location !== originalUser.location;
+	const bioChanged = modifiedUser.bio !== originalUser.bio;
 	const avatarChanged =
-		modifiedUser.value.avatar.type !== originalUser.value.avatar.type ||
-		modifiedUser.value.avatar.color !== originalUser.value.avatar.color;
+		modifiedUser.avatar.type !== originalUser.avatar.type ||
+		modifiedUser.avatar.color !== originalUser.avatar.color;
 
 	if (nameChanged) changeName();
 	if (locationChanged) changeLocation();

+ 3 - 10
frontend/src/pages/Settings/Tabs/Security.vue

@@ -8,8 +8,8 @@ import {
 	onMounted
 } from "vue";
 import { useStore } from "vuex";
-
 import Toast from "toasters";
+import { useSettingsStore } from "@/stores/settings";
 
 import _validation from "@/validation";
 
@@ -17,6 +17,7 @@ const InputHelpBox = defineAsyncComponent(
 	() => import("@/components/InputHelpBox.vue")
 );
 
+const settingsStore = useSettingsStore();
 const store = useStore();
 
 const { socket } = store.state.websockets;
@@ -44,15 +45,7 @@ const validation = reactive({
 const newPassword = ref();
 const oldPassword = ref();
 
-// TODO fix, getters are broken
-// const isPasswordLinked = computed(() => store.state.settings.isPasswordLinked);
-// const isGithubLinked = computed(() => store.state.settings.isGithubLinked);
-const isPasswordLinked = computed(
-	() => !!store.state.settings.originalUser.password
-);
-const isGithubLinked = computed(
-	() => !!store.state.settings.originalUser.github
-);
+const { isPasswordLinked, isGithubLinked } = settingsStore;
 const userId = computed(() => store.state.user.auth.userId);
 
 const togglePasswordVisibility = refName => {

+ 3 - 4
frontend/src/pages/Settings/index.vue

@@ -3,6 +3,7 @@ import { useStore } from "vuex";
 import { useRoute } from "vue-router";
 import { onMounted, defineAsyncComponent } from "vue";
 import Toast from "toasters";
+import { useSettingsStore } from "@/stores/settings";
 import ws from "@/ws";
 
 import useTabQueryHandler from "@/composables/useTabQueryHandler";
@@ -20,16 +21,14 @@ const PreferencesSettings = defineAsyncComponent(
 	() => import("./Tabs/Preferences.vue")
 );
 
+const settingsStore = useSettingsStore();
 const store = useStore();
 const route = useRoute();
 const { tab, showTab } = useTabQueryHandler("");
 
 const { socket } = store.state.websockets;
 
-const setUser = payload => store.dispatch("settings/setUser", payload);
-
-const updateOriginalUser = payload =>
-	store.dispatch("settings/updateOriginalUser", payload);
+const { setUser, updateOriginalUser } = settingsStore;
 
 const init = () => {
 	socket.dispatch("users.findBySession", res => {

+ 0 - 2
frontend/src/store/index.ts

@@ -4,7 +4,6 @@ import { createStore } from "vuex";
 import websockets from "./modules/websockets";
 
 import user from "./modules/user";
-import settings from "./modules/settings";
 import modalVisibility from "./modules/modalVisibility";
 import station from "./modules/station";
 import admin from "./modules/admin";
@@ -18,7 +17,6 @@ export default createStore({
 	modules: {
 		websockets,
 		user,
-		settings,
 		station,
 		admin,
 		modalVisibility,

+ 0 - 49
frontend/src/store/modules/settings.ts

@@ -1,49 +0,0 @@
-/* eslint no-param-reassign: 0 */
-
-const state = {
-	originalUser: {},
-	modifiedUser: {}
-};
-
-const getters = {
-	isGithubLinked: state => state.originalUser.github,
-	isPasswordLinked: state => state.originalUser.password
-};
-
-const actions = {
-	updateOriginalUser: ({ commit }, payload) => {
-		commit("updateOriginalUser", payload);
-	},
-	setUser: ({ commit }, user) => {
-		commit("setUser", user);
-	}
-};
-
-const mutations = {
-	updateOriginalUser(state, payload) {
-		const { property, value } = payload;
-
-		property.split(".").reduce(
-			// eslint-disable-next-line no-return-assign
-			(o, p, i) =>
-				(o[p] =
-					// eslint-disable-next-line no-plusplus
-					property.split(".").length === ++i
-						? JSON.parse(JSON.stringify(value))
-						: o[p] || {}),
-			state.originalUser
-		);
-	},
-	setUser(state, user) {
-		state.originalUser = user;
-		state.modifiedUser = JSON.parse(JSON.stringify(user));
-	}
-};
-
-export default {
-	namespaced: true,
-	state,
-	getters,
-	actions,
-	mutations
-};

+ 36 - 0
frontend/src/stores/settings.ts

@@ -0,0 +1,36 @@
+/* eslint no-param-reassign: 0 */
+
+import { defineStore } from "pinia";
+
+// TODO fix/decide eslint rule properly
+// eslint-disable-next-line
+export const useSettingsStore = defineStore("settings", {
+	state: () => ({
+		originalUser: {},
+		modifiedUser: {}
+	}),
+	actions: {
+		updateOriginalUser(payload) {
+			const { property, value } = payload;
+
+			property.split(".").reduce(
+				// eslint-disable-next-line no-return-assign
+				(o, p, i) =>
+					(o[p] =
+						// eslint-disable-next-line no-plusplus
+						property.split(".").length === ++i
+							? JSON.parse(JSON.stringify(value))
+							: o[p] || {}),
+				this.originalUser
+			);
+		},
+		setUser(user) {
+			this.originalUser = user;
+			this.modifiedUser = JSON.parse(JSON.stringify(user));
+		}
+	},
+	getters: {
+		isGithubLinked: state => state.originalUser.github,
+		isPasswordLinked: state => state.originalUser.password
+	}
+});