Merge branch 'main' into fix-env-upload

This commit is contained in:
Torsten Dittmann
2023-03-23 13:36:21 +01:00
committed by GitHub
20 changed files with 332 additions and 147 deletions
+4 -32
View File
@@ -9,7 +9,7 @@
"version": "0.0.1",
"dependencies": {
"@analytics/google-analytics": "^1.0.5",
"@appwrite.io/pink": "^0.0.4",
"@appwrite.io/pink": "0.0.6-rc.2",
"@aw-labs/appwrite-console": "^13.1.0",
"@popperjs/core": "^2.11.6",
"@sentry/svelte": "^7.44.2",
@@ -148,9 +148,9 @@
"integrity": "sha512-1Yw7u/COtxx06BfwlI+kVhsa/upKYzmCNrT4c8QDeCY2KMYlnijkUjtHiPU08HxyTIVB5j6d75O0YWVIHwQS8g=="
},
"node_modules/@appwrite.io/pink": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/@appwrite.io/pink/-/pink-0.0.4.tgz",
"integrity": "sha512-pCXxBqSikG5PpBb2y84tTRH6cAMUYbROlQN8LuGoY2J+vTWMT+HQ7+RAAwRWU1Dlle4FgOFFCKmqU95g6X2a6g==",
"version": "0.0.6-rc.2",
"resolved": "https://registry.npmjs.org/@appwrite.io/pink/-/pink-0.0.6-rc.2.tgz",
"integrity": "sha512-PR2TVhLgRwXfdrB+0w9pZv7X2n6WOawArSJXq8jsRF58EzWcl4nf8XkjTsJ9BSU+in9fkmhxNIBywM707jqUcg==",
"dependencies": {
"@appwrite.io/pink-icons": "*",
"normalize.css": "^8.0.1",
@@ -4521,23 +4521,6 @@
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
"dev": true
},
"node_modules/happy-dom": {
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-8.9.0.tgz",
"integrity": "sha512-JZwJuGdR7ko8L61136YzmrLv7LgTh5b8XaEM3P709mLjyQuXJ3zHTDXvUtBBahRjGlcYW0zGjIiEWizoTUGKfA==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"css.escape": "^1.5.1",
"he": "^1.2.0",
"iconv-lite": "^0.6.3",
"node-fetch": "^2.x.x",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^2.0.0",
"whatwg-mimetype": "^3.0.0"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -4607,17 +4590,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true,
"optional": true,
"peer": true,
"bin": {
"he": "bin/he"
}
},
"node_modules/html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
+1 -1
View File
@@ -20,7 +20,7 @@
},
"dependencies": {
"@analytics/google-analytics": "^1.0.5",
"@appwrite.io/pink": "^0.0.4",
"@appwrite.io/pink": "0.0.6-rc.2",
"@aw-labs/appwrite-console": "^13.1.0",
"@popperjs/core": "^2.11.6",
"@sentry/svelte": "^7.44.2",
+1 -1
View File
@@ -104,7 +104,7 @@
<Row {role} />
</TableCell>
<TableCellText title="Remove">
<div class="u-flex">
<div class="u-flex u-main-end">
<button
class="button is-text is-only-icon"
type="button"
+3
View File
@@ -0,0 +1,3 @@
export function isMac(): boolean {
return window.navigator.platform.toUpperCase().indexOf('MAC') >= 0;
}
+48
View File
@@ -0,0 +1,48 @@
import { cubicOut } from 'svelte/easing';
import type { EasingFunction, TransitionConfig } from 'svelte/transition';
export interface SlideParams {
delay?: number;
duration?: number;
easing?: EasingFunction;
axis?: 'x' | 'y';
}
export function slide(
node: Element,
{ delay = 0, duration = 400, easing = cubicOut, axis = 'y' }: SlideParams = {}
): TransitionConfig {
const style = getComputedStyle(node);
const opacity = +style.opacity;
const primary_property = axis === 'y' ? 'height' : 'width';
const primary_property_value = parseFloat(style[primary_property]);
const secondary_properties = axis === 'y' ? ['top', 'bottom'] : ['left', 'right'];
const capitalized_secondary_properties = secondary_properties.map(
(e) => `${e[0].toUpperCase()}${e.slice(1)}`
);
const padding_start_value = parseFloat(style[`padding${capitalized_secondary_properties[0]}`]);
const padding_end_value = parseFloat(style[`padding${capitalized_secondary_properties[1]}`]);
const margin_start_value = parseFloat(style[`margin${capitalized_secondary_properties[0]}`]);
const margin_end_value = parseFloat(style[`margin${capitalized_secondary_properties[1]}`]);
const border_width_start_value = parseFloat(
style[`border${capitalized_secondary_properties[0]}Width`]
);
const border_width_end_value = parseFloat(
style[`border${capitalized_secondary_properties[1]}Width`]
);
return {
delay,
duration,
easing,
css: (t) =>
'overflow: hidden;' +
`opacity: ${Math.min(t * 20, 1) * opacity};` +
`${primary_property}: ${t * primary_property_value}px;` +
`padding-${secondary_properties[0]}: ${t * padding_start_value}px;` +
`padding-${secondary_properties[1]}: ${t * padding_end_value}px;` +
`margin-${secondary_properties[0]}: ${t * margin_start_value}px;` +
`margin-${secondary_properties[1]}: ${t * margin_end_value}px;` +
`border-${secondary_properties[0]}-width: ${t * border_width_start_value}px;` +
`border-${secondary_properties[1]}-width: ${t * border_width_end_value}px;`
};
}
+10 -8
View File
@@ -5,12 +5,14 @@
</script>
<Heading size="4" tag="h1" trimmed={false}>
{#if href}
<a class="button is-text is-only-icon" {href} aria-label="page back">
<span class="icon-cheveron-left" aria-hidden="true" />
</a>
{/if}
<span class="text u-trim-1" data-private>
<slot />
</span>
<div class="u-flex u-cross-center">
{#if href}
<a class="button is-text is-only-icon" {href} aria-label="page back">
<span class="icon-cheveron-left" aria-hidden="true" />
</a>
{/if}
<span class="text u-trim-1" data-private>
<slot />
</span>
</div>
</Heading>
+3 -3
View File
@@ -11,13 +11,13 @@
<ul class="inline-links is-no-padding-first-and-last u-x-small">
<li class="inline-links-item">
<div class="u-flex u-cross-center u-gap-8">
{#if MODE === Mode.CLOUD}
{#if MODE !== Mode.CLOUD}
<span class="icon-cloud" />
{/if}
{#if $version}
<a
class="text"
href="https://github.com/appwrite/appwrite/blob/master/CHANGES.md"
href="https://github.com/appwrite/appwrite/releases"
target="_blank"
rel="noreferrer">
Version {$version}
@@ -62,7 +62,7 @@
margin-block-start: auto;
}
[class^='icon-']:not(:hover) {
[class^='icon-']:not(.icon-cloud):not(:hover) {
color: hsl(var(--color-neutral-50));
}
</style>
+160 -70
View File
@@ -2,81 +2,171 @@
import { base } from '$app/paths';
import { page } from '$app/stores';
import { trackEvent } from '$lib/actions/analytics';
import { tooltip } from '$lib/actions/tooltip';
import { isMac } from '$lib/helpers/platform';
import { slide } from '$lib/helpers/transition';
$: project = $page.params.project;
$: path = `${base}/console/project-${project}`;
$: projectPath = `${base}/console/project-${project}`;
$: subNavigation = $page.data.subNavigation;
// We need to have this second variable, because we only want narrow
// to change automatically if we change from having a second side nav to
// not having one, not when the second side nav changes to a different value.
$: hasSubNavigation = !!subNavigation;
let narrow = false;
$: {
narrow = hasSubNavigation;
}
function handleKeyDown(event: KeyboardEvent) {
// If Alt + S is pressed
if (hasSubNavigation && event.altKey && event.keyCode === 83) {
event.preventDefault();
narrow = !narrow;
}
}
</script>
<div class="side-nav">
{#if project}
<div class="side-nav-main">
<section class="drop-section">
<ul class="drop-list">
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(`${path}/overview`)}
on:click={() => trackEvent('click_menu_overview')}
href={path}>
<span class="icon-chart-bar" aria-hidden="true" />
<span class="text">Overview</span>
</a>
</li>
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(`${path}/auth`)}
on:click={() => trackEvent('click_menu_auth')}
href={`${path}/auth`}>
<span class="icon-user-group" aria-hidden="true" />
<span class="text">Auth</span>
</a>
</li>
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(`${path}/databases`)}
on:click={() => trackEvent('click_menu_databases')}
href={`${path}/databases`}>
<span class="icon-database" aria-hidden="true" />
<span class="text">Databases</span>
</a>
</li>
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(`${path}/functions`)}
on:click={() => trackEvent('click_menu_functions')}
href={`${path}/functions`}>
<span class="icon-lightning-bolt" aria-hidden="true" />
<span class="text">Functions</span>
</a>
</li>
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(`${path}/storage`)}
on:click={() => trackEvent('click_menu_storage')}
href={`${path}/storage`}>
<span class="icon-folder" aria-hidden="true" />
<span class="text">Storage</span>
</a>
</li>
</ul>
</section>
</div>
<svelte:window on:keydown={handleKeyDown} />
<div class="side-nav-bottom">
<section class="drop-section">
<a
class="drop-button"
href={`${path}/settings`}
on:click={() => trackEvent('click_menu_settings')}
class:is-selected={$page.url.pathname.startsWith(`${path}/settings`)}>
<span class="icon-cog" aria-hidden="true" />
<span class="text">Settings</span>
</a>
</section>
<div class="side-nav" class:is-open-level-2={hasSubNavigation}>
<div class="side-nav-level-1" class:is-narrow={narrow}>
{#if project}
<div class="side-nav-main">
<section class="drop-section">
<ul class="drop-list">
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(
`${projectPath}/overview`
)}
on:click={() => trackEvent('click_menu_overview')}
href={projectPath}
use:tooltip={{
content: 'Overview',
placement: 'right',
disabled: !narrow
}}>
<span class="icon-chart-bar" aria-hidden="true" />
<span class="text">Overview</span>
</a>
</li>
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(
`${projectPath}/auth`
)}
on:click={() => trackEvent('click_menu_auth')}
href={`${projectPath}/auth`}
use:tooltip={{
content: 'Auth',
placement: 'right',
disabled: !narrow
}}>
<span class="icon-user-group" aria-hidden="true" />
<span class="text">Auth</span>
</a>
</li>
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(
`${projectPath}/databases`
)}
on:click={() => trackEvent('click_menu_databases')}
href={`${projectPath}/databases`}
use:tooltip={{
content: 'Databases',
placement: 'right',
disabled: !narrow
}}>
<span class="icon-database" aria-hidden="true" />
<span class="text">Databases</span>
</a>
</li>
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(
`${projectPath}/functions`
)}
on:click={() => trackEvent('click_menu_functions')}
href={`${projectPath}/functions`}
use:tooltip={{
content: 'Functions',
placement: 'right',
disabled: !narrow
}}>
<span class="icon-lightning-bolt" aria-hidden="true" />
<span class="text">Functions</span>
</a>
</li>
<li class="drop-list-item">
<a
class="drop-button"
class:is-selected={$page.url.pathname.startsWith(
`${projectPath}/storage`
)}
on:click={() => trackEvent('click_menu_storage')}
href={`${projectPath}/storage`}
use:tooltip={{
content: 'Storage',
placement: 'right',
disabled: !narrow
}}>
<span class="icon-folder" aria-hidden="true" />
<span class="text">Storage</span>
</a>
</li>
</ul>
</section>
</div>
<div class="side-nav-bottom">
<section class="drop-section">
<a
class="drop-button"
href={`${projectPath}/settings`}
on:click={() => trackEvent('click_menu_settings')}
class:is-selected={$page.url.pathname.startsWith(`${projectPath}/settings`)}
title="Settings"
use:tooltip={{
content: 'Settings',
placement: 'right',
disabled: !narrow
}}>
<span class="icon-cog" aria-hidden="true" />
<span class="text">Settings</span>
</a>
</section>
</div>
{/if}
{#if subNavigation}
<button
class="side-nav-button button is-small is-secondary is-not-mobile"
aria-label="resize menu"
on:click={() => (narrow = !narrow)}
use:tooltip={{
content: isMac() ? '⌥ + S' : 'Alt + S'
}}>
<span
class:icon-cheveron-right={narrow}
class:icon-cheveron-left={!narrow}
aria-hidden="true" />
</button>
{/if}
</div>
{#if subNavigation}
<div class="side-nav-level-2 is-open" transition:slide={{ axis: 'x', duration: 250 }}>
<div class="side-nav-main">
<svelte:component this={subNavigation} />
</div>
</div>
{/if}
</div>
+5
View File
@@ -87,6 +87,11 @@
top: 4.5rem;
}
}
@media (min-width: 1199px) {
.grid-with-side {
grid-template-columns: auto 1fr !important;
}
}
.main-content {
overflow: hidden;
@@ -1,6 +1,6 @@
import type { LayoutLoad } from './$types';
import Breadcrumbs from './breadcrumbs.svelte';
import Header from './header.svelte';
import type { LayoutLoad } from './$types';
export const load: LayoutLoad = async () => {
return {
@@ -1,5 +1,28 @@
<script lang="ts">
import { goto, invalidate } from '$app/navigation';
import type { Models } from '@aw-labs/appwrite-console';
import CreateCollection from './createCollection.svelte';
import { showCreate } from './store';
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Dependencies } from '$lib/constants';
const project = $page.params.project;
const databaseId = $page.params.database;
async function handleCreate(event: CustomEvent<Models.Collection>) {
$showCreate = false;
await invalidate(Dependencies.DATABASE);
await goto(
`${base}/console/project-${project}/databases/database-${databaseId}/collection-${event.detail.$id}`
);
}
</script>
<svelte:head>
<title>Database - Appwrite</title>
</svelte:head>
<slot />
<CreateCollection bind:showCreate={$showCreate} on:created={handleCreate} />
@@ -1,9 +1,9 @@
import { sdk } from '$lib/stores/sdk';
import { Dependencies } from '$lib/constants';
import { error } from '@sveltejs/kit';
import type { LayoutLoad } from './$types';
import Breadcrumbs from './breadcrumbs.svelte';
import Header from './header.svelte';
import { error } from '@sveltejs/kit';
export const load: LayoutLoad = async ({ params, depends }) => {
depends(Dependencies.DATABASE);
@@ -1,38 +1,28 @@
<script lang="ts">
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { Button } from '$lib/elements/forms';
import { Empty, Copy, GridItem1, CardContainer, Heading, Pagination } from '$lib/components';
import { Pill } from '$lib/elements';
import { Container } from '$lib/layout';
import { base } from '$app/paths';
import { page } from '$app/stores';
import { CardContainer, Copy, Empty, GridItem1, Heading, Pagination } from '$lib/components';
import { CARD_LIMIT } from '$lib/constants';
import { Pill } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import { Container } from '$lib/layout';
import { cardLimit } from '$lib/stores/layout';
import { createPersistentPagination } from '$lib/stores/pagination';
import { showCreate } from '../store';
import type { PageData } from './$types';
import type { Models } from '@aw-labs/appwrite-console';
import Create from '../create.svelte';
import { CARD_LIMIT } from '$lib/constants';
export let data: PageData;
let showCreate = false;
const project = $page.params.project;
const databaseId = $page.params.database;
const offset = createPersistentPagination($cardLimit);
async function handleCreate(event: CustomEvent<Models.Collection>) {
showCreate = false;
await goto(
`${base}/console/project-${project}/databases/database-${databaseId}/collection-${event.detail.$id}`
);
}
</script>
<Container>
<div class="u-flex u-gap-12 common-section u-main-space-between">
<Heading tag="h2" size="5">Collections</Heading>
<Button on:click={() => (showCreate = true)} event="create_collection">
<Button on:click={() => ($showCreate = true)} event="create_collection">
<span class="icon-plus" aria-hidden="true" />
<span class="text">Create collection</span>
</Button>
@@ -43,7 +33,7 @@
event="collection"
total={data.collections.total}
offset={$offset}
on:click={() => (showCreate = true)}>
on:click={() => ($showCreate = true)}>
{#each data.collections.collections as collection}
<GridItem1
href={`${base}/console/project-${project}/databases/database-${databaseId}/collection-${collection.$id}`}>
@@ -76,8 +66,6 @@
single
href="https://appwrite.io/docs/databases#collection"
target="collection"
on:click={() => (showCreate = true)} />
on:click={() => ($showCreate = true)} />
{/if}
</Container>
<Create bind:showCreate on:created={handleCreate} />
@@ -4,6 +4,8 @@ import type { LayoutLoad } from './$types';
import Breadcrumbs from './breadcrumbs.svelte';
import Header from './header.svelte';
import { error } from '@sveltejs/kit';
import SubNavigation from './subNavigation.svelte';
import { Query } from '@aw-labs/appwrite-console';
export const load: LayoutLoad = async ({ params, depends }) => {
depends(Dependencies.COLLECTION);
@@ -14,7 +16,11 @@ export const load: LayoutLoad = async ({ params, depends }) => {
collection: await sdk.forProject.databases.getCollection(
params.database,
params.collection
)
),
subNavigation: SubNavigation,
allCollections: await sdk.forProject.databases.listCollections(params.database, [
Query.orderDesc('$createdAt')
])
};
} catch (e) {
throw error(e.code, e.message);
@@ -6,11 +6,11 @@
import { Cover, CoverTitle } from '$lib/layout';
import { collection } from './store';
const projectId = $page.params.project;
const databaseId = $page.params.database;
const collectionId = $page.params.collection;
const path = `/console/project-${projectId}/databases/database-${databaseId}/collection-${collectionId}`;
const tabs = [
$: projectId = $page.params.project;
$: databaseId = $page.params.database;
$: collectionId = $page.params.collection;
$: path = `/console/project-${projectId}/databases/database-${databaseId}/collection-${collectionId}`;
$: tabs = [
{
href: path,
title: 'Documents',
@@ -133,6 +133,7 @@
<div class="form-item-part u-cross-child-end">
<Button
noMargin
text
disabled={attributeList.length <= 1}
on:click={() => {
@@ -1,9 +1,10 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { goto, invalidate } from '$app/navigation';
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
import { Modal } from '$lib/components';
import { Dependencies } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
@@ -25,6 +26,7 @@
await goto(
`${base}/console/project-${$page.params.project}/databases/database-${$page.params.database}`
);
invalidate(Dependencies.DATABASE);
} catch (error) {
addNotification({
type: 'error',
@@ -0,0 +1,44 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { showCreate } from '../store';
import type { PageData } from './[[page]]/$types';
$: data = $page.data as PageData;
$: project = $page.params.project;
$: databaseId = $page.params.database;
$: collectionId = $page.params.collection;
$: sortedCollections = data?.allCollections?.collections?.sort((a, b) =>
a.name.localeCompare(b.name)
);
</script>
<section class="drop-section u-flex-vertical u-gap-8">
<a
class="u-flex u-cross-center u-sep-block-end u-padding-block-12 is-not-desktop"
href={`${base}/console/project-${project}/databases/database-${databaseId}`}>
<span class="icon-cheveron-left" aria-hidden="true" />
<h5 class="eyebrow-heading-3 u-margin-inline-auto">Collections</h5>
</a>
<h5 class="eyebrow-heading-3 u-padding-block-12 is-not-mobile">Collections</h5>
<button
class="button is-text is-full-width u-main-start u-padding-inline-0"
on:click={() => ($showCreate = true)}>
<span class="icon-plus" aria-hidden="true" />
<span class="text">Create collection</span>
</button>
{#if data?.allCollections?.total}
<ul class="drop-list">
{#each sortedCollections as collection}
{@const href = `${base}/console/project-${project}/databases/database-${databaseId}/collection-${collection.$id}/documents`}
{@const isSelected = collectionId === collection.$id}
<li class="drop-list-item">
<a class="drop-button" class:is-selected={isSelected} {href}>
<span class="text">{collection.name}</span>
</a>
</li>
{/each}
</ul>
{/if}
</section>
@@ -1,5 +1,6 @@
import { derived } from 'svelte/store';
import { page } from '$app/stores';
import type { Models } from '@aw-labs/appwrite-console';
import { derived, writable } from 'svelte/store';
export const database = derived(page, ($page) => $page.data.database as Models.Database);
export const showCreate = writable(false);