You've already forked AstralRinth
forked from didirus/AstralRinth
refactor: migrate to common eslint+prettier configs (#4168)
* refactor: migrate to common eslint+prettier configs * fix: prettier frontend * feat: config changes * fix: lint issues * fix: lint * fix: type imports * fix: cyclical import issue * fix: lockfile * fix: missing dep * fix: switch to tabs * fix: continue switch to tabs * fix: rustfmt parity * fix: moderation lint issue * fix: lint issues * fix: ui intl * fix: lint issues * Revert "fix: rustfmt parity" This reverts commit cb99d2376c321d813d4b7fc7e2a213bb30a54711. * feat: revert last rs
This commit is contained in:
@@ -1,345 +1,345 @@
|
||||
<script setup lang="ts">
|
||||
import dayjs from "dayjs";
|
||||
import {
|
||||
MoreVerticalIcon,
|
||||
HistoryIcon,
|
||||
DownloadIcon,
|
||||
SpinnerIcon,
|
||||
EditIcon,
|
||||
LockIcon,
|
||||
TrashIcon,
|
||||
FolderArchiveIcon,
|
||||
BotIcon,
|
||||
XIcon,
|
||||
LockOpenIcon,
|
||||
RotateCounterClockwiseIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { ButtonStyled, commonMessages, OverflowMenu, ProgressBar } from "@modrinth/ui";
|
||||
import { defineMessages, useVIntl } from "@vintl/vintl";
|
||||
import { ref, computed } from "vue";
|
||||
import type { Backup } from "@modrinth/utils";
|
||||
BotIcon,
|
||||
DownloadIcon,
|
||||
EditIcon,
|
||||
FolderArchiveIcon,
|
||||
HistoryIcon,
|
||||
LockIcon,
|
||||
LockOpenIcon,
|
||||
MoreVerticalIcon,
|
||||
RotateCounterClockwiseIcon,
|
||||
SpinnerIcon,
|
||||
TrashIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { ButtonStyled, commonMessages, OverflowMenu, ProgressBar } from '@modrinth/ui'
|
||||
import type { Backup } from '@modrinth/utils'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const flags = useFeatureFlags();
|
||||
const { formatMessage } = useVIntl();
|
||||
const flags = useFeatureFlags()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "prepare" | "download" | "rename" | "restore" | "lock" | "retry"): void;
|
||||
(e: "delete", skipConfirmation?: boolean): void;
|
||||
}>();
|
||||
(e: 'prepare' | 'download' | 'rename' | 'restore' | 'lock' | 'retry'): void
|
||||
(e: 'delete', skipConfirmation?: boolean): void
|
||||
}>()
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
backup: Backup;
|
||||
preview?: boolean;
|
||||
kyrosUrl?: string;
|
||||
jwt?: string;
|
||||
}>(),
|
||||
{
|
||||
preview: false,
|
||||
kyrosUrl: undefined,
|
||||
jwt: undefined,
|
||||
},
|
||||
);
|
||||
defineProps<{
|
||||
backup: Backup
|
||||
preview?: boolean
|
||||
kyrosUrl?: string
|
||||
jwt?: string
|
||||
}>(),
|
||||
{
|
||||
preview: false,
|
||||
kyrosUrl: undefined,
|
||||
jwt: undefined,
|
||||
},
|
||||
)
|
||||
|
||||
const backupQueued = computed(
|
||||
() =>
|
||||
props.backup.task?.create?.progress === 0 ||
|
||||
(props.backup.ongoing && !props.backup.task?.create),
|
||||
);
|
||||
const automated = computed(() => props.backup.automated);
|
||||
const failedToCreate = computed(() => props.backup.interrupted);
|
||||
() =>
|
||||
props.backup.task?.create?.progress === 0 ||
|
||||
(props.backup.ongoing && !props.backup.task?.create),
|
||||
)
|
||||
const automated = computed(() => props.backup.automated)
|
||||
const failedToCreate = computed(() => props.backup.interrupted)
|
||||
|
||||
const preparedDownloadStates = ["ready", "done"];
|
||||
const inactiveStates = ["failed", "cancelled"];
|
||||
const preparedDownloadStates = ['ready', 'done']
|
||||
const inactiveStates = ['failed', 'cancelled']
|
||||
|
||||
const hasPreparedDownload = computed(() => {
|
||||
const fileState = props.backup.task?.file?.state ?? "";
|
||||
return preparedDownloadStates.includes(fileState);
|
||||
});
|
||||
const fileState = props.backup.task?.file?.state ?? ''
|
||||
return preparedDownloadStates.includes(fileState)
|
||||
})
|
||||
|
||||
const creating = computed(() => {
|
||||
const task = props.backup.task?.create;
|
||||
if (task && task.progress < 1 && !inactiveStates.includes(task.state)) {
|
||||
return task;
|
||||
}
|
||||
if (props.backup.ongoing) {
|
||||
return {
|
||||
progress: 0,
|
||||
state: "ongoing",
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const task = props.backup.task?.create
|
||||
if (task && task.progress < 1 && !inactiveStates.includes(task.state)) {
|
||||
return task
|
||||
}
|
||||
if (props.backup.ongoing) {
|
||||
return {
|
||||
progress: 0,
|
||||
state: 'ongoing',
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
})
|
||||
|
||||
const restoring = computed(() => {
|
||||
const task = props.backup.task?.restore;
|
||||
if (task && task.progress < 1 && !inactiveStates.includes(task.state)) {
|
||||
return task;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const task = props.backup.task?.restore
|
||||
if (task && task.progress < 1 && !inactiveStates.includes(task.state)) {
|
||||
return task
|
||||
}
|
||||
return undefined
|
||||
})
|
||||
|
||||
const initiatedPrepare = ref(false);
|
||||
const initiatedPrepare = ref(false)
|
||||
|
||||
const preparingFile = computed(() => {
|
||||
if (hasPreparedDownload.value) {
|
||||
return false;
|
||||
}
|
||||
if (hasPreparedDownload.value) {
|
||||
return false
|
||||
}
|
||||
|
||||
const task = props.backup.task?.file;
|
||||
return (
|
||||
(!task && initiatedPrepare.value) ||
|
||||
(task && task.progress < 1 && !inactiveStates.includes(task.state))
|
||||
);
|
||||
});
|
||||
const task = props.backup.task?.file
|
||||
return (
|
||||
(!task && initiatedPrepare.value) ||
|
||||
(task && task.progress < 1 && !inactiveStates.includes(task.state))
|
||||
)
|
||||
})
|
||||
|
||||
const failedToRestore = computed(() => props.backup.task?.restore?.state === "failed");
|
||||
const failedToPrepareFile = computed(() => props.backup.task?.file?.state === "failed");
|
||||
const failedToRestore = computed(() => props.backup.task?.restore?.state === 'failed')
|
||||
const failedToPrepareFile = computed(() => props.backup.task?.file?.state === 'failed')
|
||||
|
||||
const messages = defineMessages({
|
||||
locked: {
|
||||
id: "servers.backups.item.locked",
|
||||
defaultMessage: "Locked",
|
||||
},
|
||||
lock: {
|
||||
id: "servers.backups.item.lock",
|
||||
defaultMessage: "Lock",
|
||||
},
|
||||
unlock: {
|
||||
id: "servers.backups.item.unlock",
|
||||
defaultMessage: "Unlock",
|
||||
},
|
||||
restore: {
|
||||
id: "servers.backups.item.restore",
|
||||
defaultMessage: "Restore",
|
||||
},
|
||||
rename: {
|
||||
id: "servers.backups.item.rename",
|
||||
defaultMessage: "Rename",
|
||||
},
|
||||
queuedForBackup: {
|
||||
id: "servers.backups.item.queued-for-backup",
|
||||
defaultMessage: "Queued for backup",
|
||||
},
|
||||
preparingDownload: {
|
||||
id: "servers.backups.item.preparing-download",
|
||||
defaultMessage: "Preparing download...",
|
||||
},
|
||||
prepareDownload: {
|
||||
id: "servers.backups.item.prepare-download",
|
||||
defaultMessage: "Prepare download",
|
||||
},
|
||||
prepareDownloadAgain: {
|
||||
id: "servers.backups.item.prepare-download-again",
|
||||
defaultMessage: "Try preparing again",
|
||||
},
|
||||
alreadyPreparing: {
|
||||
id: "servers.backups.item.already-preparing",
|
||||
defaultMessage: "Already preparing backup for download",
|
||||
},
|
||||
creatingBackup: {
|
||||
id: "servers.backups.item.creating-backup",
|
||||
defaultMessage: "Creating backup...",
|
||||
},
|
||||
restoringBackup: {
|
||||
id: "servers.backups.item.restoring-backup",
|
||||
defaultMessage: "Restoring from backup...",
|
||||
},
|
||||
failedToCreateBackup: {
|
||||
id: "servers.backups.item.failed-to-create-backup",
|
||||
defaultMessage: "Failed to create backup",
|
||||
},
|
||||
failedToRestoreBackup: {
|
||||
id: "servers.backups.item.failed-to-restore-backup",
|
||||
defaultMessage: "Failed to restore from backup",
|
||||
},
|
||||
failedToPrepareFile: {
|
||||
id: "servers.backups.item.failed-to-prepare-backup",
|
||||
defaultMessage: "Failed to prepare download",
|
||||
},
|
||||
automated: {
|
||||
id: "servers.backups.item.automated",
|
||||
defaultMessage: "Automated",
|
||||
},
|
||||
retry: {
|
||||
id: "servers.backups.item.retry",
|
||||
defaultMessage: "Retry",
|
||||
},
|
||||
});
|
||||
locked: {
|
||||
id: 'servers.backups.item.locked',
|
||||
defaultMessage: 'Locked',
|
||||
},
|
||||
lock: {
|
||||
id: 'servers.backups.item.lock',
|
||||
defaultMessage: 'Lock',
|
||||
},
|
||||
unlock: {
|
||||
id: 'servers.backups.item.unlock',
|
||||
defaultMessage: 'Unlock',
|
||||
},
|
||||
restore: {
|
||||
id: 'servers.backups.item.restore',
|
||||
defaultMessage: 'Restore',
|
||||
},
|
||||
rename: {
|
||||
id: 'servers.backups.item.rename',
|
||||
defaultMessage: 'Rename',
|
||||
},
|
||||
queuedForBackup: {
|
||||
id: 'servers.backups.item.queued-for-backup',
|
||||
defaultMessage: 'Queued for backup',
|
||||
},
|
||||
preparingDownload: {
|
||||
id: 'servers.backups.item.preparing-download',
|
||||
defaultMessage: 'Preparing download...',
|
||||
},
|
||||
prepareDownload: {
|
||||
id: 'servers.backups.item.prepare-download',
|
||||
defaultMessage: 'Prepare download',
|
||||
},
|
||||
prepareDownloadAgain: {
|
||||
id: 'servers.backups.item.prepare-download-again',
|
||||
defaultMessage: 'Try preparing again',
|
||||
},
|
||||
alreadyPreparing: {
|
||||
id: 'servers.backups.item.already-preparing',
|
||||
defaultMessage: 'Already preparing backup for download',
|
||||
},
|
||||
creatingBackup: {
|
||||
id: 'servers.backups.item.creating-backup',
|
||||
defaultMessage: 'Creating backup...',
|
||||
},
|
||||
restoringBackup: {
|
||||
id: 'servers.backups.item.restoring-backup',
|
||||
defaultMessage: 'Restoring from backup...',
|
||||
},
|
||||
failedToCreateBackup: {
|
||||
id: 'servers.backups.item.failed-to-create-backup',
|
||||
defaultMessage: 'Failed to create backup',
|
||||
},
|
||||
failedToRestoreBackup: {
|
||||
id: 'servers.backups.item.failed-to-restore-backup',
|
||||
defaultMessage: 'Failed to restore from backup',
|
||||
},
|
||||
failedToPrepareFile: {
|
||||
id: 'servers.backups.item.failed-to-prepare-backup',
|
||||
defaultMessage: 'Failed to prepare download',
|
||||
},
|
||||
automated: {
|
||||
id: 'servers.backups.item.automated',
|
||||
defaultMessage: 'Automated',
|
||||
},
|
||||
retry: {
|
||||
id: 'servers.backups.item.retry',
|
||||
defaultMessage: 'Retry',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
:class="
|
||||
preview
|
||||
? 'grid-cols-[min-content_1fr_1fr] sm:grid-cols-[min-content_3fr_2fr_1fr] md:grid-cols-[auto_3fr_2fr_1fr]'
|
||||
: 'grid-cols-[min-content_1fr_1fr] sm:grid-cols-[min-content_3fr_2fr_1fr] md:grid-cols-[auto_3fr_2fr_1fr_2fr]'
|
||||
"
|
||||
class="grid items-center gap-4 rounded-2xl bg-bg-raised px-4 py-3"
|
||||
>
|
||||
<div
|
||||
class="flex h-12 w-12 items-center justify-center rounded-xl border-[1px] border-solid border-button-border bg-button-bg"
|
||||
>
|
||||
<SpinnerIcon
|
||||
v-if="creating"
|
||||
class="h-6 w-6 animate-spin"
|
||||
:class="{ 'text-orange': backupQueued, 'text-green': !backupQueued }"
|
||||
/>
|
||||
<FolderArchiveIcon v-else class="h-6 w-6" />
|
||||
</div>
|
||||
<div class="col-span-2 flex flex-col gap-1 sm:col-span-1">
|
||||
<span class="font-bold text-contrast">
|
||||
{{ backup.name }}
|
||||
</span>
|
||||
<div class="flex flex-wrap items-center gap-2 text-sm">
|
||||
<span v-if="backup.locked" class="flex items-center gap-1 text-sm text-secondary">
|
||||
<LockIcon /> {{ formatMessage(messages.locked) }}
|
||||
</span>
|
||||
<span v-if="automated && backup.locked">•</span>
|
||||
<span v-if="automated" class="flex items-center gap-1 text-secondary">
|
||||
<BotIcon /> {{ formatMessage(messages.automated) }}
|
||||
</span>
|
||||
<span v-if="(failedToCreate || failedToRestore) && (automated || backup.locked)">•</span>
|
||||
<span
|
||||
v-if="failedToCreate || failedToRestore || failedToPrepareFile"
|
||||
class="flex items-center gap-1 text-sm text-red"
|
||||
>
|
||||
<XIcon />
|
||||
{{
|
||||
formatMessage(
|
||||
failedToCreate
|
||||
? messages.failedToCreateBackup
|
||||
: failedToRestore
|
||||
? messages.failedToRestoreBackup
|
||||
: messages.failedToPrepareFile,
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="creating" class="col-span-2 flex flex-col gap-3">
|
||||
<span v-if="backupQueued" class="text-orange">
|
||||
{{ formatMessage(messages.queuedForBackup) }}
|
||||
</span>
|
||||
<span v-else class="text-green"> {{ formatMessage(messages.creatingBackup) }} </span>
|
||||
<ProgressBar
|
||||
:progress="creating.progress"
|
||||
:color="backupQueued ? 'orange' : 'green'"
|
||||
:waiting="creating.progress === 0"
|
||||
class="max-w-full"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="restoring" class="col-span-2 flex flex-col gap-3 text-purple">
|
||||
{{ formatMessage(messages.restoringBackup) }}
|
||||
<ProgressBar
|
||||
:progress="restoring.progress"
|
||||
color="purple"
|
||||
:waiting="restoring.progress === 0"
|
||||
class="max-w-full"
|
||||
/>
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="col-span-2">
|
||||
{{ dayjs(backup.created_at).format("MMMM D, YYYY [at] h:mm A") }}
|
||||
</div>
|
||||
<div v-if="false">{{ 245 }} MiB</div>
|
||||
</template>
|
||||
<div
|
||||
v-if="!preview"
|
||||
class="col-span-full flex justify-normal gap-2 md:col-span-1 md:justify-end"
|
||||
>
|
||||
<template v-if="failedToCreate">
|
||||
<ButtonStyled>
|
||||
<button @click="() => emit('retry')">
|
||||
<RotateCounterClockwiseIcon />
|
||||
{{ formatMessage(messages.retry) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<button @click="() => emit('delete', true)">
|
||||
<TrashIcon />
|
||||
Remove
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
<ButtonStyled v-else-if="creating">
|
||||
<button @click="() => emit('delete')">
|
||||
<XIcon />
|
||||
{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<template v-else>
|
||||
<ButtonStyled>
|
||||
<a
|
||||
v-if="hasPreparedDownload"
|
||||
:class="{
|
||||
disabled: !kyrosUrl || !jwt,
|
||||
}"
|
||||
:href="`https://${kyrosUrl}/modrinth/v0/backups/${backup.id}/download?auth=${jwt}`"
|
||||
@click="() => emit('download')"
|
||||
>
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(commonMessages.downloadButton) }}
|
||||
</a>
|
||||
<button
|
||||
v-else
|
||||
:disabled="!!preparingFile"
|
||||
@click="
|
||||
() => {
|
||||
initiatedPrepare = true;
|
||||
emit('prepare');
|
||||
}
|
||||
"
|
||||
>
|
||||
<SpinnerIcon v-if="preparingFile" class="animate-spin" />
|
||||
<DownloadIcon v-else />
|
||||
{{
|
||||
formatMessage(
|
||||
preparingFile
|
||||
? messages.preparingDownload
|
||||
: failedToPrepareFile
|
||||
? messages.prepareDownloadAgain
|
||||
: messages.prepareDownload,
|
||||
)
|
||||
}}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled circular type="transparent">
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
{ id: 'rename', action: () => emit('rename') },
|
||||
{
|
||||
id: 'restore',
|
||||
action: () => emit('restore'),
|
||||
disabled: !!restoring || !!preparingFile,
|
||||
},
|
||||
{ id: 'lock', action: () => emit('lock') },
|
||||
{ divider: true },
|
||||
{
|
||||
id: 'delete',
|
||||
color: 'red',
|
||||
action: () => emit('delete'),
|
||||
disabled: !!restoring || !!preparingFile,
|
||||
},
|
||||
]"
|
||||
>
|
||||
<MoreVerticalIcon />
|
||||
<template #rename> <EditIcon /> {{ formatMessage(messages.rename) }} </template>
|
||||
<template #restore> <HistoryIcon /> {{ formatMessage(messages.restore) }} </template>
|
||||
<template v-if="backup.locked" #lock>
|
||||
<LockOpenIcon /> {{ formatMessage(messages.unlock) }}
|
||||
</template>
|
||||
<template v-else #lock> <LockIcon /> {{ formatMessage(messages.lock) }} </template>
|
||||
<template #delete>
|
||||
<TrashIcon /> {{ formatMessage(commonMessages.deleteLabel) }}
|
||||
</template>
|
||||
</OverflowMenu>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</div>
|
||||
<pre
|
||||
v-if="!preview && flags.advancedDebugInfo"
|
||||
class="col-span-full m-0 rounded-xl bg-button-bg text-xs"
|
||||
>{{ backup }}</pre
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
:class="
|
||||
preview
|
||||
? 'grid-cols-[min-content_1fr_1fr] sm:grid-cols-[min-content_3fr_2fr_1fr] md:grid-cols-[auto_3fr_2fr_1fr]'
|
||||
: 'grid-cols-[min-content_1fr_1fr] sm:grid-cols-[min-content_3fr_2fr_1fr] md:grid-cols-[auto_3fr_2fr_1fr_2fr]'
|
||||
"
|
||||
class="grid items-center gap-4 rounded-2xl bg-bg-raised px-4 py-3"
|
||||
>
|
||||
<div
|
||||
class="flex h-12 w-12 items-center justify-center rounded-xl border-[1px] border-solid border-button-border bg-button-bg"
|
||||
>
|
||||
<SpinnerIcon
|
||||
v-if="creating"
|
||||
class="h-6 w-6 animate-spin"
|
||||
:class="{ 'text-orange': backupQueued, 'text-green': !backupQueued }"
|
||||
/>
|
||||
<FolderArchiveIcon v-else class="h-6 w-6" />
|
||||
</div>
|
||||
<div class="col-span-2 flex flex-col gap-1 sm:col-span-1">
|
||||
<span class="font-bold text-contrast">
|
||||
{{ backup.name }}
|
||||
</span>
|
||||
<div class="flex flex-wrap items-center gap-2 text-sm">
|
||||
<span v-if="backup.locked" class="flex items-center gap-1 text-sm text-secondary">
|
||||
<LockIcon /> {{ formatMessage(messages.locked) }}
|
||||
</span>
|
||||
<span v-if="automated && backup.locked">•</span>
|
||||
<span v-if="automated" class="flex items-center gap-1 text-secondary">
|
||||
<BotIcon /> {{ formatMessage(messages.automated) }}
|
||||
</span>
|
||||
<span v-if="(failedToCreate || failedToRestore) && (automated || backup.locked)">•</span>
|
||||
<span
|
||||
v-if="failedToCreate || failedToRestore || failedToPrepareFile"
|
||||
class="flex items-center gap-1 text-sm text-red"
|
||||
>
|
||||
<XIcon />
|
||||
{{
|
||||
formatMessage(
|
||||
failedToCreate
|
||||
? messages.failedToCreateBackup
|
||||
: failedToRestore
|
||||
? messages.failedToRestoreBackup
|
||||
: messages.failedToPrepareFile,
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="creating" class="col-span-2 flex flex-col gap-3">
|
||||
<span v-if="backupQueued" class="text-orange">
|
||||
{{ formatMessage(messages.queuedForBackup) }}
|
||||
</span>
|
||||
<span v-else class="text-green"> {{ formatMessage(messages.creatingBackup) }} </span>
|
||||
<ProgressBar
|
||||
:progress="creating.progress"
|
||||
:color="backupQueued ? 'orange' : 'green'"
|
||||
:waiting="creating.progress === 0"
|
||||
class="max-w-full"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="restoring" class="col-span-2 flex flex-col gap-3 text-purple">
|
||||
{{ formatMessage(messages.restoringBackup) }}
|
||||
<ProgressBar
|
||||
:progress="restoring.progress"
|
||||
color="purple"
|
||||
:waiting="restoring.progress === 0"
|
||||
class="max-w-full"
|
||||
/>
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="col-span-2">
|
||||
{{ dayjs(backup.created_at).format('MMMM D, YYYY [at] h:mm A') }}
|
||||
</div>
|
||||
<div v-if="false">{{ 245 }} MiB</div>
|
||||
</template>
|
||||
<div
|
||||
v-if="!preview"
|
||||
class="col-span-full flex justify-normal gap-2 md:col-span-1 md:justify-end"
|
||||
>
|
||||
<template v-if="failedToCreate">
|
||||
<ButtonStyled>
|
||||
<button @click="() => emit('retry')">
|
||||
<RotateCounterClockwiseIcon />
|
||||
{{ formatMessage(messages.retry) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<button @click="() => emit('delete', true)">
|
||||
<TrashIcon />
|
||||
Remove
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
<ButtonStyled v-else-if="creating">
|
||||
<button @click="() => emit('delete')">
|
||||
<XIcon />
|
||||
{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<template v-else>
|
||||
<ButtonStyled>
|
||||
<a
|
||||
v-if="hasPreparedDownload"
|
||||
:class="{
|
||||
disabled: !kyrosUrl || !jwt,
|
||||
}"
|
||||
:href="`https://${kyrosUrl}/modrinth/v0/backups/${backup.id}/download?auth=${jwt}`"
|
||||
@click="() => emit('download')"
|
||||
>
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(commonMessages.downloadButton) }}
|
||||
</a>
|
||||
<button
|
||||
v-else
|
||||
:disabled="!!preparingFile"
|
||||
@click="
|
||||
() => {
|
||||
initiatedPrepare = true
|
||||
emit('prepare')
|
||||
}
|
||||
"
|
||||
>
|
||||
<SpinnerIcon v-if="preparingFile" class="animate-spin" />
|
||||
<DownloadIcon v-else />
|
||||
{{
|
||||
formatMessage(
|
||||
preparingFile
|
||||
? messages.preparingDownload
|
||||
: failedToPrepareFile
|
||||
? messages.prepareDownloadAgain
|
||||
: messages.prepareDownload,
|
||||
)
|
||||
}}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled circular type="transparent">
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
{ id: 'rename', action: () => emit('rename') },
|
||||
{
|
||||
id: 'restore',
|
||||
action: () => emit('restore'),
|
||||
disabled: !!restoring || !!preparingFile,
|
||||
},
|
||||
{ id: 'lock', action: () => emit('lock') },
|
||||
{ divider: true },
|
||||
{
|
||||
id: 'delete',
|
||||
color: 'red',
|
||||
action: () => emit('delete'),
|
||||
disabled: !!restoring || !!preparingFile,
|
||||
},
|
||||
]"
|
||||
>
|
||||
<MoreVerticalIcon />
|
||||
<template #rename> <EditIcon /> {{ formatMessage(messages.rename) }} </template>
|
||||
<template #restore> <HistoryIcon /> {{ formatMessage(messages.restore) }} </template>
|
||||
<template v-if="backup.locked" #lock>
|
||||
<LockOpenIcon /> {{ formatMessage(messages.unlock) }}
|
||||
</template>
|
||||
<template v-else #lock> <LockIcon /> {{ formatMessage(messages.lock) }} </template>
|
||||
<template #delete>
|
||||
<TrashIcon /> {{ formatMessage(commonMessages.deleteLabel) }}
|
||||
</template>
|
||||
</OverflowMenu>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</div>
|
||||
<pre
|
||||
v-if="!preview && flags.advancedDebugInfo"
|
||||
class="col-span-full m-0 rounded-xl bg-button-bg text-xs"
|
||||
>{{ backup }}</pre
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user