From dc7c8584f1d9062ab23f9be522a04ee5f7aa9b3c Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Tue, 30 Apr 2024 08:15:42 -0400 Subject: [PATCH] client: only submit changed settings to the server when changing settings --- client/src/components/RoomSettingsForm.vue | 48 +++++++++++++++------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/client/src/components/RoomSettingsForm.vue b/client/src/components/RoomSettingsForm.vue index d5dfbc1a6..c14dc4cb2 100644 --- a/client/src/components/RoomSettingsForm.vue +++ b/client/src/components/RoomSettingsForm.vue @@ -3,14 +3,14 @@
@@ -138,6 +138,7 @@ @click="submitRoomSettings" role="submit" :loading="isLoadingRoomSettings" + :disabled="dirtySettings.length === 0" data-cy="save" > {{ $t("common.save") }} @@ -155,19 +156,20 @@ import { API } from "@/common-http"; import { Visibility, QueueMode, RoomSettings, Role, BehaviorOption } from "ott-common/models/types"; import { Grants } from "ott-common/permissions"; import toast from "@/util/toast"; -import { onMounted, Ref, ref } from "vue"; +import { Ref, onMounted, reactive, ref, toRefs } from "vue"; import { useStore } from "@/store"; import { useI18n } from "vue-i18n"; import { OttApiResponseGetRoom } from "ott-common/models/rest-api"; import { ALL_SKIP_CATEGORIES } from "ott-common/constants"; import { useGrants } from "./composables/grants"; +import { watch } from "vue"; const store = useStore(); const { t } = useI18n(); const granted = useGrants(); const isLoadingRoomSettings = ref(false); -const inputRoomSettings = ref({ +const inputRoomSettings = reactive({ title: "", description: "", visibility: Visibility.Public, @@ -176,7 +178,17 @@ const inputRoomSettings = ref({ autoSkipSegmentCategories: Array.from([]), restoreQueueBehavior: BehaviorOption.Prompt, enableVoteSkip: false, -}) as Ref; +}); + +const settings = toRefs(inputRoomSettings); +const dirtySettings: Ref<(keyof RoomSettings)[]> = ref([]); +for (const key of Object.keys(inputRoomSettings) as (keyof RoomSettings)[]) { + watch(settings[key], () => { + if (!dirtySettings.value.includes(key)) { + dirtySettings.value.push(key); + } + }); +} onMounted(async () => { await loadRoomSettings(); @@ -202,8 +214,12 @@ async function loadRoomSettings() { isLoadingRoomSettings.value = true; try { const res = await API.get(`/room/${store.state.room.name}`); - inputRoomSettings.value = intoSettings(res.data); + Object.assign(inputRoomSettings, intoSettings(res.data)); + setTimeout(() => { + dirtySettings.value = []; + }, 0); } catch (err) { + console.error(err); toast.add({ content: t("room-settings.load-failed"), duration: 5000, @@ -225,11 +241,14 @@ function getRoomSettingsSubmit(): Partial { }; const blocked: (keyof RoomSettings)[] = []; for (const prop of Object.keys(propsToGrants)) { - if (!granted(`configure-room.${propsToGrants[prop]}`)) { + if ( + !dirtySettings.value.includes(prop as keyof typeof propsToGrants) || + !granted(`configure-room.${propsToGrants[prop]}`) + ) { blocked.push(prop as keyof typeof propsToGrants); } } - return _.omit(inputRoomSettings.value, blocked); + return _.omit(inputRoomSettings, blocked); } /** Take room settings from the UI and submit them to the server. */ @@ -242,6 +261,7 @@ async function submitRoomSettings() { content: t("room-settings.settings-applied").toString(), duration: 4000, }); + dirtySettings.value = []; } catch (e) { console.log(e); toast.add({