Files
pocketbase/ui/src/components/settings/BackupCreatePanel.svelte
2023-05-22 07:50:42 +03:00

139 lines
3.9 KiB
Svelte

<script>
import { createEventDispatcher, onDestroy } from "svelte";
import ApiClient from "@/utils/ApiClient";
import CommonHelper from "@/utils/CommonHelper";
import { setErrors } from "@/stores/errors";
import { addInfoToast, addSuccessToast } from "@/stores/toasts";
import OverlayPanel from "@/components/base/OverlayPanel.svelte";
import Field from "@/components/base/Field.svelte";
const dispatch = createEventDispatcher();
const formId = "backup_create_" + CommonHelper.randomString(5);
let panel;
let name = "";
let isSubmitting = false;
let submitTimeoutId;
export function show(newName) {
setErrors({});
isSubmitting = false;
name = newName || "";
panel?.show();
}
export function hide() {
return panel?.hide();
}
async function submit() {
if (isSubmitting) {
return;
}
isSubmitting = true;
clearTimeout(submitTimeoutId);
submitTimeoutId = setTimeout(() => {
hide();
}, 1500);
try {
await ApiClient.backups.create(name, { $cancelKey: formId });
isSubmitting = false;
hide();
dispatch("submit");
addSuccessToast("Successfully generated new backup.");
} catch (err) {
if (!err.isAbort) {
ApiClient.error(err);
}
}
clearTimeout(submitTimeoutId);
isSubmitting = false;
}
onDestroy(() => {
clearTimeout(submitTimeoutId);
});
</script>
<OverlayPanel
bind:this={panel}
class="backup-create-panel"
beforeOpen={() => {
if (isSubmitting) {
addInfoToast("A backup has already been started, please wait.");
return false;
}
return true;
}}
beforeHide={() => {
if (isSubmitting) {
addInfoToast(
"The backup was started but may take a while to complete. You can come back later.",
4500
);
}
return true;
}}
popup
on:show
on:hide
>
<svelte:fragment slot="header">
<h4 class="center txt-break">Initialize new backup</h4>
</svelte:fragment>
<div class="alert alert-info">
<div class="icon">
<i class="ri-information-line" />
</div>
<div class="content">
<p>
Please note that during the backup other concurrent write requests may fail since the
database will be temporary "locked" (this usually happens only during the ZIP generation).
</p>
<p class="txt-bold">
If you are using S3 storage for the collections file upload, you'll have to backup them
separately since they are not locally stored and will not be included in the final backup!
</p>
</div>
</div>
<form id={formId} autocomplete="off" on:submit|preventDefault={submit}>
<Field class="form-field m-0" name="name" let:uniqueId>
<label for={uniqueId}>Backup name</label>
<input
type="text"
id={uniqueId}
placeholder={"Leave empty to autogenerate"}
pattern="^[a-z0-9_-]+\.zip$"
bind:value={name}
/>
<em class="help-block">Must be in the format [a-z0-9_-].zip</em>
</Field>
</form>
<svelte:fragment slot="footer">
<button type="button" class="btn btn-transparent" on:click={hide} disabled={isSubmitting}>
<span class="txt">Cancel</span>
</button>
<button
type="submit"
form={formId}
class="btn btn-expanded"
class:btn-loading={isSubmitting}
disabled={isSubmitting}
>
<span class="txt">Start backup</span>
</button>
</svelte:fragment>
</OverlayPanel>