This commit is contained in:
Torsten Dittmann
2022-03-09 18:53:07 +01:00
parent 063f79a34d
commit 7eb84a0da6
55 changed files with 738 additions and 159 deletions
+13 -13
View File
@@ -11,7 +11,7 @@
"aw-labs-ui": "latest"
},
"devDependencies": {
"@sveltejs/adapter-static": "next",
"@sveltejs/adapter-static": "^1.0.0-next.28",
"@sveltejs/kit": "next",
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.36",
"@testing-library/dom": "^8.11.3",
@@ -5044,9 +5044,9 @@
}
},
"node_modules/log-symbols/node_modules/chalk": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.0.tgz",
"integrity": "sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
"integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
"dev": true,
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
@@ -5369,9 +5369,9 @@
}
},
"node_modules/ora/node_modules/chalk": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.0.tgz",
"integrity": "sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
"integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
"dev": true,
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
@@ -10805,9 +10805,9 @@
},
"dependencies": {
"chalk": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.0.tgz",
"integrity": "sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
"integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
"dev": true
}
}
@@ -11053,9 +11053,9 @@
"dev": true
},
"chalk": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.0.tgz",
"integrity": "sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
"integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
"dev": true
},
"strip-ansi": {
+1 -1
View File
@@ -23,7 +23,7 @@
"aw-labs-ui": "latest"
},
"devDependencies": {
"@sveltejs/adapter-static": "next",
"@sveltejs/adapter-static": "^1.0.0-next.28",
"@sveltejs/kit": "next",
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.36",
"@testing-library/dom": "^8.11.3",
+5
View File
@@ -0,0 +1,5 @@
<script lang="ts">
export let href: string;
</script>
<a {href}><i class="icon-left-open" /> <slot /></a>
+1
View File
@@ -1,3 +1,4 @@
export { default as Modal } from './modal.svelte';
export { default as Pagination } from './pagination.svelte';
export { default as Card } from './card.svelte';
export { default as Back } from './back.svelte';
+6 -1
View File
@@ -40,7 +40,12 @@
bind:value
bind:this={element}
/>
<button class="input-button" aria-label="Switch" on:click={() => (unique = !unique)}>
<button
class="input-button"
aria-label="Switch"
on:click={() => (unique = !unique)}
type="button"
>
<span class:icon-edit={unique} class:icon-shuffle={!unique} aria-hidden="true" />
</button>
</div>
@@ -1,12 +1,14 @@
<script>
import { page } from '$app/stores';
import { Back } from '$lib/components';
import Tabs from './_tabs.svelte';
const project = $page.params.project;
</script>
<h1>Database</h1>
{#if $page.url.pathname === `/console/${project}/database` || $page.url.pathname === `/console/${project}/database/@usage`}
{#if $page.url.pathname === `/console/${project}/database/` || $page.url.pathname === `/console/${project}/database/usage/`}
<Back href={`/console/${project}`}>Home</Back>
<h1>Database</h1>
<Tabs />
{/if}
@@ -1,6 +1,6 @@
<script lang="ts">
import { Modal } from '$lib/components';
import { Button, InputFile } from '$lib/elements/forms';
import { Button, InputText, InputCustomId } from '$lib/elements/forms';
import { addNotification } from '$lib/stores/notifications';
import { sdkForProject } from '$lib/stores/sdk';
@@ -10,12 +10,13 @@
const dispatch = createEventDispatcher();
let files: FileList;
let id = '';
let name = '';
const create = async () => {
try {
await sdkForProject.storage.createFile('unique()', files[0]);
files = null;
await sdkForProject.database.createCollection(id, name, 'collection', [], []);
id = name = '';
showCreate = false;
dispatch('created');
} catch (error) {
@@ -29,11 +30,12 @@
<form on:submit|preventDefault={create}>
<Modal bind:show={showCreate}>
<span slot="header">Upload File</span>
<InputFile id="file" label="File" bind:files required />
<span slot="header">Create Collection</span>
<InputCustomId label="ID" id="id" bind:value={id} />
<InputText label="Name" id="name" bind:value={name} />
<footer>
<Button secondary on:click={() => (showCreate = false)}>Cancel</Button>
<Button submit>Upload</Button>
<Button submit>Create</Button>
</footer>
</Modal>
</form>
@@ -9,7 +9,7 @@
<a
class="tabs-button is-selected"
href={`/console/${project}/database`}
class:is-selected={$page.url.pathname === `/console/${project}/database`}
class:is-selected={$page.url.pathname === `/console/${project}/database/`}
>
<span class="text">Collections</span>
</a>
@@ -17,8 +17,8 @@
<li class="tabs-item">
<a
class="tabs-button is-selected"
href={`/console/${project}/database/@usage`}
class:is-selected={$page.url.pathname === `/console/${project}/database/@usage`}
href={`/console/${project}/database/usage`}
class:is-selected={$page.url.pathname === `/console/${project}/database/usage/`}
>
<span class="text">Usage</span>
</a>
@@ -1,28 +1,25 @@
<script lang="ts">
import { browser } from '$app/env';
import { page } from '$app/stores';
import { addNotification } from '$lib/stores/notifications';
import { sdkForProject } from '$lib/stores/sdk';
import { Back } from '$lib/components';
import { collection } from './store';
import Tabs from './_tabs.svelte';
page.subscribe(async (p) => {
if (browser && p.params.collection) {
try {
collection.set(await sdkForProject.database.getCollection(p.params.collection));
} catch (error) {
addNotification({
type: 'error',
message: error.message
});
}
const project = $page.params.project;
const collectionId = $page.params.collection;
$: {
if (browser) {
collection.load(collectionId);
}
});
}
</script>
<Tabs />
<Back href={`/console/${project}/database`}>Database</Back>
{#if $collection}
<h1>{$collection.name}</h1>
<Tabs />
<slot />
{:else}
<div aria-busy="true" />
@@ -3,15 +3,15 @@
$: project = $page.params.project;
$: collectionId = $page.params.collection;
$: path = `/console/${project}/database/collection/${collectionId}`;
</script>
<ul class="tabs">
<li class="tabs-item">
<a
class="tabs-button is-selected"
href={`/console/${project}/database/collection/${collectionId}`}
class:is-selected={$page.url.pathname ===
`/console/${project}/database/collection/${collectionId}`}
href={path}
class:is-selected={$page.url.pathname === `${path}/`}
>
<span class="text">Documents</span>
</a>
@@ -19,10 +19,8 @@
<li class="tabs-item">
<a
class="tabs-button"
href={`/console/${project}/database/collection/${collectionId}/attributes`}
class:is-selected={$page.url.pathname.startsWith(
`/console/${project}/database/collection/${collectionId}/attributes`
)}
href={`${path}/attributes`}
class:is-selected={$page.url.pathname.startsWith(`${path}/attributes`)}
>
<span class="text">Attributes</span>
</a>
@@ -30,10 +28,8 @@
<li class="tabs-item">
<a
class="tabs-button"
href={`/console/${project}/database/collection/${collectionId}/indexes`}
class:is-selected={$page.url.pathname.startsWith(
`/console/${project}/database/collection/${collectionId}/indexes`
)}
href={`${path}/indexes`}
class:is-selected={$page.url.pathname.startsWith(`${path}/indexes`)}
>
<span class="text">Indexes</span>
</a>
@@ -41,10 +37,8 @@
<li class="tabs-item">
<a
class="tabs-button"
href={`/console/${project}/database/collection/${collectionId}/settings`}
class:is-selected={$page.url.pathname.startsWith(
`/console/${project}/database/collection/${collectionId}/settings`
)}
href={`${path}/settings`}
class:is-selected={$page.url.pathname.startsWith(`${path}/settings`)}
>
<span class="text">Settings</span>
</a>
@@ -1,4 +1,5 @@
<script lang="ts">
import { Card } from '$lib/components';
import { Button } from '$lib/elements/forms';
import { Table, TableCell, TableHeader, TableBody, TableRow } from '$lib/elements/table';
import Create from './attributes/_create.svelte';
@@ -7,7 +8,9 @@
let showCreate = false;
</script>
<section>
<h1>Attributes</h1>
<Card>
<Table>
<TableHeader>
<TableCell>Status</TableCell>
@@ -24,7 +27,7 @@
{/each}
</TableBody>
</Table>
</section>
</Card>
<Button on:click={() => (showCreate = true)}>Create Attribute</Button>
<Create bind:show={showCreate} />
@@ -2,7 +2,7 @@
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Table, TableRow, TableBody, TableHeader, TableCell } from '$lib/elements/table';
import { Pagination } from '$lib/components';
import { Card, Pagination } from '$lib/components';
import { collection } from './store';
let offset = 0;
@@ -23,7 +23,8 @@
let request = getDocuments();
</script>
<section>
<h1>Documents</h1>
<Card>
{#await request}
<div aria-busy="true" />
{:then response}
@@ -51,8 +52,8 @@
<Pagination
{limit}
bind:offset
sum={response.sum}
sum={response.total}
on:change={() => (request = getDocuments())}
/>
{/await}
</section>
</Card>
@@ -0,0 +1 @@
<h1>Indexes</h1>
@@ -0,0 +1 @@
<h1>Settings</h1>
@@ -1,3 +1,4 @@
import { sdkForProject } from '$lib/stores/sdk';
import type { Models } from 'src/sdk';
import { writable } from 'svelte/store';
@@ -17,6 +18,9 @@ function createCollection() {
return {
subscribe,
set,
load: async (collectionId: string) => {
set(await sdkForProject.database.getCollection(collectionId));
},
addAttribute: (attribute: Attributes) =>
update((n) => {
n.attributes.push(attribute);
@@ -20,6 +20,7 @@
let request = getCollections();
</script>
<h1>Collections</h1>
<Card>
<form on:submit|preventDefault={doSearch}>
<input type="search" bind:value={search} />
@@ -0,0 +1 @@
<h1>Usage</h1>
@@ -0,0 +1,14 @@
<script>
import { page } from '$app/stores';
import { Back } from '$lib/components';
import Tabs from './_tabs.svelte';
const project = $page.params.project;
</script>
{#if $page.url.pathname === `/console/${project}/functions/`}
<Back href={`/console/${project}`}>Home</Back>
<h1>Functions</h1>
<Tabs />
{/if}
<slot />
@@ -0,0 +1,39 @@
<script lang="ts">
import { Modal } from '$lib/components';
import { Button, InputText } from '$lib/elements/forms';
import { addNotification } from '$lib/stores/notifications';
import { sdkForProject } from '$lib/stores/sdk';
import { createEventDispatcher } from 'svelte';
export let showCreate = false;
const dispatch = createEventDispatcher();
let name = '';
const create = async () => {
try {
await sdkForProject.storage.createBucket('unique()', name, 'bucket');
name = null;
showCreate = false;
dispatch('created');
} catch (error) {
addNotification({
type: 'error',
message: error.message
});
}
};
</script>
<form on:submit|preventDefault={create}>
<Modal bind:show={showCreate}>
<span slot="header">Upload File</span>
<InputText id="name" label="Name" bind:value={name} required />
<footer>
<Button secondary on:click={() => (showCreate = false)}>Cancel</Button>
<Button submit>Upload</Button>
</footer>
</Modal>
</form>
@@ -0,0 +1,17 @@
<script>
import { page } from '$app/stores';
$: project = $page.params.project;
</script>
<ul class="tabs">
<li class="tabs-item">
<a
class="tabs-button is-selected"
href={`/console/${project}/storage`}
class:is-selected={$page.url.pathname === `/console/${project}/functions/`}
>
<span class="text">Functions</span>
</a>
</li>
</ul>
@@ -0,0 +1,24 @@
<script lang="ts">
import { browser } from '$app/env';
import { page } from '$app/stores';
import { Back } from '$lib/components';
import { func } from './store';
import Tabs from './_tabs.svelte';
const project = $page.params.project;
const functionId = $page.params.function;
$: {
if (browser) {
func.load(functionId);
}
}
</script>
<Back href={`/console/${project}/functions`}>Functions</Back>
{#if $func}
<h1>{$func.name}</h1>
<Tabs />
<slot />
{/if}
@@ -0,0 +1,45 @@
<script lang="ts">
import { InputTags, Button, InputFile } from '$lib/elements/forms';
import { Modal } from '$lib/components';
import { sdkForProject } from '$lib/stores/sdk';
import { createEventDispatcher } from 'svelte';
import { addNotification } from '$lib/stores/notifications';
import { page } from '$app/stores';
export let showCreate = false;
const bucket = $page.params.bucket;
const dispatch = createEventDispatcher();
let files: FileList;
let read: string[] = [];
let write: string[] = [];
const create = async () => {
try {
console.log(read, write);
await sdkForProject.storage.createFile(bucket, 'unique()', files[0], read, write);
files = null;
showCreate = false;
dispatch('created');
} catch (error) {
addNotification({
type: 'error',
message: error.message
});
}
};
</script>
<form on:submit|preventDefault={create}>
<Modal bind:show={showCreate}>
<span slot="header">Upload File</span>
<InputFile id="file" label="File" bind:files required />
<InputTags id="read" label="Read" bind:tags={read} />
<InputTags id="write" label="Write" bind:tags={write} />
<footer>
<Button secondary on:click={() => (showCreate = false)}>Cancel</Button>
<Button submit>Upload</Button>
</footer>
</Modal>
</form>
@@ -0,0 +1,46 @@
<script>
import { page } from '$app/stores';
$: project = $page.params.project;
$: functionId = $page.params.function;
$: path = `/console/${project}/functions/function/${functionId}`;
</script>
<ul class="tabs">
<li class="tabs-item">
<a
class="tabs-button is-selected"
href={path}
class:is-selected={$page.url.pathname === `${path}/`}
>
<span class="text">Files</span>
</a>
</li>
<li class="tabs-item">
<a
class="tabs-button"
href={`${path}/monitors`}
class:is-selected={$page.url.pathname === `${path}/monitors/`}
>
<span class="text">Monitors</span>
</a>
</li>
<li class="tabs-item">
<a
class="tabs-button"
href={`${path}/logs`}
class:is-selected={$page.url.pathname === `${path}/logs/`}
>
<span class="text">Logs</span>
</a>
</li>
<li class="tabs-item">
<a
class="tabs-button"
href={`${path}/settings`}
class:is-selected={$page.url.pathname === `${path}/settings/`}
>
<span class="text">Settings</span>
</a>
</li>
</ul>
@@ -0,0 +1,76 @@
<script lang="ts">
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Button } from '$lib/elements/forms';
import { Card, Pagination } from '$lib/components';
import { Table, TableHeader, TableCell, TableBody, TableRow } from '$lib/elements/table';
import Create from './_create.svelte';
import { func } from './store';
let search = '';
let showCreate = false;
let offset = 0;
const limit = 25;
const project = $page.params.project;
const functionId = $page.params.function;
const getDeployments = () =>
sdkForProject.functions.listDeployments(functionId, search, limit, offset);
// const doSearch = () => {
// offset = 0;
// request = getDeployments();
// };
let request = getDeployments();
</script>
<h1>Overview</h1>
<Card>
<p><b>Function ID:</b> {$func.$id}</p>
<p><b>Runtime:</b> {$func.runtime}</p>
<p><b>Last Updated:</b> {$func.dateUpdated}</p>
<p><b>Created:</b> {$func.dateCreated}</p>
</Card>
<h1>Deployments</h1>
<!-- <Card>
<form on:submit|preventDefault={doSearch}>
<input type="search" bind:value={search} />
</form>
</Card> -->
<Card>
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCell>#</TableCell>
<TableCell>Active</TableCell>
</TableHeader>
<TableBody>
{#each response.deployments as deployment}
<TableRow>
<TableCell>
<a href={`/console/${project}/storage/bucket/${functionId}/${deployment.$id}`}>
{deployment.$id}
</a>
</TableCell>
<TableCell>{deployment.activate}</TableCell>
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination
{limit}
bind:offset
sum={response.total}
on:change={() => (request = getDeployments())}
/>
{/await}
</Card>
<Button on:click={() => (showCreate = true)}>Upload</Button>
<Create bind:showCreate on:created={() => (request = getDeployments())} />
@@ -0,0 +1 @@
<h1>Logs</h1>
@@ -0,0 +1 @@
<h1>Monitors</h1>
@@ -0,0 +1 @@
<h1>Settings</h1>
@@ -0,0 +1,17 @@
import { sdkForProject } from '$lib/stores/sdk';
import type { Models } from 'src/sdk';
import { writable } from 'svelte/store';
function createFunctionStore() {
const { subscribe, set } = writable<Models.Function>();
return {
subscribe,
set,
load: async (functionId: string) => {
set(await sdkForProject.functions.get(functionId));
}
};
}
export const func = createFunctionStore();
@@ -0,0 +1 @@
<h1>Usage</h1>
@@ -0,0 +1,60 @@
<script lang="ts">
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Table, TableRow, TableBody, TableHeader, TableCell } from '$lib/elements/table';
import { Button } from '$lib/elements/forms';
import { Card, Pagination } from '$lib/components';
import Create from './_create.svelte';
let search = '';
let showCreate = false;
let offset = 0;
const limit = 25;
const project = $page.params.project;
const getFunctions = () => sdkForProject.functions.list(search, limit, offset);
const doSearch = () => {
offset = 0;
request = getFunctions();
};
let request = getFunctions();
</script>
<h1>Functions</h1>
<Card>
<form on:submit|preventDefault={doSearch}>
<input type="search" bind:value={search} />
</form>
</Card>
<Card>
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCell>#</TableCell>
<TableCell>Name</TableCell>
</TableHeader>
<TableBody>
{#each response.functions as func}
<TableRow>
<TableCell>
<a href={`/console/${project}/functions/function/${func.$id}`}>{func.$id}</a>
</TableCell>
<TableCell>{func.name}</TableCell>
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination
{limit}
bind:offset
sum={response.total}
on:change={() => (request = getFunctions())}
/>
{/await}
</Card>
<Button on:click={() => (showCreate = true)}>Create Function</Button>
<Create bind:showCreate on:created={() => (request = getFunctions())} />
@@ -0,0 +1 @@
<h1>Usage</h1>
@@ -1,3 +1,14 @@
<h1>Storage</h1>
<script>
import { page } from '$app/stores';
import { Back } from '$lib/components';
import Tabs from './_tabs.svelte';
<slot><!-- optional fallback --></slot>
const project = $page.params.project;
</script>
{#if $page.url.pathname === `/console/${project}/storage/` || $page.url.pathname === `/console/${project}/storage/usage/`}
<Back href={`/console/${project}`}>Home</Back>
<h1>Storage</h1>
<Tabs />
{/if}
<slot />
@@ -1,22 +1,21 @@
<script lang="ts">
import { InputTags, Button, InputFile } from '$lib/elements/forms';
import { Modal } from '$lib/components';
import { Button, InputText } from '$lib/elements/forms';
import { addNotification } from '$lib/stores/notifications';
import { sdkForProject } from '$lib/stores/sdk';
import { createEventDispatcher } from 'svelte';
import { addNotification } from '$lib/stores/notifications';
export let showCreate = false;
const dispatch = createEventDispatcher();
let files: FileList;
let read: string[] = [];
let write: string[] = [];
let name = '';
const create = async () => {
try {
await sdkForProject.storage.createFile('unique()', files[0], read, write);
files = null;
await sdkForProject.storage.createBucket('unique()', name, 'bucket');
name = null;
showCreate = false;
dispatch('created');
} catch (error) {
@@ -31,9 +30,7 @@
<form on:submit|preventDefault={create}>
<Modal bind:show={showCreate}>
<span slot="header">Upload File</span>
<InputFile id="file" label="File" bind:files required />
<InputTags id="read" label="Read" bind:tags={read} />
<InputTags id="write" label="Write" bind:tags={write} />
<InputText id="name" label="Name" bind:value={name} required />
<footer>
<Button secondary on:click={() => (showCreate = false)}>Cancel</Button>
<Button submit>Upload</Button>
@@ -0,0 +1,26 @@
<script>
import { page } from '$app/stores';
$: project = $page.params.project;
</script>
<ul class="tabs">
<li class="tabs-item">
<a
class="tabs-button is-selected"
href={`/console/${project}/storage`}
class:is-selected={$page.url.pathname === `/console/${project}/storage/`}
>
<span class="text">Buckets</span>
</a>
</li>
<li class="tabs-item">
<a
class="tabs-button is-selected"
href={`/console/${project}/storage/usage`}
class:is-selected={$page.url.pathname === `/console/${project}/storage/usage/`}
>
<span class="text">Usage</span>
</a>
</li>
</ul>
@@ -1,12 +1,12 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { Button } from '$lib/elements/forms';
import { addNotification } from '$lib/stores/notifications';
import { sdkForProject } from '$lib/stores/sdk';
const request = sdkForProject.storage.getFile($page.params.file);
const bucket = $page.params.bucket;
const request = sdkForProject.storage.getFile($page.params.bucket, $page.params.file);
const deleteFile = async () => {
try {
@@ -14,7 +14,7 @@
return;
}
await sdkForProject.storage.deleteFile($page.params.file);
await sdkForProject.storage.deleteFile(bucket, $page.params.file);
await goto(`/console/${$page.params.project}/storage`);
} catch (error) {
addNotification({
@@ -27,11 +27,11 @@
{#await request}
<div aria-busy="true" />
{:then user}
<p>Name: {user.name}</p>
<p>Type: {user.mimeType}</p>
<p>Size: {user.sizeOriginal}</p>
<p>Create: {user.dateCreated}</p>
{:then file}
<p>Name: {file.name}</p>
<p>Type: {file.mimeType}</p>
<p>Size: {file.sizeOriginal}</p>
<p>Create: {file.dateCreated}</p>
{/await}
<Button contrast on:click={deleteFile}>Delete File</Button>
@@ -0,0 +1,24 @@
<script lang="ts">
import { browser } from '$app/env';
import { page } from '$app/stores';
import { Back } from '$lib/components';
import { bucket } from './store';
import Tabs from './_tabs.svelte';
const project = $page.params.project;
const bucketId = $page.params.bucket;
$: {
if (browser) {
bucket.load(bucketId);
}
}
</script>
<Back href={`/console/${project}/storage`}>Storage</Back>
{#if $bucket}
<h1>{$bucket.name}</h1>
<Tabs />
<slot />
{/if}
@@ -0,0 +1,45 @@
<script lang="ts">
import { InputTags, Button, InputFile } from '$lib/elements/forms';
import { Modal } from '$lib/components';
import { sdkForProject } from '$lib/stores/sdk';
import { createEventDispatcher } from 'svelte';
import { addNotification } from '$lib/stores/notifications';
import { page } from '$app/stores';
export let showCreate = false;
const bucket = $page.params.bucket;
const dispatch = createEventDispatcher();
let files: FileList;
let read: string[] = [];
let write: string[] = [];
const create = async () => {
try {
console.log(read, write);
await sdkForProject.storage.createFile(bucket, 'unique()', files[0], read, write);
files = null;
showCreate = false;
dispatch('created');
} catch (error) {
addNotification({
type: 'error',
message: error.message
});
}
};
</script>
<form on:submit|preventDefault={create}>
<Modal bind:show={showCreate}>
<span slot="header">Upload File</span>
<InputFile id="file" label="File" bind:files required />
<InputTags id="read" label="Read" bind:tags={read} />
<InputTags id="write" label="Write" bind:tags={write} />
<footer>
<Button secondary on:click={() => (showCreate = false)}>Cancel</Button>
<Button submit>Upload</Button>
</footer>
</Modal>
</form>
@@ -0,0 +1,37 @@
<script>
import { page } from '$app/stores';
$: project = $page.params.project;
$: bucketId = $page.params.bucket;
$: path = `/console/${project}/storage/bucket/${bucketId}`;
</script>
<ul class="tabs">
<li class="tabs-item">
<a
class="tabs-button is-selected"
href={path}
class:is-selected={$page.url.pathname === `${path}/`}
>
<span class="text">Files</span>
</a>
</li>
<li class="tabs-item">
<a
class="tabs-button"
href={`${path}/usage`}
class:is-selected={$page.url.pathname === `${path}/usage/`}
>
<span class="text">Usage</span>
</a>
</li>
<li class="tabs-item">
<a
class="tabs-button"
href={`${path}/settings`}
class:is-selected={$page.url.pathname === `${path}/settings/`}
>
<span class="text">Settings</span>
</a>
</li>
</ul>
@@ -0,0 +1,65 @@
<script lang="ts">
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Button } from '$lib/elements/forms';
import { Card, Pagination } from '$lib/components';
import { Table, TableHeader, TableCell, TableBody, TableRow } from '$lib/elements/table';
import Create from './_create.svelte';
let search = '';
let showCreate = false;
let offset = 0;
const limit = 25;
const project = $page.params.project;
const bucket = $page.params.bucket;
const getBuckets = () => sdkForProject.storage.listFiles(bucket, search, limit, offset);
const doSearch = () => {
offset = 0;
request = getBuckets();
};
let request = getBuckets();
</script>
<form on:submit|preventDefault={doSearch}>
<input type="search" bind:value={search} />
</form>
<Card>
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCell>#</TableCell>
<TableCell>Type</TableCell>
<TableCell>Size</TableCell>
<TableCell>Date Created</TableCell>
</TableHeader>
<TableBody>
{#each response.files as file}
<TableRow>
<TableCell>
<a href={`/console/${project}/storage/bucket/${bucket}/${file.$id}`}>
{file.$id}
</a>
</TableCell>
<TableCell>{file.mimeType}</TableCell>
<TableCell>{file.sizeOriginal}</TableCell>
<TableCell>{file.dateCreated}</TableCell>
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination
{limit}
bind:offset
sum={response.total}
on:change={() => (request = getBuckets())}
/>
{/await}
</Card>
<Button on:click={() => (showCreate = true)}>Upload</Button>
<Create bind:showCreate on:created={() => (request = getBuckets())} />
@@ -0,0 +1 @@
<h1>Settings</h1>
@@ -0,0 +1,17 @@
import { sdkForProject } from '$lib/stores/sdk';
import type { Models } from 'src/sdk';
import { writable } from 'svelte/store';
function createBucketStore() {
const { subscribe, set } = writable<Models.Bucket>();
return {
subscribe,
set,
load: async (bucketId: string) => {
set(await sdkForProject.storage.getBucket(bucketId));
}
};
}
export const bucket = createBucketStore();
@@ -0,0 +1 @@
<h1>Usage</h1>
@@ -1,9 +1,9 @@
<script lang="ts">
import { page } from '$app/stores';
import { sdkForProject } from '$lib/stores/sdk';
import { Table, TableRow, TableBody, TableHeader, TableCell } from '$lib/elements/table';
import { Button } from '$lib/elements/forms';
import { Pagination } from '$lib/components';
import { Table, TableHeader, TableCell, TableBody, TableRow } from '$lib/elements/table';
import { Card, Pagination } from '$lib/components';
import Create from './_create.svelte';
let search = '';
@@ -12,48 +12,49 @@
const limit = 25;
const project = $page.params.project;
const getUsers = () => sdkForProject.storage.listFiles(search, limit, offset);
const getCollections = () => sdkForProject.storage.listBuckets(search, limit, offset);
const doSearch = () => {
offset = 0;
request = getUsers();
request = getCollections();
};
let request = getUsers();
let request = getCollections();
</script>
<form on:submit|preventDefault={doSearch}>
<input type="search" bind:value={search} />
</form>
<h1>Buckets</h1>
<Card>
<form on:submit|preventDefault={doSearch}>
<input type="search" bind:value={search} />
</form>
</Card>
<section>
<Card>
{#await request}
<div aria-busy="true" />
{:then response}
<Table>
<TableHeader>
<TableCell>#</TableCell>
<TableCell>Type</TableCell>
<TableCell>Size</TableCell>
<TableCell>Date Created</TableCell>
<TableCell>Name</TableCell>
</TableHeader>
<TableBody>
{#each response.files as file}
{#each response.buckets as bucket}
<TableRow>
<TableCell>
<a href={`/console/${project}/storage/${file.$id}`}>
{file.$id}
</a>
<a href={`/console/${project}/storage/bucket/${bucket.$id}`}>{bucket.$id}</a>
</TableCell>
<TableCell>{file.mimeType}</TableCell>
<TableCell>{file.sizeOriginal}</TableCell>
<TableCell>{file.dateCreated}</TableCell>
<TableCell>{bucket.name}</TableCell>
</TableRow>
{/each}
</TableBody>
</Table>
<Pagination {limit} bind:offset sum={response.sum} on:change={() => (request = getUsers())} />
<Pagination
{limit}
bind:offset
sum={response.total}
on:change={() => (request = getCollections())}
/>
{/await}
</section>
</Card>
<Button on:click={() => (showCreate = true)}>Upload</Button>
<Create bind:showCreate on:created={() => (request = getUsers())} />
<Button on:click={() => (showCreate = true)}>Create Bucket</Button>
<Create bind:showCreate on:created={() => (request = getCollections())} />
@@ -0,0 +1 @@
<h1>Usage</h1>
@@ -1,11 +1,13 @@
<script lang="ts">
import { page } from '$app/stores';
import { Back } from '$lib/components';
import Tabs from './_tabs.svelte';
$: project = $page.params.project;
const project = $page.params.project;
</script>
{#if !($page.url.pathname.startsWith(`/console/${project}/users/user/`) || $page.url.pathname.startsWith(`/console/${project}/users/team/`))}
{#if $page.url.pathname.endsWith(`/users/`) || $page.url.pathname.endsWith(`/users/team/`) || $page.url.pathname.endsWith(`/users/usage/`) || $page.url.pathname.endsWith(`/users/settings/`)}
<Back href={`/console/${project}`}>Home</Back>
<h1>Users</h1>
<Tabs />
{/if}
@@ -8,8 +8,8 @@
<li class="tabs-item">
<a
class="tabs-button"
href={`/console/${project}/users`}
class:is-selected={$page.url.pathname === `/console/${project}/users`}
href={`/console/${project}/users/`}
class:is-selected={$page.url.pathname === `/console/${project}/users/`}
>
<span class="text">Users</span>
</a>
@@ -17,8 +17,8 @@
<li class="tabs-item">
<a
class="tabs-button"
href={`/console/${project}/users/team`}
class:is-selected={$page.url.pathname === `/console/${project}/users/team`}
href={`/console/${project}/users/team/`}
class:is-selected={$page.url.pathname === `/console/${project}/users/team/`}
>
<span class="text">Teams</span>
</a>
@@ -26,8 +26,8 @@
<li class="tabs-item">
<a
class="tabs-button"
href={`/console/${project}/users/settings`}
class:is-selected={$page.url.pathname === `/console/${project}/users/settings`}
href={`/console/${project}/users/settings/`}
class:is-selected={$page.url.pathname === `/console/${project}/users/settings/`}
>
<span class="text">Settings</span>
</a>
@@ -35,8 +35,8 @@
<li class="tabs-item">
<a
class="tabs-button"
href={`/console/${project}/users/usage`}
class:is-selected={$page.url.pathname === `/console/${project}/users/usage`}
href={`/console/${project}/users/usage/`}
class:is-selected={$page.url.pathname === `/console/${project}/users/usage/`}
>
<span class="text">Usage</span>
</a>
@@ -0,0 +1,11 @@
<script lang="ts">
import { page } from '$app/stores';
import { Back } from '$lib/components';
const project = $page.params.project;
</script>
<Back href={`/console/${project}/users`}>Users</Back>
<slot />
@@ -2,6 +2,7 @@
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { Card } from '$lib/components';
import { Button } from '$lib/elements/forms';
import { sdkForProject } from '$lib/stores/sdk';
@@ -34,13 +35,13 @@
<div aria-busy="true" />
{:then [team, members]}
<h1>Overview</h1>
<article class="overview">
<Card>
<p>{team.$id}</p>
<p>Created {team.dateCreated}</p>
</article>
</Card>
<h1>Members</h1>
<article>
<Card>
{#each members.memberships as membership}
<p>
{membership.name}
@@ -53,15 +54,7 @@
{:else}
No members found.
{/each}
</article>
</Card>
<Button on:click={() => deleteTeam(team.$id)}>Delete Team</Button>
{/await}
<style lang="scss">
article.overview {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
@@ -3,7 +3,7 @@
import { sdkForProject } from '$lib/stores/sdk';
import { Table, TableHeader, TableCell, TableBody, TableRow } from '$lib/elements/table';
import { Button } from '$lib/elements/forms';
import { Pagination } from '$lib/components';
import { Card, Pagination } from '$lib/components';
import Create from './_create.svelte';
let search = '';
@@ -21,10 +21,13 @@
</script>
<h1>Teams</h1>
<form on:submit|preventDefault={doSearch}>
<input type="search" bind:value={search} />
</form>
<section>
<Card>
<form on:submit|preventDefault={doSearch}>
<input type="search" bind:value={search} />
</form>
</Card>
<Card>
{#await request}
<div aria-busy="true" />
{:then response}
@@ -51,7 +54,7 @@
<Pagination {limit} bind:offset sum={response.total} on:change={() => (request = getTeams())} />
{/await}
</section>
</Card>
<Button on:click={() => (showCreate = true)}>Create Team</Button>
<Create bind:showCreate on:created={() => (request = getTeams())} />
@@ -1,9 +1,11 @@
<script lang="ts">
import { browser } from '$app/env';
import { page } from '$app/stores';
import { Back } from '$lib/components';
import { user } from './store';
import Tabs from './_tabs.svelte';
const project = $page.params.project;
const userId = $page.params.user;
$: {
@@ -13,6 +15,7 @@
}
</script>
<Back href={`/console/${project}/users`}>Users</Back>
{#if $user}
<h1>{$user.name}</h1>
<Tabs />
@@ -6,7 +6,7 @@
<ul class="tabs">
<li class="tabs-item">
<a class="tabs-button" href={path} class:is-selected={$page.url.pathname === path}>
<a class="tabs-button" href={path} class:is-selected={$page.url.pathname === `${path}/`}>
<span class="text">Overview</span>
</a>
</li>
@@ -14,7 +14,7 @@
<a
class="tabs-button"
href={`${path}/sessions`}
class:is-selected={$page.url.pathname === `${path}/sessions`}
class:is-selected={$page.url.pathname === `${path}/sessions/`}
>
<span class="text">Sessions</span>
</a>
@@ -23,7 +23,7 @@
<a
class="tabs-button"
href={`${path}/activity`}
class:is-selected={$page.url.pathname === `${path}/activity`}
class:is-selected={$page.url.pathname === `${path}/activity/`}
>
<span class="text">Activity</span>
</a>
@@ -43,22 +43,3 @@
<p>PLEASE NOTE: User deletion is irreversible.</p>
<Button on:click={() => deleteUser($user.$id)}>Delete User</Button>
</Card>
<style lang="scss">
article.overview {
display: flex;
flex-direction: column;
align-items: center;
.avatar {
border-radius: 50%;
}
}
article.danger {
background-color: #f53d3d;
p {
color: #ffffff;
}
}
</style>
+2 -2
View File
@@ -5962,7 +5962,7 @@ class Appwrite {
entrypoint: string,
code: File,
activate: boolean,
onProgress = (progress: UploadProgress) => {}
onProgress?: (progress: UploadProgress) => UploadProgress
): Promise<Models.Deployment> => {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
@@ -8628,7 +8628,7 @@ class Appwrite {
file: File,
read?: string[],
write?: string[],
onProgress = (progress: UploadProgress) => {}
onProgress?: (progress: UploadProgress) => UploadProgress
): Promise<Models.File> => {
if (typeof bucketId === 'undefined') {
throw new AppwriteException('Missing required parameter: "bucketId"');
-1
View File
@@ -6,7 +6,6 @@ const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: preprocess(),
kit: {
adapter: adapter(),
trailingSlash: 'always'