Fixes MOD-160 (#2948)

* fix: refresh backups automatically when ongoing backups are running

Signed-off-by: Evan Song <theevansong@gmail.com>

* chore: improve backup creation rate limit msg

Signed-off-by: Evan Song <theevansong@gmail.com>

* chore: increase polling timeout

Signed-off-by: Evan Song <theevansong@gmail.com>

* chore: clean

Signed-off-by: Evan Song <theevansong@gmail.com>

* chore: add notice of automatic refresh

Signed-off-by: Evan Song <theevansong@gmail.com>

---------

Signed-off-by: Evan Song <theevansong@gmail.com>
This commit is contained in:
Evan Song 2024-11-17 19:59:01 -07:00 committed by GitHub
parent a1a920ee67
commit 1f230383ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 5 deletions

View File

@ -17,6 +17,9 @@
<span class="font-semibold"> Backup #{{ newBackupAmount }}</span>
</span>
</div>
<div v-if="isRateLimited" class="mt-2 text-sm text-red">
You're creating backups too fast. Please wait a moment before trying again.
</div>
</div>
<div class="mb-1 mt-4 flex justify-start gap-4">
<ButtonStyled color="brand">
@ -36,10 +39,9 @@
</template>
<script setup lang="ts">
import { ref, nextTick } from "vue";
import { ref, nextTick, computed } from "vue";
import { ButtonStyled, NewModal } from "@modrinth/ui";
import { PlusIcon, XIcon, InfoIcon } from "@modrinth/assets";
import type { Server } from "~/composables/pyroServers";
const props = defineProps<{
server: Server<["general", "mods", "backups", "network", "startup", "ws", "fs"]>;
@ -50,6 +52,7 @@ const emit = defineEmits(["backupCreated"]);
const modal = ref<InstanceType<typeof NewModal>>();
const input = ref<HTMLInputElement>();
const isCreating = ref(false);
const isRateLimited = ref(false);
const backupError = ref<string | null>(null);
const backupName = ref("");
const newBackupAmount = computed(() =>
@ -75,14 +78,20 @@ const createBackup = async () => {
}
isCreating.value = true;
isRateLimited.value = false;
try {
await props.server.backups?.create(backupName.value);
await props.server.refresh();
hideModal();
emit("backupCreated", { success: true, message: "Backup created successfully" });
} catch (error) {
backupError.value = error instanceof Error ? error.message : String(error);
emit("backupCreated", { success: false, message: backupError.value });
if (error instanceof PyroFetchError && error.statusCode === 429) {
isRateLimited.value = true;
backupError.value = "You're creating backups too fast.";
} else {
backupError.value = error instanceof Error ? error.message : String(error);
emit("backupCreated", { success: false, message: backupError.value });
}
} finally {
isCreating.value = false;
}

View File

@ -66,7 +66,11 @@
: ''
"
class="w-full sm:w-fit"
:disabled="isServerRunning && !userPreferences.backupWhileRunning"
:disabled="
(isServerRunning && !userPreferences.backupWhileRunning) ||
data.used_backup_quota >= data.backup_quota ||
backups.some((backup) => backup.ongoing)
"
@click="showCreateModel"
>
<PlusIcon class="h-5 w-5" />
@ -77,6 +81,15 @@
</div>
</div>
<div
v-if="backups.some((backup) => backup.ongoing)"
data-pyro-server-backup-ongoing
class="flex w-full flex-row items-center gap-4 rounded-2xl bg-bg-orange p-4 text-contrast"
>
A backup is currently being created. This may take a few minutes. This page will
automatically refresh when the backup is complete.
</div>
<li
v-for="(backup, index) in backups"
:key="backup.id"
@ -246,6 +259,8 @@ const backupSettingsModal = ref<typeof NewModal>();
const renameBackupName = ref("");
const currentBackup = ref("");
const refreshInterval = ref<ReturnType<typeof setInterval>>();
const currentBackupDetails = computed(() => {
return backups.value.find((backup) => backup.id === currentBackup.value);
});
@ -319,6 +334,29 @@ const initiateDownload = async (backupId: string) => {
console.error("Download failed:", error);
}
};
onMounted(() => {
watchEffect(() => {
const hasOngoingBackups = backups.value.some((backup) => backup.ongoing);
if (refreshInterval.value) {
clearInterval(refreshInterval.value);
refreshInterval.value = undefined;
}
if (hasOngoingBackups) {
refreshInterval.value = setInterval(() => {
props.server.refresh(["backups"]);
}, 10000);
}
});
});
onUnmounted(() => {
if (refreshInterval.value) {
clearInterval(refreshInterval.value);
}
});
</script>
<style scoped>