feat: overview screen

This commit is contained in:
Arman
2025-03-07 12:03:17 +01:00
parent 5b80c9d1fc
commit d9b3fb663d
5 changed files with 155 additions and 169 deletions
+23 -17
View File
@@ -1,26 +1,32 @@
<script lang="ts">
import PaginationInline from './paginationInline.svelte';
import { Card, Empty } from '@appwrite.io/pink-svelte';
import { Card, Empty, Layout } from '@appwrite.io/pink-svelte';
export let hidePagination = false;
export let hidePages = false;
export let target = '';
export let search = '';
</script>
<Card.Base padding="none">
<Empty
title={`Sorry, we couldn't find ${search ? `‘${search}’` : `any ${target}`}`}
description={`There are no ${target} that match your search.`}
type="secondary">
<svelte:fragment slot="actions">
<slot />
</svelte:fragment>
</Empty>
</Card.Base>
<Layout.Stack gap="l">
<Card.Base padding="none">
<Empty
title={`Sorry, we couldn't find ${search ? `‘${search}’` : `any ${target}`}`}
description={`There are no ${target} that match your search.`}
type="secondary">
<svelte:fragment slot="actions">
<slot />
</svelte:fragment>
</Empty>
</Card.Base>
{#if !hidePagination}
<div class="u-flex u-margin-block-start-32 u-main-space-between u-cross-center">
<p class="text">Total results: 0</p>
<PaginationInline limit={1} offset={0} sum={0} {hidePages} />
</div>
{/if}
{#if !hidePagination}
<Layout.Stack
direction="row"
justifyContent="space-between"
alignItems="center"
wrap="wrap">
<p class="text">Total results: 0</p>
<PaginationInline limit={1} offset={0} sum={0} {hidePages} />
</Layout.Stack>
{/if}
</Layout.Stack>
+81 -70
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { EmptySearch } from '$lib/components';
import { EmptySearch, Paginator } from '$lib/components';
import { Button, InputSearch, InputSelect } from '$lib/elements/forms';
import { timeFromNow } from '$lib/helpers/date';
import { sdk } from '$lib/stores/sdk';
@@ -143,79 +143,90 @@
</Table.Root>
{:then response}
{#if response?.length}
<Table.Root>
{#each response as repo}
<Table.Row>
<Table.Cell>
<Layout.Stack direction="row" alignItems="center" gap="s">
{#if action === 'select'}
<input
class="is-small u-margin-inline-end-8"
type="radio"
name="repositories"
bind:group={selectedRepository}
on:change={() => repository.set(repo)}
value={repo.id} />
{/if}
{#if product === 'sites'}
{#await detectFramework(repo)}
<Avatar size="xs" alt={repo.name} empty />
{:then framework}
<Avatar
size="xs"
alt={repo.name}
empty={!framework}>
<SvgIcon
name={getFrameworkIcon(framework)}
iconSize="small" />
</Avatar>
{/await}
{:else}
{@const iconName = repo?.runtime
? repo.runtime.split('-')[0]
: undefined}
<Avatar size="xs" alt={repo.name} empty={!iconName}>
<SvgIcon name={iconName} iconSize="small" />
</Avatar>
{/if}
<Layout.Stack gap="s" direction="row" alignItems="center">
<Typography.Text
truncate
color="--fgcolor-neutral-secondary">
{repo.name}
</Typography.Text>
{#if repo.private}
<Icon
size="s"
icon={IconLockClosed}
color="--fgcolor-neutral-tertiary" />
<Paginator
items={response}
let:paginatedItems
hideFooter={response?.length <= 6}
limit={6}>
<Table.Root>
{#each paginatedItems as repo}
<Table.Row>
<Table.Cell>
<Layout.Stack direction="row" alignItems="center" gap="s">
{#if action === 'select'}
<input
class="is-small u-margin-inline-end-8"
type="radio"
name="repositories"
bind:group={selectedRepository}
on:change={() => repository.set(repo)}
value={repo.id} />
{/if}
<time datetime={repo.pushedAt}>
<Typography.Caption
variant="400"
{#if product === 'sites'}
{#await detectFramework(repo)}
<Avatar size="xs" alt={repo.name} empty />
{:then framework}
<Avatar
size="xs"
alt={repo.name}
empty={!framework}>
<SvgIcon
name={getFrameworkIcon(framework)}
iconSize="small" />
</Avatar>
{/await}
{:else}
{@const iconName = repo?.runtime
? repo.runtime.split('-')[0]
: undefined}
<Avatar size="xs" alt={repo.name} empty={!iconName}>
<SvgIcon name={iconName} iconSize="small" />
</Avatar>
{/if}
<Layout.Stack
gap="s"
direction="row"
alignItems="center">
<Typography.Text
truncate
color="--fgcolor-neutral-tertiary">
{timeFromNow(repo.pushedAt)}
</Typography.Caption>
</time>
</Layout.Stack>
{#if action === 'button'}
<Layout.Stack direction="row" justifyContent="flex-end">
<PinkButton.Button
size="xs"
variant="secondary"
on:click={() => dispatch('connect', repo)}>
Connect
</PinkButton.Button>
color="--fgcolor-neutral-secondary">
{repo.name}
</Typography.Text>
{#if repo.private}
<Icon
size="s"
icon={IconLockClosed}
color="--fgcolor-neutral-tertiary" />
{/if}
<time datetime={repo.pushedAt}>
<Typography.Caption
variant="400"
truncate
color="--fgcolor-neutral-tertiary">
{timeFromNow(repo.pushedAt)}
</Typography.Caption>
</time>
</Layout.Stack>
{/if}
</Layout.Stack>
</Table.Cell>
</Table.Row>
{/each}
</Table.Root>
{#if action === 'button'}
<Layout.Stack
direction="row"
justifyContent="flex-end">
<PinkButton.Button
size="xs"
variant="secondary"
on:click={() => dispatch('connect', repo)}>
Connect
</PinkButton.Button>
</Layout.Stack>
{/if}
</Layout.Stack>
</Table.Cell>
</Table.Row>
{/each}
</Table.Root>
</Paginator>
{:else}
<EmptySearch hidePages bind:search target="repositories">
<EmptySearch hidePages hidePagination bind:search target="repositories">
<svelte:fragment slot="actions">
{#if search}
<Button secondary on:click={() => (search = '')}>
@@ -1,6 +1,6 @@
<script lang="ts">
import { base } from '$app/paths';
import { AvatarGroup, SvgIcon } from '$lib/components';
import { SvgIcon } from '$lib/components';
import { page } from '$app/stores';
import { Click, trackEvent } from '$lib/actions/analytics';
import type { Models } from '@appwrite.io/console';
@@ -11,14 +11,14 @@
import { Repositories } from '$lib/components/git';
import {
Avatar,
Badge,
Card,
Divider,
Icon,
Layout,
Tooltip,
Typography
} from '@appwrite.io/pink-svelte';
import { IconArrowSmRight, IconDeno, IconDotnet } from '@appwrite.io/pink-icons-svelte';
import { IconArrowSmRight } from '@appwrite.io/pink-icons-svelte';
import Wizard from '$lib/layout/wizard.svelte';
import { Link } from '$lib/elements';
@@ -66,11 +66,11 @@
$: console.log(data);
</script>
<Wizard title="Create function" href={previousPage} column>
<Wizard title="Create function" href={previousPage} column columnSize="l">
<div class="git-container u-position-relative">
<Layout.Stack>
<Layout.Stack gap="l">
<!-- TODO: fix mobile -->
<Layout.GridFraction start={4} end={6} gap="l">
<Layout.GridFraction start={4} end={6} gap="l" rowSize="auto">
<Card.Base>
<Layout.Stack
gap="xl"
@@ -108,7 +108,7 @@
<Card.Base>
<Layout.Stack gap="xl">
<Typography.Title size="s">Quick start</Typography.Title>
<Layout.Grid columnsXXS={1} columnsXS={2} columnsS={3} columns={4}>
<Layout.Grid columnsXXS={1} columnsXS={2} columnsS={3} columns={4} gap="s">
{#each starterTemplateRuntimes.slice(0, 6) as template}
{@const iconName = template.name.split('-')[0]}
{@const runtimeDetail = baseRuntimesList.find(
@@ -133,27 +133,23 @@
empty={!template.name}>
<SvgIcon name={iconName} iconSize="small" />
</Avatar>
<Typography.Text>
{runtimeDetail?.name}
{#if runtimeDetail?.name?.toLowerCase() === 'deno'}
<span class="inline-tag">New</span>
{/if}
<Typography.Text color="--fgcolor-neutral-primary">
<Layout.Stack
direction="row"
gap="xs"
alignItems="center">
{runtimeDetail?.name}
{#if runtimeDetail?.name?.toLowerCase() === 'deno'}
<Badge
variant="secondary"
size="xs"
content="New" />
{/if}
</Layout.Stack>
</Typography.Text>
</Layout.Stack>
</Card.Link>
{/each}
{#if starterTemplateRuntimes.length < 6}
<Tooltip>
<Card.Base variant="secondary" radius="s" padding="s">
<AvatarGroup
icons={[IconDotnet, IconDeno]}
total={4}
size="xs" />
</Card.Base>
<span slot="tooltip">More runtimes coming soon</span>
</Tooltip>
{/if}
</Layout.Grid>
<Divider />
@@ -161,6 +157,8 @@
<Layout.Grid columnsS={1} columns={2}>
{#each featuredTemplatesList as template}
<Card.Link
radius="s"
padding="xs"
href={`${wizardBase}/create-function/template-${template.id}`}
on:click={() => {
trackEvent('click_connect_template', {
@@ -168,7 +166,7 @@
template: template.name
});
}}>
<Layout.Stack gap="s">
<Layout.Stack gap="xxs">
<Layout.Stack
direction="row"
gap="s"
@@ -179,7 +177,9 @@
color="--fgcolor-neutral-primary">
{template.name}
</Typography.Text>
<Icon icon={IconArrowSmRight} />
<Icon
icon={IconArrowSmRight}
color="--fgcolor-neutral-tertiary" />
</Layout.Stack>
<Typography.Text variant="m-400">
{template.tagline}
@@ -189,7 +189,7 @@
{/each}
</Layout.Grid>
<Link variant="quiet" href="#/">
<Link variant="quiet" href={`${wizardBase}/templates`}>
<Layout.Stack direction="row" gap="xs">
Browse all templates <Icon icon={IconArrowSmRight} />
</Layout.Stack>
@@ -210,44 +210,38 @@
>.
</span>
</Layout.Stack>
</div>
<!-- TODO: fix overlay -->
{#if isSelfHosted && !isVcsEnabled}
<div
class="overlay u-flex-vertical u-position-absolute u-height-100-percent u-width-full-line u-z-index-1 u-text-center u-inset-0"
style="border-radius: var(--border-radius-medium)">
{#if isSelfHosted && !isVcsEnabled}
<div
class="u-flex-vertical u-height-100-percent u-main-center u-cross-center u-gap-16 u-padding-inline-24">
<Typography.Title size="s">
Connect your self-hosted instance to Git
</Typography.Title>
<p>
Configure your self-hosted instance to connect your function to a Git
repository.
<a
href="https://appwrite.io/docs/advanced/self-hosting/functions#git"
target="_blank"
rel="noopener noreferrer"
class="link">Learn more</a
>.
</p>
class="overlay u-flex-vertical u-position-absolute u-height-100-percent u-width-full-line u-z-index-1 u-text-center u-inset-0"
style="border-radius: var(--border-radius-medium); ">
<div
class="u-flex-vertical u-height-100-percent u-main-center u-cross-center u-gap-16 u-padding-inline-24">
<Typography.Title size="s" align="center">
Connect your self-hosted instance to Git
</Typography.Title>
<p style="max-width: 420px">
Configure your self-hosted instance to connect your function to a Git
repository.
<a
href="https://appwrite.io/docs/advanced/self-hosting/functions#git"
target="_blank"
rel="noopener noreferrer"
class="link">Learn more</a
>.
</p>
</div>
</div>
</div>
{/if}
{/if}
</div>
</Wizard>
<style lang="scss">
.git-container .overlay {
background: linear-gradient(
0,
hsl(var(--p-card-bg-color)) 68.91%,
hsl(var(--p-card-bg-color) / 0.5) 92.8%
var(--bgcolor-neutral-primary) 50%,
color-mix(in srgb, var(--bgcolor-neutral-primary) 90%, transparent) 70%,
color-mix(in srgb, var(--bgcolor-neutral-primary) 20%, transparent) 90%
);
}
.inline-tag {
line-height: 140%;
font-weight: 500;
}
</style>
@@ -289,18 +289,3 @@
</Layout.Stack>
</Layout.GridFraction>
</Container>
<style>
:global(.theme-light .functions-avatar-holder .avatar) {
background-color: var(--p-avatar-bg-color-default);
--p-avatar-bg-color-default: hsl(var(--color-neutral-0));
}
:global(.theme-light .functions-template-title) {
color: hsl(var(--color-neutral-70));
}
:global(.theme-dark .functions-template-title) {
color: hsl(var(--color-neutral-15));
}
</style>
@@ -100,13 +100,3 @@
</Card>
</Layout.GridFraction>
</Container>
<style>
:global(.theme-dark .collapsible-item-divider:where(:not(:last-child))) {
border-block-end: solid 0.0625rem hsl(var(--color-neutral-85));
}
:global(.theme-light .collapsible-item-divider:where(:not(:last-child))) {
border-block-end: solid 0.0625rem hsl(var(--color-neutral-10));
}
</style>