added backup apis and tests
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import { slide } from "svelte/transition";
|
||||
import ApiClient from "@/utils/ApiClient";
|
||||
import CommonHelper from "@/utils/CommonHelper";
|
||||
@@ -8,9 +7,8 @@
|
||||
import { removeAllToasts, addWarningToast, addSuccessToast } from "@/stores/toasts";
|
||||
import tooltip from "@/actions/tooltip";
|
||||
import PageWrapper from "@/components/base/PageWrapper.svelte";
|
||||
import Field from "@/components/base/Field.svelte";
|
||||
import RedactedPasswordInput from "@/components/base/RedactedPasswordInput.svelte";
|
||||
import SettingsSidebar from "@/components/settings/SettingsSidebar.svelte";
|
||||
import S3Fields from "@/components/settings/S3Fields.svelte";
|
||||
|
||||
$pageTitle = "Files storage";
|
||||
|
||||
@@ -21,8 +19,7 @@
|
||||
let isLoading = false;
|
||||
let isSaving = false;
|
||||
let isTesting = false;
|
||||
let testS3Error = null;
|
||||
let testS3TimeoutId = null;
|
||||
let testError = null;
|
||||
|
||||
$: initialHash = JSON.stringify(originalFormSettings);
|
||||
|
||||
@@ -37,7 +34,7 @@
|
||||
const settings = (await ApiClient.settings.getAll()) || {};
|
||||
init(settings);
|
||||
} catch (err) {
|
||||
ApiClient.errorResponseHandler(err);
|
||||
ApiClient.error(err);
|
||||
}
|
||||
|
||||
isLoading = false;
|
||||
@@ -59,13 +56,13 @@
|
||||
|
||||
removeAllToasts();
|
||||
|
||||
if (testS3Error) {
|
||||
if (testError) {
|
||||
addWarningToast("Successfully saved but failed to establish S3 connection.");
|
||||
} else {
|
||||
addSuccessToast("Successfully saved files storage settings.");
|
||||
}
|
||||
} catch (err) {
|
||||
ApiClient.errorResponseHandler(err);
|
||||
ApiClient.error(err);
|
||||
}
|
||||
|
||||
isSaving = false;
|
||||
@@ -75,49 +72,13 @@
|
||||
formSettings = {
|
||||
s3: settings?.s3 || {},
|
||||
};
|
||||
originalFormSettings = JSON.parse(JSON.stringify(formSettings));
|
||||
|
||||
await testS3();
|
||||
originalFormSettings = JSON.parse(JSON.stringify(formSettings));
|
||||
}
|
||||
|
||||
async function reset() {
|
||||
formSettings = JSON.parse(JSON.stringify(originalFormSettings || {}));
|
||||
|
||||
await testS3();
|
||||
}
|
||||
|
||||
async function testS3() {
|
||||
testS3Error = null;
|
||||
|
||||
if (!formSettings.s3.enabled) {
|
||||
return; // nothing to test
|
||||
}
|
||||
|
||||
// auto cancel the test request after 30sec
|
||||
ApiClient.cancelRequest(testRequestKey);
|
||||
clearTimeout(testS3TimeoutId);
|
||||
testS3TimeoutId = setTimeout(() => {
|
||||
ApiClient.cancelRequest(testRequestKey);
|
||||
addErrorToast("S3 test connection timeout.");
|
||||
}, 30000);
|
||||
|
||||
isTesting = true;
|
||||
|
||||
try {
|
||||
await ApiClient.settings.testS3({ $cancelKey: testRequestKey });
|
||||
} catch (err) {
|
||||
testS3Error = err;
|
||||
}
|
||||
|
||||
isTesting = false;
|
||||
clearTimeout(testS3TimeoutId);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
return () => {
|
||||
clearTimeout(testS3TimeoutId);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<SettingsSidebar />
|
||||
@@ -142,129 +103,57 @@
|
||||
{#if isLoading}
|
||||
<div class="loader" />
|
||||
{:else}
|
||||
<Field class="form-field form-field-toggle" let:uniqueId>
|
||||
<input type="checkbox" id={uniqueId} required bind:checked={formSettings.s3.enabled} />
|
||||
<label for={uniqueId}>Use S3 storage</label>
|
||||
</Field>
|
||||
|
||||
{#if originalFormSettings.s3?.enabled != formSettings.s3.enabled}
|
||||
<div transition:slide|local={{ duration: 150 }}>
|
||||
<div class="alert alert-warning m-0">
|
||||
<div class="icon">
|
||||
<i class="ri-error-warning-line" />
|
||||
</div>
|
||||
<div class="content">
|
||||
If you have existing uploaded files, you'll have to migrate them manually from
|
||||
the
|
||||
<strong>
|
||||
{originalFormSettings.s3?.enabled ? "S3 storage" : "local file system"}
|
||||
</strong>
|
||||
to the
|
||||
<strong>{formSettings.s3.enabled ? "S3 storage" : "local file system"}</strong
|
||||
>.
|
||||
<br />
|
||||
There are numerous command line tools that can help you, such as:
|
||||
<a
|
||||
href="https://github.com/rclone/rclone"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="txt-bold"
|
||||
>
|
||||
rclone
|
||||
</a>,
|
||||
<a
|
||||
href="https://github.com/peak/s5cmd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="txt-bold"
|
||||
>
|
||||
s5cmd
|
||||
</a>, etc.
|
||||
<S3Fields
|
||||
toggleLabel="Use S3 storage"
|
||||
originalConfig={originalFormSettings.s3}
|
||||
bind:config={formSettings.s3}
|
||||
bind:isTesting
|
||||
bind:testError
|
||||
>
|
||||
{#if originalFormSettings.s3?.enabled != formSettings.s3.enabled}
|
||||
<div transition:slide|local={{ duration: 150 }}>
|
||||
<div class="alert alert-warning m-0">
|
||||
<div class="icon">
|
||||
<i class="ri-error-warning-line" />
|
||||
</div>
|
||||
<div class="content">
|
||||
If you have existing uploaded files, you'll have to migrate them manually
|
||||
from the
|
||||
<strong>
|
||||
{originalFormSettings.s3?.enabled
|
||||
? "S3 storage"
|
||||
: "local file system"}
|
||||
</strong>
|
||||
to the
|
||||
<strong
|
||||
>{formSettings.s3.enabled
|
||||
? "S3 storage"
|
||||
: "local file system"}</strong
|
||||
>.
|
||||
<br />
|
||||
There are numerous command line tools that can help you, such as:
|
||||
<a
|
||||
href="https://github.com/rclone/rclone"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="txt-bold"
|
||||
>
|
||||
rclone
|
||||
</a>,
|
||||
<a
|
||||
href="https://github.com/peak/s5cmd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="txt-bold"
|
||||
>
|
||||
s5cmd
|
||||
</a>, etc.
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix m-t-base" />
|
||||
</div>
|
||||
<div class="clearfix m-t-base" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if formSettings.s3.enabled}
|
||||
<div class="grid" transition:slide|local={{ duration: 150 }}>
|
||||
<div class="col-lg-6">
|
||||
<Field class="form-field required" name="s3.endpoint" let:uniqueId>
|
||||
<label for={uniqueId}>Endpoint</label>
|
||||
<input
|
||||
type="text"
|
||||
id={uniqueId}
|
||||
required
|
||||
bind:value={formSettings.s3.endpoint}
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<Field class="form-field required" name="s3.bucket" let:uniqueId>
|
||||
<label for={uniqueId}>Bucket</label>
|
||||
<input
|
||||
type="text"
|
||||
id={uniqueId}
|
||||
required
|
||||
bind:value={formSettings.s3.bucket}
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<Field class="form-field required" name="s3.region" let:uniqueId>
|
||||
<label for={uniqueId}>Region</label>
|
||||
<input
|
||||
type="text"
|
||||
id={uniqueId}
|
||||
required
|
||||
bind:value={formSettings.s3.region}
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<Field class="form-field required" name="s3.accessKey" let:uniqueId>
|
||||
<label for={uniqueId}>Access key</label>
|
||||
<input
|
||||
type="text"
|
||||
id={uniqueId}
|
||||
required
|
||||
bind:value={formSettings.s3.accessKey}
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<Field class="form-field required" name="s3.secret" let:uniqueId>
|
||||
<label for={uniqueId}>Secret</label>
|
||||
<RedactedPasswordInput
|
||||
id={uniqueId}
|
||||
required
|
||||
bind:value={formSettings.s3.secret}
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
<div class="col-lg-12">
|
||||
<Field class="form-field" name="s3.forcePathStyle" let:uniqueId>
|
||||
<input
|
||||
type="checkbox"
|
||||
id={uniqueId}
|
||||
bind:checked={formSettings.s3.forcePathStyle}
|
||||
/>
|
||||
<label for={uniqueId}>
|
||||
<span class="txt">Force path-style addressing</span>
|
||||
<i
|
||||
class="ri-information-line link-hint"
|
||||
use:tooltip={{
|
||||
text: 'Forces the request to use path-style addressing, eg. "https://s3.amazonaws.com/BUCKET/KEY" instead of the default "https://BUCKET.s3.amazonaws.com/KEY".',
|
||||
position: "top",
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
</Field>
|
||||
</div>
|
||||
<!-- margin helper -->
|
||||
<div class="col-lg-12" />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</S3Fields>
|
||||
|
||||
<div class="flex">
|
||||
<div class="flex-fill" />
|
||||
@@ -272,10 +161,10 @@
|
||||
{#if formSettings.s3?.enabled && !hasChanges && !isSaving}
|
||||
{#if isTesting}
|
||||
<span class="loader loader-sm" />
|
||||
{:else if testS3Error}
|
||||
{:else if testError}
|
||||
<div
|
||||
class="label label-sm label-warning entrance-right"
|
||||
use:tooltip={testS3Error.data?.message}
|
||||
use:tooltip={testError.data?.message}
|
||||
>
|
||||
<i class="ri-error-warning-line txt-warning" />
|
||||
<span class="txt">Failed to establish S3 connection</span>
|
||||
@@ -295,7 +184,7 @@
|
||||
disabled={isSaving}
|
||||
on:click={() => reset()}
|
||||
>
|
||||
<span class="txt">Cancel</span>
|
||||
<span class="txt">Reset</span>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user