mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
fix: push some changes
This commit is contained in:
Generated
+4
-4
@@ -8,7 +8,7 @@
|
||||
"dependencies": {
|
||||
"@analytics/google-analytics": "^1.0.5",
|
||||
"@appwrite.io/console": "npm:matej-appwrite-console@7.1.102",
|
||||
"@appwrite.io/pink": "0.0.6-rc.10",
|
||||
"@appwrite.io/pink": "0.0.6-rc.15",
|
||||
"@popperjs/core": "^2.11.6",
|
||||
"@sentry/svelte": "^7.44.2",
|
||||
"@sentry/tracing": "^7.44.2",
|
||||
@@ -167,9 +167,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@appwrite.io/pink": {
|
||||
"version": "0.0.6-rc.10",
|
||||
"resolved": "https://registry.npmjs.org/@appwrite.io/pink/-/pink-0.0.6-rc.10.tgz",
|
||||
"integrity": "sha512-mhpgjQVfQvghItgcCzsHN0Ynn4U9JNg8HlSJ+HVDUi/bNHxmlm7XdNJE6s65LMJ6LfepROn6zZMHquANvGfNDg==",
|
||||
"version": "0.0.6-rc.15",
|
||||
"resolved": "https://registry.npmjs.org/@appwrite.io/pink/-/pink-0.0.6-rc.15.tgz",
|
||||
"integrity": "sha512-CLgN+2NLuypmcYEjAlB8sOQyvjloCTKvNHa/flIBOkZKIEH2YX5qWSM/O08GLUuMPWS4Y/+z1U4uIvGOATTiTg==",
|
||||
"dependencies": {
|
||||
"@appwrite.io/pink-icons": "*",
|
||||
"normalize.css": "^8.0.1",
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
"dependencies": {
|
||||
"@analytics/google-analytics": "^1.0.5",
|
||||
"@appwrite.io/console": "npm:matej-appwrite-console@7.1.102",
|
||||
"@appwrite.io/pink": "0.0.6-rc.10",
|
||||
"@appwrite.io/pink": "0.0.6-rc.15",
|
||||
"@popperjs/core": "^2.11.6",
|
||||
"@sentry/svelte": "^7.44.2",
|
||||
"@sentry/tracing": "^7.44.2",
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
let selectedResponse = 'logs';
|
||||
let rawData: string;
|
||||
|
||||
$: console.log($log.data);
|
||||
|
||||
function isExecution(
|
||||
data: Models.Deployment | Models.Execution<any>
|
||||
): data is Models.Execution<any> {
|
||||
|
||||
@@ -26,13 +26,17 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Cancel navigation when wizard is open and triggered by popstate
|
||||
*/
|
||||
beforeNavigate((n) => {
|
||||
/**
|
||||
* Hide wizard when navigation is triggered by popstate.
|
||||
*/
|
||||
if (n.type === 'popstate' && $wizard.show) {
|
||||
wizard.hide();
|
||||
n.cancel();
|
||||
if ($wizard.show || $wizard.cover) {
|
||||
if (n.type === 'popstate') {
|
||||
n.cancel();
|
||||
}
|
||||
if (n.type !== 'leave') {
|
||||
wizard.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -42,7 +46,7 @@
|
||||
<main
|
||||
class:grid-with-side={showSideNavigation}
|
||||
class:is-open={isOpen}
|
||||
class:u-hide={$wizard.show || $log.show}>
|
||||
class:u-hide={$wizard.show || $log.show || $wizard.cover}>
|
||||
<header class="main-header u-padding-inline-end-0">
|
||||
<button
|
||||
class:u-hide={!showSideNavigation}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
|
||||
function handleKeydown(event: KeyboardEvent) {
|
||||
if (event.key === 'Escape') {
|
||||
event.preventDefault();
|
||||
wizard.hide();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={handleKeydown} />
|
||||
|
||||
<section class="cover-frame is-color-header">
|
||||
<header class="cover-frame-header">
|
||||
<div
|
||||
class="container u-flex u-gap-16 u-main-space-between u-cross-center"
|
||||
style:--p-container-padding-block="0">
|
||||
<div class="u-flex u-gap-8 u-cross-center">
|
||||
<div class="body-text-1 u-bold"><slot name="title" /></div>
|
||||
</div>
|
||||
<button
|
||||
on:click={wizard.hide}
|
||||
class="button is-text is-only-icon"
|
||||
style:--button-size="1.5rem"
|
||||
aria-label="close popup">
|
||||
<span class="icon-x" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="cover-frame-content u-flex u-flex-vertical u-overflow-y-auto">
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { beforeNavigate, invalidate } from '$app/navigation';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
import { dependencyStore, domain } from './wizard/store';
|
||||
@@ -18,10 +18,6 @@
|
||||
});
|
||||
});
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
async function onFinish() {
|
||||
await invalidate($dependencyStore);
|
||||
wizard.hide();
|
||||
|
||||
@@ -6,6 +6,7 @@ export type WizardStore = {
|
||||
show: boolean;
|
||||
media?: string;
|
||||
component?: typeof SvelteComponent;
|
||||
cover?: typeof SvelteComponent;
|
||||
interceptor?: () => Promise<void>;
|
||||
};
|
||||
|
||||
@@ -13,6 +14,7 @@ function createWizardStore() {
|
||||
const { subscribe, update, set } = writable<WizardStore>({
|
||||
show: false,
|
||||
component: null,
|
||||
cover: null,
|
||||
interceptor: null,
|
||||
media: null
|
||||
});
|
||||
@@ -25,6 +27,7 @@ function createWizardStore() {
|
||||
n.show = true;
|
||||
n.component = component;
|
||||
n.media = media;
|
||||
n.cover = null;
|
||||
trackEvent('wizard_start');
|
||||
return n;
|
||||
}),
|
||||
@@ -40,7 +43,12 @@ function createWizardStore() {
|
||||
n.show = false;
|
||||
n.component = null;
|
||||
n.media = null;
|
||||
|
||||
n.cover = null;
|
||||
return n;
|
||||
}),
|
||||
showCover: (component: typeof SvelteComponent) =>
|
||||
update((n) => {
|
||||
n.cover = component;
|
||||
return n;
|
||||
})
|
||||
};
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { EmptySearch } from '$lib/components';
|
||||
import { Button, InputSearch, InputSelect } from '$lib/elements/forms';
|
||||
import { timeFromNow } from '$lib/helpers/date';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { installation, installations, repository } from '../store';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let selectedRepository: string = null;
|
||||
export let hasInstallations = false;
|
||||
export let action: 'button' | 'select' = 'select';
|
||||
|
||||
$: {
|
||||
hasInstallations = $installations?.total > 0;
|
||||
}
|
||||
|
||||
let selectedInstallation = null;
|
||||
async function loadInstallations() {
|
||||
const { installations } = await sdk.forProject.vcs.listInstallations();
|
||||
if (installations.length) {
|
||||
selectedInstallation = installations[0].$id;
|
||||
installation.set(installations.find((entry) => entry.$id === selectedInstallation));
|
||||
}
|
||||
return installations;
|
||||
}
|
||||
|
||||
let search = '';
|
||||
async function loadRepositories(installationId: string, search: string) {
|
||||
return sdk.forProject.vcs.listRepositories(installationId, search || undefined);
|
||||
}
|
||||
|
||||
const detectionMemory = new Map<string, Models.Detection>();
|
||||
async function loadDetection(installationId: string, repositoryId: string) {
|
||||
const key = `${installationId}.${repositoryId}`;
|
||||
if (detectionMemory.has(key)) {
|
||||
return detectionMemory.get(key);
|
||||
}
|
||||
const detection = await sdk.forProject.vcs.createRepositoryDetection(
|
||||
installationId,
|
||||
repositoryId
|
||||
);
|
||||
detectionMemory.set(key, detection);
|
||||
|
||||
return detection;
|
||||
}
|
||||
|
||||
function connectGitHub() {
|
||||
const redirect = new URL($page.url);
|
||||
redirect.searchParams.append('github-installed', 'true');
|
||||
const target = new URL(
|
||||
`${sdk.forProject.client.config.endpoint}/v1/vcs/github/installations`
|
||||
);
|
||||
target.searchParams.set('projectId', $page.params.project);
|
||||
target.searchParams.set('redirect', redirect.toString());
|
||||
return target;
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if hasInstallations}
|
||||
{#await loadInstallations()}
|
||||
<div class="u-flex u-gap-8 u-cross-center u-main-center">
|
||||
<div class="loader u-margin-32" />
|
||||
</div>
|
||||
{:then installations}
|
||||
<div class="u-flex u-gap-16">
|
||||
<div class="u-width-full-line">
|
||||
<InputSelect
|
||||
id="installation"
|
||||
label="Select installation"
|
||||
showLabel={false}
|
||||
options={installations.map((entry) => {
|
||||
return {
|
||||
label: entry.organization,
|
||||
value: entry.$id
|
||||
};
|
||||
})}
|
||||
on:change={() => {
|
||||
search = '';
|
||||
installation.set(
|
||||
installations.find((entry) => entry.$id === selectedInstallation)
|
||||
);
|
||||
}}
|
||||
bind:value={selectedInstallation} />
|
||||
</div>
|
||||
<div class="u-width-full-line">
|
||||
<InputSearch placeholder="Search repositories" bind:value={search} />
|
||||
</div>
|
||||
</div>
|
||||
{/await}
|
||||
|
||||
{#if selectedInstallation}
|
||||
<p class="text common-section">
|
||||
Manage organization configuration in your <a
|
||||
class="link"
|
||||
href={`${base}/console/project-${$page.params.project}/settings`}
|
||||
>project settings</a
|
||||
>.
|
||||
</p>
|
||||
{#await loadRepositories(selectedInstallation, search)}
|
||||
<div class="card-git card is-border-dashed is-no-shadow common-section">
|
||||
<div class="u-flex u-gap-8 u-cross-center u-main-center">
|
||||
<div class="loader u-margin-16" />
|
||||
Loading repositories...
|
||||
</div>
|
||||
</div>
|
||||
{:then response}
|
||||
{#if response?.total}
|
||||
<ul class="table is-remove-outer-styles common-section">
|
||||
{#each response.repositories as repo}
|
||||
<li class="table-row">
|
||||
<div class="table-col">
|
||||
<div
|
||||
class="u-flex u-cross-center u-gap-8"
|
||||
style="margin-block: .75rem;">
|
||||
{#if action === 'select'}
|
||||
<input
|
||||
class="is-small u-margin-inline-end-8"
|
||||
type="radio"
|
||||
name={repo.name}
|
||||
bind:group={selectedRepository}
|
||||
on:change={() => repository.set(repo)}
|
||||
value={repo.id} />
|
||||
{/if}
|
||||
{#await loadDetection(selectedInstallation, repo.id)}
|
||||
<div class="avatar is-size-x-small">
|
||||
<div class="loader u-margin-16" />
|
||||
</div>
|
||||
{:then detection}
|
||||
<div
|
||||
class="avatar is-size-x-small"
|
||||
style:--p-text-size="1.25rem"
|
||||
class:is-color-empty={!detection.runtime}>
|
||||
{#if detection.runtime}
|
||||
<img
|
||||
src={`${base}/icons/${$app.themeInUse}/color/${detection.runtime}.svg`}
|
||||
alt={repo.name} />
|
||||
{/if}
|
||||
</div>
|
||||
{/await}
|
||||
<div class="u-flex u-gap-8">
|
||||
<span class="text">{repo.name}</span>
|
||||
{#if repo.private}
|
||||
<span class="icon-lock" aria-hidden="true" />
|
||||
{/if}
|
||||
<time class="u-color-text-gray" datetime={repo.pushedAt}>
|
||||
{timeFromNow(repo.pushedAt)}
|
||||
</time>
|
||||
</div>
|
||||
{#if action === 'button'}
|
||||
<div class="u-margin-inline-start-auto">
|
||||
<Button
|
||||
secondary
|
||||
on:click={() => dispatch('connect', repo)}>
|
||||
Connect
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{:else if search}
|
||||
<EmptySearch hidePages>
|
||||
<div class="common-section">
|
||||
<div class="u-text-center common-section">
|
||||
<b class="body-text-2 u-bold">Sorry we couldn't find "{search}"</b>
|
||||
<p>There are no repositories that match your search.</p>
|
||||
</div>
|
||||
<div class="u-flex u-gap-16 common-section u-main-center">
|
||||
<Button external href="https://appwrite.io/docs/client/teams" text
|
||||
>Documentation</Button>
|
||||
<Button secondary on:click={() => (search = '')}>Clear search</Button>
|
||||
</div>
|
||||
</div>
|
||||
</EmptySearch>
|
||||
{:else}
|
||||
<EmptySearch hidePages>
|
||||
<div class="common-section">
|
||||
<div class="u-text-center common-section">
|
||||
<p class="text u-line-height-1-5">You have no repositories.</p>
|
||||
<p class="text u-line-height-1-5">
|
||||
Need a hand? Learn more in our <a
|
||||
href="https://appwrite.io/docs/client/teams"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
documentation</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</EmptySearch>
|
||||
{/if}
|
||||
{/await}
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="u-flex u-cross-center u-flex-vertical u-gap-16">
|
||||
<Button href={connectGitHub().toString()} fullWidth secondary>
|
||||
<span class="icon-github" aria-hidden="true" />
|
||||
<span class="text">Continue with GitHub</span>
|
||||
</Button>
|
||||
<Button disabled fullWidth secondary>
|
||||
<span class="icon-gitlab" aria-hidden="true" />
|
||||
<span class="text">GitLab (coming soon)</span>
|
||||
</Button>
|
||||
<Button disabled fullWidth secondary>
|
||||
<span class="icon-bitBucket" aria-hidden="true" />
|
||||
<span class="text">BitBucket (coming soon)</span>
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -7,7 +7,7 @@
|
||||
import { func } from '$routes/console/project-[project]/functions/function-[function]/store';
|
||||
import { choices, installation, repository } from './store';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { beforeNavigate, invalidate } from '$app/navigation';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
|
||||
async function createGitHubInstallation() {
|
||||
@@ -33,10 +33,6 @@
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
function resetState() {
|
||||
choices.set({
|
||||
branch: null,
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { Heading } from '$lib/components';
|
||||
import { clickOnEnter } from '$lib/helpers/a11y';
|
||||
import WizardCover from '$lib/layout/wizardCover.svelte';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import Repositories from './components/repositories.svelte';
|
||||
import CreateManual from './createManual.svelte';
|
||||
import { repository } from './store';
|
||||
import CreateGit from './createGit.svelte';
|
||||
|
||||
let hasInstallations;
|
||||
let selectedRepository;
|
||||
|
||||
const quickStarts: {
|
||||
name: string;
|
||||
icon: string;
|
||||
}[] = [
|
||||
{
|
||||
icon: 'dart',
|
||||
name: 'Dart'
|
||||
},
|
||||
{
|
||||
icon: 'node',
|
||||
name: 'Node.js'
|
||||
},
|
||||
{
|
||||
icon: 'php',
|
||||
name: 'PHP'
|
||||
},
|
||||
{
|
||||
icon: 'python',
|
||||
name: 'Python'
|
||||
},
|
||||
{
|
||||
icon: 'swift',
|
||||
name: 'Swift'
|
||||
},
|
||||
{
|
||||
icon: 'ruby',
|
||||
name: 'Ruby'
|
||||
}
|
||||
];
|
||||
|
||||
const templates: {
|
||||
name: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
}[] = [
|
||||
{
|
||||
name: 'URL shortener',
|
||||
description: 'Shorten URLs using Bitly',
|
||||
icon: 'python'
|
||||
},
|
||||
{
|
||||
name: 'URL shortener',
|
||||
description: 'Shorten URLs using Bitly',
|
||||
icon: 'dart'
|
||||
},
|
||||
{
|
||||
name: 'URL shortener',
|
||||
description: 'Shorten URLs using Bitly',
|
||||
icon: 'node'
|
||||
}
|
||||
];
|
||||
|
||||
function connect(event: CustomEvent<Models.Repository>) {
|
||||
repository.set(event.detail);
|
||||
wizard.start(CreateGit);
|
||||
}
|
||||
</script>
|
||||
|
||||
<WizardCover>
|
||||
<svelte:fragment slot="title">Create function</svelte:fragment>
|
||||
<div class="wizard-container container">
|
||||
<div class="u-text-center">
|
||||
<Heading size="5" tag="h1">Choose your source</Heading>
|
||||
<p class="u-margin-block-start-8">
|
||||
Connect your function to a Git repository or use a template to get started. You can
|
||||
also create a function <span
|
||||
class="link"
|
||||
on:keyup={clickOnEnter}
|
||||
on:click={() => wizard.start(CreateManual)}>manually</span
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid-1-1 u-gap-24 u-margin-block-start-48">
|
||||
<div class="card u-cross-child-start">
|
||||
<Heading size="6" tag="h2">Import Git repository</Heading>
|
||||
<p class="u-margin-block-start-8">
|
||||
Create and deploy a function with a connected git repository.
|
||||
</p>
|
||||
<div class="u-margin-block-start-24" />
|
||||
<Repositories
|
||||
bind:hasInstallations
|
||||
bind:selectedRepository
|
||||
action="button"
|
||||
on:connect={connect} />
|
||||
</div>
|
||||
<div class="card">
|
||||
<section class="common-section">
|
||||
<h2 class="heading-level-6">Quick start</h2>
|
||||
<p class="u-margin-block-start-8">
|
||||
Use a starter templates to begin with the basics.
|
||||
</p>
|
||||
<ul
|
||||
class="grid-box u-margin-block-start-16"
|
||||
style:--grid-gap="1rem"
|
||||
style:--p-grid-item-size="8rem">
|
||||
{#each quickStarts as quickStart}
|
||||
<li>
|
||||
<button
|
||||
class="box u-width-full-line u-flex-vertical u-cross-center u-gap-8"
|
||||
style:--box-padding="1rem"
|
||||
style:--box-border-radius="var(--border-radius-small)">
|
||||
<div class="avatar">
|
||||
<img
|
||||
style:--p-text-size="1.25rem"
|
||||
src={`${base}/icons/${$app.themeInUse}/color/${quickStart.icon}.svg`}
|
||||
alt={quickStart.name} />
|
||||
</div>
|
||||
<div class="body-text-2">{quickStart.name}</div>
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</section>
|
||||
<section class="common-section">
|
||||
<h2 class="heading-level-6">Templates</h2>
|
||||
<p class="u-margin-block-start-8">
|
||||
Choose from a selection of templates to find the right one for your use
|
||||
case.
|
||||
</p>
|
||||
|
||||
<ul class="u-flex-vertical u-gap-8 u-margin-block-start-16">
|
||||
{#each templates as template}
|
||||
<li>
|
||||
<button
|
||||
class="box u-width-full-line u-flex u-gap-8"
|
||||
style:--box-padding="1rem"
|
||||
style:--box-border-radius="var(--border-radius-small)">
|
||||
<div class="avatar is-size-small" style:--p-text-size="1.25rem">
|
||||
<img
|
||||
src={`${base}/icons/${$app.themeInUse}/color/${template.icon}.svg`}
|
||||
alt={template.name} />
|
||||
</div>
|
||||
<div>
|
||||
<div class="body-text-2 u-trim">{template.name}</div>
|
||||
<div class="u-trim u-color-text-gray">
|
||||
{template.description}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WizardCover>
|
||||
@@ -4,14 +4,13 @@
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { beforeNavigate, goto } from '$app/navigation';
|
||||
import { goto } from '$app/navigation';
|
||||
import { choices, createFunction, installation, repository } from './store';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { Submit, trackEvent } from '$lib/actions/analytics';
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import ExecuteAccess from './steps/executeAccess.svelte';
|
||||
import SelectRepository from './steps/selectRepository.svelte';
|
||||
import GitConfiguration from './steps/gitConfiguration.svelte';
|
||||
import FunctionConfiguration from './steps/functionConfiguration.svelte';
|
||||
|
||||
@@ -46,10 +45,6 @@
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
function resetState() {
|
||||
createFunction.set({
|
||||
$id: null,
|
||||
@@ -62,18 +57,14 @@
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Select Repository',
|
||||
component: SelectRepository
|
||||
});
|
||||
stepsComponents.set(2, {
|
||||
label: 'Git configuration',
|
||||
component: GitConfiguration
|
||||
});
|
||||
stepsComponents.set(3, {
|
||||
stepsComponents.set(2, {
|
||||
label: 'Function configuration',
|
||||
component: FunctionConfiguration
|
||||
});
|
||||
stepsComponents.set(4, {
|
||||
stepsComponents.set(3, {
|
||||
label: 'Execute access',
|
||||
component: ExecuteAccess,
|
||||
optional: true
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { beforeNavigate, goto } from '$app/navigation';
|
||||
import { goto } from '$app/navigation';
|
||||
import {
|
||||
choices,
|
||||
createFunction,
|
||||
@@ -36,7 +36,7 @@
|
||||
);
|
||||
await sdk.forProject.functions.createDeployment(
|
||||
response.$id,
|
||||
$createFunctionDeployment.item[0],
|
||||
$createFunctionDeployment[0],
|
||||
true
|
||||
);
|
||||
goto(`${base}/console/project-${$page.params.project}/functions/function-${response.$id}`);
|
||||
@@ -51,10 +51,6 @@
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
function resetState() {
|
||||
createFunction.set({
|
||||
$id: null,
|
||||
@@ -70,6 +66,7 @@
|
||||
});
|
||||
installation.set(null);
|
||||
repository.set(null);
|
||||
createFunctionDeployment.set(null);
|
||||
}
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { beforeNavigate, goto } from '$app/navigation';
|
||||
import { goto } from '$app/navigation';
|
||||
import { choices, createFunction, installation, repository } from './store';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { Submit, trackEvent } from '$lib/actions/analytics';
|
||||
@@ -46,10 +46,6 @@
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
function resetState() {
|
||||
createFunction.set({
|
||||
$id: null,
|
||||
|
||||
@@ -1,48 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { EmptySearch } from '$lib/components';
|
||||
import { Button, InputSearch, InputSelect } from '$lib/elements/forms';
|
||||
import { toLocaleDateTime } from '$lib/helpers/date';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { installation, installations, repository } from '../store';
|
||||
import Repositories from '../components/repositories.svelte';
|
||||
|
||||
let selectedInstallation = null;
|
||||
async function loadInstallations() {
|
||||
const { installations } = await sdk.forProject.vcs.listInstallations();
|
||||
if (installations.length) {
|
||||
selectedInstallation = installations[0].$id;
|
||||
installation.set(installations.find((entry) => entry.$id === selectedInstallation));
|
||||
}
|
||||
return installations;
|
||||
}
|
||||
|
||||
let search = '';
|
||||
let selectedRepository = null;
|
||||
async function loadRepositories(installationId: string, search: string) {
|
||||
return sdk.forProject.vcs.listRepositories(installationId, search || undefined);
|
||||
}
|
||||
|
||||
const detectionMemory = new Map<string, Models.Detection>();
|
||||
async function loadDetection(installationId: string, repositoryId: string) {
|
||||
const key = `${installationId}.${repositoryId}`;
|
||||
if (detectionMemory.has(key)) {
|
||||
return detectionMemory.get(key);
|
||||
}
|
||||
const detection = await sdk.forProject.vcs.createRepositoryDetection(
|
||||
installationId,
|
||||
repositoryId
|
||||
);
|
||||
detectionMemory.set(key, detection);
|
||||
|
||||
return detection;
|
||||
}
|
||||
|
||||
$: hasInstallations = $installations?.total > 0;
|
||||
$: console.log(hasInstallations);
|
||||
let hasInstallations;
|
||||
let selectedRepository;
|
||||
async function beforeSubmit() {
|
||||
if (!hasInstallations) {
|
||||
throw new Error('Please connect a Git provider');
|
||||
@@ -51,12 +12,6 @@
|
||||
throw new Error('Please select a repository');
|
||||
}
|
||||
}
|
||||
|
||||
function connectGitHub() {
|
||||
const target = new URL($page.url);
|
||||
target.searchParams.append('github-installed', 'true');
|
||||
sdk.forProject.vcs.createGitHubInstallation(target.toString());
|
||||
}
|
||||
</script>
|
||||
|
||||
<WizardStep {beforeSubmit}>
|
||||
@@ -64,144 +19,5 @@
|
||||
<svelte:fragment slot="subtitle">
|
||||
Select a Git repository that will trigger your function deployments when updated.
|
||||
</svelte:fragment>
|
||||
{#if hasInstallations}
|
||||
{#await loadInstallations()}
|
||||
<div class="u-flex u-gap-8 u-cross-center u-main-center">
|
||||
<div class="loader u-margin-32" />
|
||||
</div>
|
||||
{:then installations}
|
||||
<div class="u-flex u-gap-16">
|
||||
<div class="u-width-full-line">
|
||||
<InputSelect
|
||||
id="installation"
|
||||
label="Select installation"
|
||||
showLabel={false}
|
||||
options={installations.map((entry) => {
|
||||
return {
|
||||
label: entry.organization,
|
||||
value: entry.$id
|
||||
};
|
||||
})}
|
||||
on:change={() => {
|
||||
search = '';
|
||||
installation.set(
|
||||
installations.find((entry) => entry.$id === selectedInstallation)
|
||||
);
|
||||
}}
|
||||
bind:value={selectedInstallation} />
|
||||
</div>
|
||||
<div class="u-width-full-line">
|
||||
<InputSearch placeholder="Search repositories" bind:value={search} />
|
||||
</div>
|
||||
</div>
|
||||
{/await}
|
||||
|
||||
{#if selectedInstallation}
|
||||
<p class="text common-section">
|
||||
Manage organization configuration in your <a
|
||||
class="link"
|
||||
href={`${base}/console/project-${$page.params.project}/settings`}
|
||||
>project settings</a
|
||||
>.
|
||||
</p>
|
||||
{#await loadRepositories(selectedInstallation, search)}
|
||||
<div class="card-git card is-border-dashed is-no-shadow common-section">
|
||||
<div class="u-flex u-gap-8 u-cross-center u-main-center">
|
||||
<div class="loader u-margin-16" />
|
||||
Loading repositories...
|
||||
</div>
|
||||
</div>
|
||||
{:then response}
|
||||
{#if response?.total}
|
||||
<ul class="table is-remove-outer-styles u-sep-block-start common-section">
|
||||
{#each response.repositories as repo}
|
||||
<li class="table-row">
|
||||
<label class="table-col u-cursor-pointer">
|
||||
<div class="u-flex u-cross-center u-gap-8">
|
||||
<input
|
||||
class="is-small u-margin-inline-end-8"
|
||||
type="radio"
|
||||
name={repo.name}
|
||||
bind:group={selectedRepository}
|
||||
on:change={() => repository.set(repo)}
|
||||
value={repo.id} />
|
||||
{#await loadDetection(selectedInstallation, repo.id)}
|
||||
<div class="avatar is-size-x-small">
|
||||
<div class="loader u-margin-16" />
|
||||
</div>
|
||||
{:then detection}
|
||||
<div
|
||||
class="avatar is-size-x-small"
|
||||
class:is-color-empty={!detection.runtime}>
|
||||
{#if detection.runtime}
|
||||
<img
|
||||
src={`${base}/icons/${$app.themeInUse}/color/${detection.runtime}.svg`}
|
||||
alt={repo.name} />
|
||||
{/if}
|
||||
</div>
|
||||
{/await}
|
||||
<div class="u-flex u-gap-8">
|
||||
<span class="text">{repo.name}</span>
|
||||
|
||||
<time
|
||||
class="u-color-text-gray"
|
||||
datetime={repo.pushedAt}>
|
||||
{toLocaleDateTime(repo.pushedAt)}
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{:else if search}
|
||||
<EmptySearch hidePages>
|
||||
<div class="common-section">
|
||||
<div class="u-text-center common-section">
|
||||
<b class="body-text-2 u-bold">Sorry we couldn't find "{search}"</b>
|
||||
<p>There are no repositories that match your search.</p>
|
||||
</div>
|
||||
<div class="u-flex u-gap-16 common-section u-main-center">
|
||||
<Button external href="https://appwrite.io/docs/client/teams" text
|
||||
>Documentation</Button>
|
||||
<Button secondary on:click={() => (search = '')}
|
||||
>Clear search</Button>
|
||||
</div>
|
||||
</div>
|
||||
</EmptySearch>
|
||||
{:else}
|
||||
<EmptySearch hidePages>
|
||||
<div class="common-section">
|
||||
<div class="u-text-center common-section">
|
||||
<p class="text u-line-height-1-5">You have no repositories.</p>
|
||||
<p class="text u-line-height-1-5">
|
||||
Need a hand? Learn more in our <a
|
||||
href="https://appwrite.io/docs/client/teams"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
documentation</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</EmptySearch>
|
||||
{/if}
|
||||
{/await}
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="u-flex u-cross-center u-flex-vertical u-gap-16">
|
||||
<Button on:click={() => connectGitHub()} fullWidth secondary>
|
||||
<span class="icon-github" aria-hidden="true" />
|
||||
<span class="text">Continue with GitHub</span>
|
||||
</Button>
|
||||
<Button disabled fullWidth secondary>
|
||||
<span class="icon-gitlab" aria-hidden="true" />
|
||||
<span class="text">GitLab (coming soon)</span>
|
||||
</Button>
|
||||
<Button disabled fullWidth secondary>
|
||||
<span class="icon-bitBucket" aria-hidden="true" />
|
||||
<span class="text">BitBucket (coming soon)</span>
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
<Repositories bind:hasInstallations bind:selectedRepository />
|
||||
</WizardStep>
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
|
||||
{#if $wizard.show && $wizard.component}
|
||||
<svelte:component this={$wizard.component} />
|
||||
{:else if $wizard.cover}
|
||||
<svelte:component this={$wizard.cover} />
|
||||
{/if}
|
||||
|
||||
<Create bind:show={$newOrgModal} />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import type { LayoutLoad } from './$types';
|
||||
|
||||
export const load: LayoutLoad = async () => {
|
||||
export const load: LayoutLoad = async ({ fetch }) => {
|
||||
const response = await fetch(`${sdk.forConsole.client.config.endpoint}/health/version`);
|
||||
const data = await response.json();
|
||||
|
||||
|
||||
+1
-5
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { beforeNavigate, invalidate } from '$app/navigation';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
@@ -68,10 +68,6 @@
|
||||
$createDocument.permissions = [];
|
||||
});
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Create data',
|
||||
|
||||
@@ -7,56 +7,41 @@
|
||||
GridItem1,
|
||||
Heading,
|
||||
PaginationWithLimit,
|
||||
Id,
|
||||
DropList,
|
||||
DropListItem
|
||||
Id
|
||||
} from '$lib/components';
|
||||
import { Container } from '$lib/layout';
|
||||
import { base } from '$app/paths';
|
||||
import { tooltip } from '$lib/actions/tooltip';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { beforeNavigate } from '$app/navigation';
|
||||
import { toLocaleDateTime } from '$lib/helpers/date';
|
||||
import CreateManual from '$lib/wizards/functions/createManual.svelte';
|
||||
import CreateGit from '$lib/wizards/functions/createGit.svelte';
|
||||
import CreateStarter from '$lib/wizards/functions/createStarter.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import Initial from '$lib/wizards/functions/cover.svelte';
|
||||
|
||||
export let data;
|
||||
|
||||
let offset = 0;
|
||||
let showCreateDropdown = false;
|
||||
|
||||
const project = $page.params.project;
|
||||
|
||||
function openWizard() {
|
||||
wizard.start(CreateManual);
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
onMount(() => {
|
||||
if ($page.url.searchParams.has('github-installed')) {
|
||||
openWizard();
|
||||
}
|
||||
});
|
||||
|
||||
function openWizard() {
|
||||
wizard.showCover(Initial);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<div class="u-flex u-gap-12 common-section u-main-space-between">
|
||||
<Heading tag="h2" size="5">Functions</Heading>
|
||||
<DropList bind:show={showCreateDropdown} scrollable>
|
||||
<slot>
|
||||
<Button
|
||||
on:click={() => (showCreateDropdown = !showCreateDropdown)}
|
||||
event="create_attribute">
|
||||
<span class="icon-plus" aria-hidden="true" />
|
||||
<span class="text">Create function</span>
|
||||
</Button>
|
||||
</slot>
|
||||
<svelte:fragment slot="list">
|
||||
<DropListItem on:click={() => wizard.start(CreateManual)}>Manual</DropListItem>
|
||||
<DropListItem on:click={() => wizard.start(CreateGit)}>Git</DropListItem>
|
||||
<DropListItem on:click={() => wizard.start(CreateStarter)}
|
||||
>Starter template</DropListItem>
|
||||
</svelte:fragment>
|
||||
</DropList>
|
||||
<Button on:click={openWizard} event="create_attribute">
|
||||
<span class="icon-plus" aria-hidden="true" />
|
||||
<span class="text">Create function</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{#if data.functions.total}
|
||||
@@ -81,14 +66,14 @@
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="icons">
|
||||
{#if func.scheduleNext}
|
||||
{#if func.schedule}
|
||||
<li>
|
||||
<span
|
||||
class="icon-clock"
|
||||
aria-hidden="true"
|
||||
use:tooltip={{
|
||||
content: `Next execution:
|
||||
${toLocaleDateTime(func.scheduleNext)}`
|
||||
${toLocaleDateTime(func.schedule)}`
|
||||
}} />
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { beforeNavigate, goto, invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { goto, invalidate } from '$app/navigation';
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
import Step1 from './wizard/step1.svelte';
|
||||
import Step2 from './wizard/step2.svelte';
|
||||
@@ -42,10 +41,6 @@
|
||||
key.reset();
|
||||
});
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Details',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { beforeNavigate, invalidate } from '$app/navigation';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
@@ -20,10 +20,6 @@
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Register your app',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { beforeNavigate, invalidate } from '$app/navigation';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
@@ -20,10 +20,6 @@
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Register your app',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { beforeNavigate, invalidate } from '$app/navigation';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
@@ -20,10 +20,6 @@
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Register your app',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { beforeNavigate, invalidate } from '$app/navigation';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
@@ -20,10 +20,6 @@
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Register your app',
|
||||
|
||||
@@ -2,15 +2,20 @@
|
||||
import Modal from '$lib/components/modal.svelte';
|
||||
import Button from '$lib/elements/forms/button.svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
export let showGitInstall: boolean;
|
||||
|
||||
function connectGitHub() {
|
||||
sdk.forProject.vcs.createGitHubInstallation(
|
||||
$page.params.project,
|
||||
window.location.href + '?alert=installation-created'
|
||||
const redirect = new URL($page.url);
|
||||
redirect.searchParams.append('alert', 'installation-created');
|
||||
const target = new URL(
|
||||
`${sdk.forProject.client.config.endpoint}/v1/vcs/github/installations`
|
||||
);
|
||||
target.searchParams.set('projectId', $page.params.project);
|
||||
target.searchParams.set('redirect', redirect.toString());
|
||||
goto(target);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -60,8 +60,13 @@
|
||||
|
||||
function configureGitHub() {
|
||||
const redirect = new URL($page.url);
|
||||
redirect.searchParams.set('alert', 'installation-updated');
|
||||
sdk.forProject.vcs.createGitHubInstallation(redirect.toString());
|
||||
redirect.searchParams.append('alert', 'installation-updated');
|
||||
const target = new URL(
|
||||
`${sdk.forProject.client.config.endpoint}/v1/vcs/github/installations`
|
||||
);
|
||||
target.searchParams.set('projectId', $page.params.project);
|
||||
target.searchParams.set('redirect', redirect.toString());
|
||||
goto(target);
|
||||
}
|
||||
|
||||
async function navigateInstallations() {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { beforeNavigate } from '$app/navigation';
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { Empty } from '$lib/components';
|
||||
@@ -26,10 +25,6 @@
|
||||
wizard.start(Create);
|
||||
}
|
||||
|
||||
beforeNavigate(() => {
|
||||
wizard.hide();
|
||||
});
|
||||
|
||||
const projectId = $page.params.project;
|
||||
</script>
|
||||
|
||||
|
||||
+8
-1
@@ -7,7 +7,14 @@ const config = defineConfig({
|
||||
include: ['echarts', 'prismjs']
|
||||
},
|
||||
ssr: {
|
||||
noExternal: ['echarts', 'prismjs', '@analytics/google-analytics', 'analytics', 'dayjs']
|
||||
noExternal: [
|
||||
'echarts',
|
||||
'prismjs',
|
||||
'@analytics/google-analytics',
|
||||
'analytics',
|
||||
'dayjs',
|
||||
'dotenv'
|
||||
]
|
||||
},
|
||||
define: {
|
||||
'import.meta.env.VERCEL_ANALYTICS_ID': JSON.stringify(process.env.VERCEL_ANALYTICS_ID)
|
||||
|
||||
Reference in New Issue
Block a user