You've already forked AstralRinth
forked from xxxOFFxxx/AstralRinth
* feat: init selecting paper+purpur on purchase flow Signed-off-by: Evan Song <theevansong@gmail.com> * feat: properly implement Paper/Purpur in Platform Signed-off-by: Evan Song <theevansong@gmail.com> * chore: correct wording Signed-off-by: Evan Song <theevansong@gmail.com> * feat: redo platform modal Signed-off-by: Evan Song <theevansong@gmail.com> * Switch to HCaptcha for Auth-related captchas (#2945) * Switch to HCaptcha for Auth-related captchas * run fmt * fix hcaptcha not loading * fix: more robust loader dropdown logic Signed-off-by: Evan Song <theevansong@gmail.com> * fix: handle "not yet supported" install err Signed-off-by: Evan Song <theevansong@gmail.com> * chore: fix icon kerfuffles Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve vanilla install modal title Signed-off-by: Evan Song <theevansong@gmail.com> * fix: spacing Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve no loader state Signed-off-by: Evan Song <theevansong@gmail.com> * fix: type error Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust mod version modal title Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust modpack warning copy Signed-off-by: Evan Song <theevansong@gmail.com> * feat: vanilla empty state in content page Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust copy Signed-off-by: Evan Song <theevansong@gmail.com> * chore: update icon Signed-off-by: Evan Song <theevansong@gmail.com> * fix: loader type Signed-off-by: Evan Song <theevansong@gmail.com> * fix: loader type Signed-off-by: Evan Song <theevansong@gmail.com> * feat: always show dropdown if possible Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve spacing Signed-off-by: Evan Song <theevansong@gmail.com> * chore: appear disabled Signed-off-by: Evan Song <theevansong@gmail.com> * h Signed-off-by: Evan Song <theevansong@gmail.com> * chore: if reinstalling, show it on the modal title Signed-off-by: Evan Song <theevansong@gmail.com> * feat: put it in the dropdown, they said Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust style Signed-off-by: Evan Song <theevansong@gmail.com> * chore: sort paper-purpur versions desc Signed-off-by: Evan Song <theevansong@gmail.com> * fix: do not consider backup limit in reinstall prompt Signed-off-by: Evan Song <theevansong@gmail.com> * feat: backup locking, plugin support * fix: content type error Signed-off-by: Evan Song <theevansong@gmail.com> * fix: casing Signed-off-by: Evan Song <theevansong@gmail.com> * fix: plugins pt 2 * feat: backups, mrpack * fix: type errors come on Signed-off-by: Evan Song <theevansong@gmail.com> * fix: spacing Signed-off-by: Evan Song <theevansong@gmail.com> * fix: type maxing * chore: show copy button on allocation rows Signed-off-by: Evan Song <theevansong@gmail.com> * feat: suspend improvement --------- Signed-off-by: Evan Song <theevansong@gmail.com> Co-authored-by: Evan Song <theevansong@gmail.com> Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com> Co-authored-by: Jai A <jaiagr+gpg@pm.me> Co-authored-by: Evan Song <52982404+ferothefox@users.noreply.github.com>
202 lines
6.1 KiB
Vue
202 lines
6.1 KiB
Vue
<template>
|
|
<NewModal ref="modal" header="Editing auto backup settings">
|
|
<div class="flex flex-col gap-4 md:w-[600px]">
|
|
<div class="flex flex-col gap-2">
|
|
<div class="font-semibold text-contrast">Auto backup</div>
|
|
<p class="m-0">
|
|
Automatically create a backup of your server every
|
|
<strong>{{ autoBackupInterval == 1 ? "hour" : `${autoBackupInterval} hours` }}</strong>
|
|
</p>
|
|
</div>
|
|
|
|
<div v-if="isLoadingSettings" class="py-2 text-sm text-secondary">Loading settings...</div>
|
|
<template v-else>
|
|
<input
|
|
id="auto-backup-toggle"
|
|
v-model="autoBackupEnabled"
|
|
class="switch stylized-toggle"
|
|
type="checkbox"
|
|
:disabled="isSaving"
|
|
/>
|
|
|
|
<div class="flex flex-col gap-2">
|
|
<div class="font-semibold text-contrast">Interval</div>
|
|
<p class="m-0">
|
|
The amount of hours between each backup. This will only backup your server if it has
|
|
been modified since the last backup.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-2 text-contrast">
|
|
<div
|
|
class="flex w-fit items-center rounded-xl border border-solid border-button-border bg-table-alternateRow"
|
|
>
|
|
<button
|
|
class="rounded-l-xl p-3 text-secondary enabled:hover:text-contrast [&&]:bg-transparent enabled:[&&]:hover:bg-button-bg"
|
|
:disabled="!autoBackupEnabled || isSaving"
|
|
@click="autoBackupInterval = Math.max(autoBackupInterval - 1, 1)"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="2" viewBox="-2 0 18 2">
|
|
<path
|
|
d="M18,12H6"
|
|
transform="translate(-5 -11)"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
<input
|
|
id="auto-backup-interval"
|
|
v-model="autoBackupInterval"
|
|
class="w-16 !appearance-none text-center [&&]:bg-transparent [&&]:focus:shadow-none"
|
|
type="number"
|
|
style="-moz-appearance: textfield; appearance: none"
|
|
min="1"
|
|
max="24"
|
|
step="1"
|
|
:disabled="!autoBackupEnabled || isSaving"
|
|
/>
|
|
|
|
<button
|
|
class="rounded-r-xl p-3 text-secondary enabled:hover:text-contrast [&&]:bg-transparent enabled:[&&]:hover:bg-button-bg"
|
|
:disabled="!autoBackupEnabled || isSaving"
|
|
@click="autoBackupInterval = Math.min(autoBackupInterval + 1, 24)"
|
|
>
|
|
<PlusIcon />
|
|
</button>
|
|
</div>
|
|
{{ autoBackupInterval == 1 ? "hour" : "hours" }}
|
|
</div>
|
|
|
|
<div class="mt-4 flex justify-start gap-4">
|
|
<ButtonStyled color="brand">
|
|
<button :disabled="!hasChanges || isSaving" @click="saveSettings">
|
|
<SaveIcon class="h-5 w-5" />
|
|
{{ isSaving ? "Saving..." : "Save changes" }}
|
|
</button>
|
|
</ButtonStyled>
|
|
<ButtonStyled>
|
|
<button :disabled="isSaving" @click="modal?.hide()">
|
|
<XIcon />
|
|
Cancel
|
|
</button>
|
|
</ButtonStyled>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</NewModal>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ButtonStyled, NewModal } from "@modrinth/ui";
|
|
import { PlusIcon, XIcon, SaveIcon } from "@modrinth/assets";
|
|
import { ref, computed } from "vue";
|
|
import type { Server } from "~/composables/pyroServers";
|
|
|
|
const props = defineProps<{
|
|
server: Server<["backups"]>;
|
|
}>();
|
|
|
|
const modal = ref<InstanceType<typeof NewModal>>();
|
|
|
|
const initialSettings = ref<{ interval: number; enabled: boolean } | null>(null);
|
|
const autoBackupEnabled = ref(false);
|
|
const autoBackupInterval = ref(6);
|
|
const isLoadingSettings = ref(true);
|
|
const isSaving = ref(false);
|
|
|
|
const validatedBackupInterval = computed(() => {
|
|
const roundedValue = Math.round(autoBackupInterval.value);
|
|
|
|
if (roundedValue < 1) {
|
|
return 1;
|
|
} else if (roundedValue > 24) {
|
|
return 24;
|
|
}
|
|
return roundedValue;
|
|
});
|
|
|
|
const hasChanges = computed(() => {
|
|
if (!initialSettings.value) return false;
|
|
|
|
return (
|
|
autoBackupEnabled.value !== initialSettings.value.enabled ||
|
|
autoBackupInterval.value !== initialSettings.value.interval
|
|
);
|
|
});
|
|
|
|
const fetchSettings = async () => {
|
|
isLoadingSettings.value = true;
|
|
try {
|
|
const settings = await props.server.backups?.getAutoBackup();
|
|
initialSettings.value = settings as { interval: number; enabled: boolean };
|
|
autoBackupEnabled.value = settings?.enabled ?? false;
|
|
autoBackupInterval.value = settings?.interval || 6;
|
|
} catch (error) {
|
|
console.error("Error fetching backup settings:", error);
|
|
addNotification({
|
|
group: "server",
|
|
title: "Error",
|
|
text: "Failed to load backup settings",
|
|
type: "error",
|
|
});
|
|
} finally {
|
|
isLoadingSettings.value = false;
|
|
}
|
|
};
|
|
|
|
const saveSettings = async () => {
|
|
isSaving.value = true;
|
|
try {
|
|
await props.server.backups?.updateAutoBackup(
|
|
autoBackupEnabled.value ? "enable" : "disable",
|
|
autoBackupInterval.value,
|
|
);
|
|
|
|
initialSettings.value = {
|
|
enabled: autoBackupEnabled.value,
|
|
interval: autoBackupInterval.value,
|
|
};
|
|
|
|
addNotification({
|
|
group: "server",
|
|
title: "Success",
|
|
text: "Backup settings updated successfully",
|
|
type: "success",
|
|
});
|
|
|
|
modal.value?.hide();
|
|
} catch (error) {
|
|
console.error("Error saving backup settings:", error);
|
|
addNotification({
|
|
group: "server",
|
|
title: "Error",
|
|
text: "Failed to save backup settings",
|
|
type: "error",
|
|
});
|
|
} finally {
|
|
isSaving.value = false;
|
|
}
|
|
};
|
|
|
|
watch(autoBackupInterval, () => {
|
|
autoBackupInterval.value = validatedBackupInterval.value;
|
|
});
|
|
|
|
defineExpose({
|
|
show: async () => {
|
|
await fetchSettings();
|
|
modal.value?.show();
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.stylized-toggle:checked::after {
|
|
background: var(--color-accent-contrast) !important;
|
|
}
|
|
</style>
|