瀏覽代碼

refactor: Add save button handling to useForm

Owen Diffey 4 周之前
父節點
當前提交
a769fb4df2
共有 2 個文件被更改,包括 27 次插入12 次删除
  1. 9 10
      frontend/src/components/modals/EditNews.vue
  2. 18 2
      frontend/src/composables/useForm.ts

+ 9 - 10
frontend/src/components/modals/EditNews.vue

@@ -64,7 +64,7 @@ const getTitle = () => {
 	return title;
 };
 
-const { inputs, save, setModelValues } = useForm(
+const { inputs, saveButton, save, setModelValues } = useForm(
 	{
 		markdown: {
 			value: "# Header\n## Sub-Header\n- **So**\n- _Many_\n- ~Points~\n\nOther things you want to say and [link](https://example.com).\n\n### Sub-Sub-Header\n> Oh look, a quote!\n\n`lil code`\n\n```\nbig code\n```\n",
@@ -156,23 +156,21 @@ onMounted(async () => {
 		<template #body>
 			<div class="left-section" v-show="canShow">
 				<p><strong>Markdown</strong></p>
-				<textarea v-model="inputs['markdown'].value"></textarea>
+				<textarea v-model="inputs.markdown.value"></textarea>
 			</div>
 			<div class="right-section" v-show="canShow">
 				<p><strong>Preview</strong></p>
 				<div
 					class="news-item"
 					id="preview"
-					v-html="
-						DOMPurify.sanitize(marked(inputs['markdown'].value))
-					"
+					v-html="DOMPurify.sanitize(marked(inputs.markdown.value))"
 				></div>
 			</div>
 		</template>
 		<template #footer>
 			<div>
 				<p class="control select">
-					<select v-model="inputs['status'].value">
+					<select v-model="inputs.status.value">
 						<option value="draft">Draft</option>
 						<option value="published" selected>Publish</option>
 					</select>
@@ -183,7 +181,7 @@ onMounted(async () => {
 						<input
 							type="checkbox"
 							id="show-to-new-users"
-							v-model="inputs['showToNewUsers'].value"
+							v-model="inputs.showToNewUsers.value"
 						/>
 						<span class="slider round"></span>
 					</label>
@@ -193,17 +191,18 @@ onMounted(async () => {
 					</label>
 				</p>
 
-				<save-button
-					ref="saveButton"
+				<SaveButton
 					v-if="createNews"
+					ref="saveButton"
 					@clicked="save()"
 				/>
 
-				<save-button
+				<SaveButton
 					ref="saveAndCloseButton"
 					default-message="Save and close"
 					@clicked="save(closeCurrentModal)"
 				/>
+
 				<div class="right" v-if="createdAt > 0">
 					<span>
 						By&nbsp;

+ 18 - 2
frontend/src/composables/useForm.ts

@@ -72,6 +72,8 @@ export const useForm = (
 		return _sourceChanged;
 	});
 
+	const saveButton = ref();
+
 	const useCallback = (status: string, messages?: Record<string, string>) =>
 		new Promise((resolve, reject: (reason: Error) => void) => {
 			cb(
@@ -129,17 +131,25 @@ export const useForm = (
 	};
 
 	const save = (saveCb?: () => void) => {
+		if (saveButton.value) saveButton.value.status = "disabled";
+
 		const errors = validate();
 		const errorCount = Object.keys(errors).length;
+
 		if (errorCount === 0 && unsavedChanges.value.length > 0) {
 			const onSave = () => {
 				useCallback("success")
 					.then(() => {
 						resetOriginalValues();
 						if (saveCb) saveCb();
+						saveButton.value?.handleSuccessfulSave();
 					})
 					.catch((err: Error) =>
-						useCallback("error", { error: err.message })
+						useCallback("error", { error: err.message }).then(
+							() => {
+								saveButton.value?.handleFailedSave();
+							}
+						)
 					);
 			};
 			if (sourceChanged.value.length > 0)
@@ -156,9 +166,12 @@ export const useForm = (
 			useCallback("unchanged", { unchanged: "No changes have been made" })
 				.then(() => {
 					if (saveCb) saveCb();
+					saveButton.value?.handleSuccessfulSave();
 				})
 				.catch((err: Error) =>
-					useCallback("error", { error: err.message })
+					useCallback("error", { error: err.message }).then(() => {
+						saveButton.value?.handleFailedSave();
+					})
 				);
 		} else {
 			useCallback("error", {
@@ -166,6 +179,8 @@ export const useForm = (
 				error: `${errorCount} ${
 					errorCount === 1 ? "input" : "inputs"
 				} failed validation.`
+			}).then(() => {
+				saveButton.value?.handleFailedSave();
 			});
 		}
 	};
@@ -251,6 +266,7 @@ export const useForm = (
 	return {
 		inputs,
 		unsavedChanges,
+		saveButton,
 		save,
 		setValue,
 		setOriginalValue,