refactor: change create file from modal to wizard

This commit is contained in:
tglide
2023-02-20 21:34:59 +00:00
parent ca08b538c9
commit e3256650ba
7 changed files with 201 additions and 30 deletions
+5
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import { Trim } from '$lib/components';
import { humanFileSize } from '$lib/helpers/sizeConvertion';
import { onMount } from 'svelte';
import { Helper } from '.';
export let label: string = null;
@@ -47,6 +48,10 @@
}
$: fileArray = files?.length ? Array.from(files) : [];
onMount(() => {
input.files = files;
});
</script>
<input
@@ -1,45 +1,45 @@
<script lang="ts">
import { invalidate } from '$app/navigation';
import { base } from '$app/paths';
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Pill } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import {
Empty,
EmptySearch,
Pagination,
Avatar,
DropList,
DropListItem,
DropListLink,
Empty,
EmptySearch,
Pagination,
SearchQuery
} from '$lib/components';
import Create from '../create.svelte';
import Delete from '../deleteFile.svelte';
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
import { Pill } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import {
Table,
TableHeader,
TableBody,
TableRowLink,
TableRow,
TableCell,
TableCellHead,
TableCellText,
TableCell
TableHeader,
TableRow,
TableRowLink
} from '$lib/elements/table';
import { toLocaleDate } from '$lib/helpers/date';
import { calculateSize } from '$lib/helpers/sizeConvertion';
import { Container } from '$lib/layout';
import { base } from '$app/paths';
import type { Models } from '@aw-labs/appwrite-console';
import { uploader } from '$lib/stores/uploader';
import { addNotification } from '$lib/stores/notifications';
import { sdkForProject } from '$lib/stores/sdk';
import { uploader } from '$lib/stores/uploader';
import { wizard } from '$lib/stores/wizard';
import type { Models } from '@aw-labs/appwrite-console';
import type { PageData } from './$types';
import { invalidate } from '$app/navigation';
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
import CreateWizard from './create/create.svelte';
import Delete from './deleteFile.svelte';
export let data: PageData;
let showCreate = false;
let showDelete = false;
let showDropdown = [];
let selectedFile: Models.File = null;
@@ -49,11 +49,6 @@
const getPreview = (fileId: string) =>
sdkForProject.storage.getFilePreview(bucketId, fileId, 32, 32).toString() + '&mode=admin';
function fileCreated() {
showCreate = false;
invalidate(Dependencies.FILES);
}
function fileDeleted(event: CustomEvent<Models.File>) {
showDelete = false;
uploader.removeFile(event.detail);
@@ -78,8 +73,9 @@
<Container>
<SearchQuery search={data.search} placeholder="Search by filename">
<Button on:click={() => (showCreate = true)} event="create_file">
<span class="icon-plus" aria-hidden="true" /> <span class="text">Create file</span>
<Button on:click={() => wizard.start(CreateWizard)} event="create_file">
<span class="icon-plus" aria-hidden="true" />
<span class="text">Create file</span>
</Button>
</SearchQuery>
@@ -97,7 +93,7 @@
{#if file.chunksTotal / file.chunksUploaded !== 1}
<TableRow>
<TableCell title="Name">
<div class="u-flex u-gap-12 u-main-space-between">
<div class="u-flex u-gap-12 u-main-space-between u-cross-center">
<span class="avatar is-size-small is-color-empty" />
<span class="text u-trim">{file.name}</span>
@@ -136,7 +132,7 @@
<TableRowLink
href={`${base}/console/project-${projectId}/storage/bucket-${bucketId}/file-${file.$id}`}>
<TableCell title="Name">
<div class="u-flex u-gap-12">
<div class="u-flex u-gap-12 u-cross-center">
<Avatar size={32} src={getPreview(file.$id)} name={file.name} />
<span class="text u-trim">{file.name}</span>
</div>
@@ -213,11 +209,10 @@
single
href="https://appwrite.io/docs/storage#createFile"
target="file"
on:click={() => (showCreate = true)} />
on:click={() => wizard.start(CreateWizard)} />
{/if}
</Container>
<Create bind:showCreate on:created={fileCreated} />
{#if selectedFile}
<Delete file={selectedFile} bind:showDelete on:deleted={fileDeleted} />
{/if}
@@ -0,0 +1,60 @@
<script lang="ts">
import { invalidate } from '$app/navigation';
import { page } from '$app/stores';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Dependencies } from '$lib/constants';
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
import Wizard from '$lib/layout/wizard.svelte';
import { addNotification } from '$lib/stores/notifications';
import { uploader } from '$lib/stores/uploader';
import { wizard } from '$lib/stores/wizard';
import { ID } from '@aw-labs/appwrite-console';
import Step1 from './step1.svelte';
import Step2 from './step2.svelte';
import { createFile } from './store';
const bucketId = $page.params.bucket;
const stepComponents: WizardStepsType = new Map();
stepComponents.set(1, {
component: Step1,
label: 'Upload a file'
});
stepComponents.set(2, {
component: Step2,
label: 'Update permissions'
});
async function create() {
try {
await uploader.uploadFile(
bucketId,
$createFile.id ?? ID.unique(),
$createFile.files[0],
$createFile.permissions
);
createFile.reset();
wizard.hide();
invalidate(Dependencies.FILES);
addNotification({
type: 'success',
message: `File has been uploaded`
});
trackEvent(Submit.FileCreate, {
customId: !!$createFile.id
});
} catch (e) {
addNotification({
type: 'error',
message: e.message
});
trackError(e, Submit.FileCreate);
}
}
</script>
<Wizard title="Upload file" steps={stepComponents} on:exit={createFile.reset} on:finish={create} />
@@ -0,0 +1,44 @@
<script lang="ts">
import { CustomId } from '$lib/components';
import { Pill } from '$lib/elements';
import { FormList, InputFile } from '$lib/elements/forms';
import WizardStep from '$lib/layout/wizardStep.svelte';
import { bucket } from '../store';
import { createFile } from './store';
let showCustomId = false;
</script>
<WizardStep>
<svelte:fragment slot="title">Upload a File</svelte:fragment>
<svelte:fragment slot="subtitle">Upload a file to add it to your bucket.</svelte:fragment>
<FormList>
<div>
<InputFile
required
bind:files={$createFile.files}
allowedFileExtensions={$bucket.allowedFileExtensions}
maxSize={$bucket.maximumFileSize} />
</div>
{#if !showCustomId}
<div>
<Pill button on:click={() => (showCustomId = !showCustomId)}>
<span class="icon-pencil" aria-hidden="true" /><span class="text">
File ID
</span>
</Pill>
</div>
{:else}
<div class="custom-id-wrapper">
<CustomId bind:show={showCustomId} name="File" bind:id={$createFile.id} />
</div>
{/if}
</FormList>
</WizardStep>
<style lang="scss">
.custom-id-wrapper :global(.is-inner-modal) {
inline-size: auto;
}
</style>
@@ -0,0 +1,43 @@
<script lang="ts">
import Alert from '$lib/components/alert.svelte';
import Permissions from '$lib/components/permissions/permissions.svelte';
import WizardStep from '$lib/layout/wizardStep.svelte';
import { bucket } from '../store';
import { createFile } from './store';
</script>
<WizardStep>
<svelte:fragment slot="title">Update Permissions</svelte:fragment>
<svelte:fragment slot="subtitle"
>Choose who can get access to your buckets and files. For more information, check out the
Permissions Guide in our documentation.</svelte:fragment>
<p class="text">
Choose who can access your buckets and files. For more information, check out the
<a
href="https://appwrite.io/docs/permissions"
target="_blank"
rel="noopener noreferrer"
class="link">
Permissions Guide
</a>.
</p>
{#if $bucket.fileSecurity}
<div class="common-section">
<Alert type="info">
<svelte:fragment slot="title">File security enabled</svelte:fragment>
Users will be able to access this file if they have been granted
<b>either File or Bucket permissions</b>.
</Alert>
</div>
<div class="common-section">
<Permissions bind:permissions={$createFile.permissions} />
</div>
{:else}
<Alert type="info">
<svelte:fragment slot="title">File security disabled</svelte:fragment>
If you want to assign file permissions, navigate to Bucket settings and enable file security.
Otherwise, only Bucket permissions will be used.
</Alert>
{/if}
</WizardStep>
@@ -0,0 +1,24 @@
import { writable } from 'svelte/store';
type CreateFile = {
files: FileList | null;
id: string | null;
permissions: string[];
};
const initialState: CreateFile = {
files: null,
id: null,
permissions: []
};
export const createFile = (function initialize() {
const store = writable<CreateFile>({ ...initialState });
return {
...store,
reset() {
store.set({ ...initialState });
}
};
})();