mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
feat: template flows (WIP)
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@
|
||||
"e2e:ui": "playwright test tests/e2e --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c",
|
||||
"@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@cfe6b8d",
|
||||
"@appwrite.io/pink-icons": "0.25.0",
|
||||
"@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5",
|
||||
"@appwrite.io/pink-legacy": "^1.0.3",
|
||||
|
||||
Generated
+5
-5
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@appwrite.io/console':
|
||||
specifier: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c
|
||||
version: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c
|
||||
specifier: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@cfe6b8d
|
||||
version: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@cfe6b8d
|
||||
'@appwrite.io/pink-icons':
|
||||
specifier: 0.25.0
|
||||
version: 0.25.0
|
||||
@@ -211,8 +211,8 @@ packages:
|
||||
'@analytics/type-utils@0.6.2':
|
||||
resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==}
|
||||
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c':
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c}
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@cfe6b8d':
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@cfe6b8d}
|
||||
version: 1.2.1
|
||||
|
||||
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5':
|
||||
@@ -4241,7 +4241,7 @@ snapshots:
|
||||
|
||||
'@analytics/type-utils@0.6.2': {}
|
||||
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@8db247c': {}
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@cfe6b8d': {}
|
||||
|
||||
'@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@4a5aab5(svelte@4.2.19)':
|
||||
dependencies:
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
import { IconLockClosed } from '@appwrite.io/pink-icons-svelte';
|
||||
import ConnectGit from './connectGit.svelte';
|
||||
import SvgIcon from '../svgIcon.svelte';
|
||||
import { getFrameworkIcon } from '$routes/(console)/project-[project]/sites/store';
|
||||
import { VCSDetectionType, type Models } from '@appwrite.io/console';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ export const sdk = {
|
||||
assistant: new Assistant(clientConsole),
|
||||
billing: new Billing(clientConsole),
|
||||
sources: new Sources(clientConsole),
|
||||
sites: new Sites(clientConsole),
|
||||
domains: new Domains(clientConsole)
|
||||
},
|
||||
get forProject() {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
export function getFrameworkIcon(framework: string) {
|
||||
switch (true) {
|
||||
case framework.toLocaleLowerCase().includes('sveltekit'):
|
||||
return 'svelte';
|
||||
case framework.toLocaleLowerCase().includes('nuxt'):
|
||||
return 'nuxt';
|
||||
case framework.toLocaleLowerCase().includes('vue'):
|
||||
return 'vue';
|
||||
case framework.toLocaleLowerCase().includes('react'):
|
||||
return 'react';
|
||||
case framework.toLocaleLowerCase().includes('angular'):
|
||||
return 'angular';
|
||||
case framework.toLocaleLowerCase().includes('svelte'):
|
||||
return 'svelte';
|
||||
case framework.toLocaleLowerCase().includes('next'):
|
||||
return 'nextjs';
|
||||
case framework.toLocaleLowerCase().includes('astro'):
|
||||
return 'astro';
|
||||
case framework.toLocaleLowerCase().includes('remix'):
|
||||
return 'remix';
|
||||
case framework.toLocaleLowerCase().includes('flutter'):
|
||||
return 'flutter';
|
||||
case framework.toLocaleLowerCase().includes('analog'):
|
||||
return 'analog';
|
||||
case framework.toLocaleLowerCase().includes('vite'):
|
||||
return 'vite';
|
||||
case framework.toLocaleLowerCase().includes('lynx'):
|
||||
return 'lynx';
|
||||
case framework.toLocaleLowerCase().includes('other'):
|
||||
return 'empty';
|
||||
|
||||
default:
|
||||
return 'empty';
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@ export const columns = writable<Column[]>([
|
||||
id: 'requestPath',
|
||||
title: 'Path',
|
||||
type: 'string',
|
||||
width: { min: 100, max: 200 },
|
||||
width: { min: 200 },
|
||||
format: 'string'
|
||||
},
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { IconGithub, IconGitBranch } from '@appwrite.io/pink-icons-svelte';
|
||||
import { consoleVariables } from '$routes/(console)/store';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { getFrameworkIcon } from '../store';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
|
||||
export let framework: Partial<Models.Framework>;
|
||||
export let repositoryName: string;
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
IconPencil
|
||||
} from '@appwrite.io/pink-icons-svelte';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { getFrameworkIcon } from '../store';
|
||||
import { iconPath } from '$lib/stores/app';
|
||||
import VariableEditorModal from './variableEditorModal.svelte';
|
||||
import SecretVariableModal from './secretVariableModal.svelte';
|
||||
@@ -33,6 +32,7 @@
|
||||
import DeleteVariableModal from './deleteVariableModal.svelte';
|
||||
import UpdateVariableModal from './updateVariableModal.svelte';
|
||||
import { Click, trackEvent } from '$lib/actions/analytics';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
|
||||
export let frameworks: Models.Framework[];
|
||||
export let selectedFramework: Models.Framework;
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
import Button from '$lib/elements/forms/button.svelte';
|
||||
import Aside from '../aside.svelte';
|
||||
import Logs from '../../(components)/logs.svelte';
|
||||
import { getFrameworkIcon } from '../../store';
|
||||
import { Copy, SvgIcon } from '$lib/components';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { onMount } from 'svelte';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
|
||||
export let data;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import { Card, Layout, Accordion, Selector, Tooltip } from '@appwrite.io/pink-svelte';
|
||||
import { capitalize } from '$lib/helpers/string';
|
||||
import { app } from '$lib/stores/app.js';
|
||||
import { getFrameworkIcon } from '../../store.js';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites.js';
|
||||
|
||||
export let data;
|
||||
|
||||
|
||||
+1
-1
@@ -32,11 +32,11 @@
|
||||
Repositories,
|
||||
RepositoryBehaviour
|
||||
} from '$lib/components/git';
|
||||
import { getFrameworkIcon } from '../../../store';
|
||||
import { app, iconPath } from '$lib/stores/app';
|
||||
import { consoleVariables } from '$routes/(console)/store';
|
||||
import { connectGitHub } from '$lib/stores/git';
|
||||
import Domain from '../../domain.svelte';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
|
||||
export let data;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { timeFromNow } from '$lib/helpers/date';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Card, Icon, Layout, Popover, Tooltip, Typography } from '@appwrite.io/pink-svelte';
|
||||
import { generateSiteDeploymentDesc, getFrameworkIcon } from './store';
|
||||
import { generateSiteDeploymentDesc } from './store';
|
||||
import { SvgIcon } from '$lib/components';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { getApiEndpoint } from '$lib/stores/sdk';
|
||||
@@ -13,6 +13,7 @@
|
||||
import { capitalize } from '$lib/helpers/string';
|
||||
import { IconExclamation } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Link } from '$lib/elements';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
|
||||
export let siteList: Models.SiteList;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ export const columns = writable<Column[]>([
|
||||
id: 'requestPath',
|
||||
title: 'Path',
|
||||
type: 'string',
|
||||
width: { min: 500, max: 900 },
|
||||
width: { min: 500 },
|
||||
format: 'string'
|
||||
},
|
||||
|
||||
|
||||
+1
-1
@@ -9,10 +9,10 @@
|
||||
import { Adapter, BuildRuntime, Framework, type Models } from '@appwrite.io/console';
|
||||
import { Card, Fieldset, Icon, InlineCode, Layout, Tooltip } from '@appwrite.io/pink-svelte';
|
||||
import { iconPath } from '$lib/stores/app';
|
||||
import { getFrameworkIcon } from '../../store';
|
||||
import { Link } from '$lib/elements';
|
||||
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
|
||||
import { adapterDataList } from './store';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
|
||||
export let site: Models.Site;
|
||||
export let frameworks: Models.Framework[];
|
||||
|
||||
@@ -16,42 +16,6 @@ export const columns = writable<Column[]>([
|
||||
{ id: '$createdAt', title: 'Created', type: 'datetime', width: { min: 120 } }
|
||||
]);
|
||||
|
||||
export function getFrameworkIcon(framework: string) {
|
||||
switch (true) {
|
||||
case framework.toLocaleLowerCase().includes('sveltekit'):
|
||||
return 'svelte';
|
||||
case framework.toLocaleLowerCase().includes('nuxt'):
|
||||
return 'nuxt';
|
||||
case framework.toLocaleLowerCase().includes('vue'):
|
||||
return 'vue';
|
||||
case framework.toLocaleLowerCase().includes('react'):
|
||||
return 'react';
|
||||
case framework.toLocaleLowerCase().includes('angular'):
|
||||
return 'angular';
|
||||
case framework.toLocaleLowerCase().includes('svelte'):
|
||||
return 'svelte';
|
||||
case framework.toLocaleLowerCase().includes('next'):
|
||||
return 'nextjs';
|
||||
case framework.toLocaleLowerCase().includes('astro'):
|
||||
return 'astro';
|
||||
case framework.toLocaleLowerCase().includes('remix'):
|
||||
return 'remix';
|
||||
case framework.toLocaleLowerCase().includes('flutter'):
|
||||
return 'flutter';
|
||||
case framework.toLocaleLowerCase().includes('analog'):
|
||||
return 'analog';
|
||||
case framework.toLocaleLowerCase().includes('vite'):
|
||||
return 'vite';
|
||||
case framework.toLocaleLowerCase().includes('lynx'):
|
||||
return 'lynx';
|
||||
case framework.toLocaleLowerCase().includes('other'):
|
||||
return 'empty';
|
||||
|
||||
default:
|
||||
return 'empty';
|
||||
}
|
||||
}
|
||||
|
||||
export function generateSiteDeploymentDesc(site: Models.Site) {
|
||||
if (site.latestDeploymentStatus === 'building') {
|
||||
return `Deployment building ${timer(site.latestDeploymentCreatedAt)}`;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { page } from '$app/stores';
|
||||
import { timeFromNow, toLocaleDateTime } from '$lib/helpers/date';
|
||||
import { Avatar, Icon, Layout, Popover, Table, Typography } from '@appwrite.io/pink-svelte';
|
||||
import { columns, getFrameworkIcon } from './store';
|
||||
import { columns } from './store';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import SitesActionMenu from './sitesActionMenu.svelte';
|
||||
import AddCollaboratorModal from './(components)/addCollaboratorModal.svelte';
|
||||
@@ -13,6 +13,7 @@
|
||||
import { Link } from '$lib/elements';
|
||||
import { timer } from '$lib/helpers/timeConversion';
|
||||
import DualTimeView from '$lib/components/dualTimeView.svelte';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites';
|
||||
|
||||
export let siteList: Models.SiteList;
|
||||
|
||||
|
||||
@@ -1,16 +1,135 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { SvgIcon } from '$lib/components/index.js';
|
||||
import { Button, InputSelect } from '$lib/elements/forms';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { loading } from '$routes/store';
|
||||
import { Typography } from '@appwrite.io/pink-svelte';
|
||||
import type { Organization } from '$lib/stores/organization';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { getFrameworkIcon } from '$lib/stores/sites.js';
|
||||
import { OAuthProvider, Query, type Models } from '@appwrite.io/console';
|
||||
import { IconGithub } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Card, Divider, Icon, Image, Layout, Typography } from '@appwrite.io/pink-svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
loading.set(false);
|
||||
export let data;
|
||||
|
||||
let projects: Models.ProjectList;
|
||||
let selectedOrg: Organization = data?.organizations?.total
|
||||
? data.organizations.teams[0]
|
||||
: undefined;
|
||||
onMount(async () => {
|
||||
if (data.organizations) {
|
||||
projects = await sdk.forConsole.projects.list([
|
||||
Query.equal('teamId', selectedOrg.$id),
|
||||
Query.orderDesc('')
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
export function isSiteTemplate(
|
||||
template: Models.TemplateFunction | Models.TemplateSite,
|
||||
product: 'site' | 'function'
|
||||
): template is Models.TemplateSite {
|
||||
return product === 'site';
|
||||
}
|
||||
|
||||
function onGithubLogin() {
|
||||
sdk.forConsole.account.createOAuth2Session(
|
||||
OAuthProvider.Github,
|
||||
window.location.origin,
|
||||
window.location.origin,
|
||||
['read:user', 'user:email']
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Deploy {data.template.name} - Appwrite</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="auth-bg">
|
||||
<section>
|
||||
<div class="console-container">
|
||||
<slot />
|
||||
</div>
|
||||
<section class="console-container">
|
||||
<Card.Base padding="s" radius="l">
|
||||
<Layout.Stack gap="xl">
|
||||
<Layout.Stack gap="l">
|
||||
<Typography.Title size="l">
|
||||
Deploy {data.product}
|
||||
</Typography.Title>
|
||||
<Card.Base variant="secondary" padding="xxxs" radius="s">
|
||||
<Layout.GridFraction start={4} end={5}>
|
||||
{#if isSiteTemplate(data.template, data.product)}
|
||||
{@const framework = data.template.frameworks[0]}
|
||||
<Image
|
||||
border
|
||||
radius="s"
|
||||
ratio="16/9"
|
||||
style=" align-self: start"
|
||||
src={$app.themeInUse === 'dark'
|
||||
? data.template.screenshotDark ||
|
||||
`${base}/images/sites/screenshot-placeholder-dark.svg`
|
||||
: data.template.screenshotLight ||
|
||||
`${base}/images/sites/screenshot-placeholder-light.svg`}
|
||||
alt="Screenshot" />
|
||||
<Layout.Stack gap="xl">
|
||||
<Layout.Stack gap="xxs">
|
||||
<Typography.Text
|
||||
variant="m-500"
|
||||
color="--fgcolor-neutral-primary">
|
||||
{data.template.name}
|
||||
</Typography.Text>
|
||||
<Typography.Text variant="m-500">
|
||||
{data.template.tagline}
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
{@const frameworkIcon = getFrameworkIcon(framework.key)}
|
||||
<Layout.Stack gap="xxs" alignItems="center" direction="row">
|
||||
{#if frameworkIcon}
|
||||
<SvgIcon
|
||||
iconSize="small"
|
||||
size={16}
|
||||
name={frameworkIcon} />
|
||||
{/if}
|
||||
<Typography.Text
|
||||
variant="m-500"
|
||||
color="--fgcolor-neutral-primary">
|
||||
{framework.name}
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
{/if}
|
||||
</Layout.GridFraction>
|
||||
</Card.Base>
|
||||
|
||||
{#if data.account}
|
||||
<InputSelect
|
||||
id="organization"
|
||||
label="Organization"
|
||||
placeholder="Select an organization"
|
||||
options={data.organizations.teams.map((o) => ({
|
||||
label: o.name,
|
||||
value: o.$id
|
||||
}))}
|
||||
bind:value={selectedOrg.$id} />
|
||||
|
||||
<Divider />
|
||||
<Button secondary fullWidth on:click={onGithubLogin}>
|
||||
<Icon slot="start" icon={IconGithub} />
|
||||
<span class="text">Sign in with GitHub</span>
|
||||
</Button>
|
||||
{:else}
|
||||
<Typography.Text variant="m-500">
|
||||
Sign in to deploy a site from GitHub.
|
||||
</Typography.Text>
|
||||
|
||||
<Divider />
|
||||
<Button secondary fullWidth on:click={onGithubLogin}>
|
||||
<Icon slot="start" icon={IconGithub} />
|
||||
<span class="text">Sign in with GitHub</span>
|
||||
</Button>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card.Base>
|
||||
</section>
|
||||
<footer>
|
||||
<Typography.Eyebrow color="--fgcolor-neutral-secondary">POWERED BY</Typography.Eyebrow>
|
||||
@@ -48,6 +167,8 @@
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 592px;
|
||||
}
|
||||
footer {
|
||||
padding: 2rem 1rem;
|
||||
|
||||
@@ -1,14 +1,40 @@
|
||||
import { base } from '$app/paths';
|
||||
import { sdk } from '$lib/stores/sdk.js';
|
||||
import { isCloud } from '$lib/system.js';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import { error } from '@sveltejs/kit';
|
||||
|
||||
export const load = async ({ parent, url, params }) => {
|
||||
//TODO: enable before release
|
||||
// if (!isCloud) redirect(303, '/');
|
||||
|
||||
export const load = async ({ parent, url }) => {
|
||||
const { account } = await parent();
|
||||
|
||||
// const params = new URLSearchParams(window.location.search);
|
||||
|
||||
if (account) {
|
||||
redirect(303, `${base}/templates-[template]?type=${url.searchParams.get('type')}`);
|
||||
} else {
|
||||
return {};
|
||||
if (!url.searchParams.has('type')) {
|
||||
error(404, 'Type is not optional');
|
||||
}
|
||||
|
||||
const product = url.searchParams.get('type');
|
||||
let template: Models.TemplateFunction | Models.TemplateSite;
|
||||
|
||||
switch (product) {
|
||||
case 'function':
|
||||
template = await sdk.forConsole.functions.getTemplate(params.template);
|
||||
break;
|
||||
case 'site':
|
||||
template = await sdk.forConsole.sites.getTemplate(params.template);
|
||||
break;
|
||||
default:
|
||||
error(404, 'Type is not valid');
|
||||
}
|
||||
|
||||
if (account)
|
||||
return {
|
||||
account,
|
||||
template: template,
|
||||
product,
|
||||
organizations: account?.$id
|
||||
? await sdk.forConsole.billing.listOrganization()
|
||||
: undefined
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user