mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge pull request #1266 from appwrite/feat-use-functions-listtemplates
feat: use functions listtemplates
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@
|
||||
"e2e:ui": "playwright test tests/e2e --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appwrite.io/console": "npm:matej-appwrite-console@0.6.10",
|
||||
"@appwrite.io/console": "npm:matej-appwrite-console@0.6.13",
|
||||
"@appwrite.io/pink": "0.25.0",
|
||||
"@appwrite.io/pink-icons": "0.25.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
|
||||
Generated
+5
-5
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@appwrite.io/console':
|
||||
specifier: npm:matej-appwrite-console@0.6.10
|
||||
version: matej-appwrite-console@0.6.10
|
||||
specifier: npm:matej-appwrite-console@0.6.13
|
||||
version: matej-appwrite-console@0.6.13
|
||||
'@appwrite.io/pink':
|
||||
specifier: 0.25.0
|
||||
version: 0.25.0
|
||||
@@ -2164,8 +2164,8 @@ packages:
|
||||
makeerror@1.0.12:
|
||||
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
|
||||
|
||||
matej-appwrite-console@0.6.10:
|
||||
resolution: {integrity: sha512-gaeMHwp23uPcuBWe4/4nCNTyY81GAyyCsLFLwOom9Gl6m+VRwr7hgsz9wqoCfHfHA09nAAT3Vp9jFZoQ+WIeZQ==}
|
||||
matej-appwrite-console@0.6.13:
|
||||
resolution: {integrity: sha512-F15YP98n9Um809SN3wbyZun8ZFY/m5MEU2uWUUU+4ej+PI0af3YGhwnkYC1nmciKpDbILf8O4hQ1+ORXKho8hg==}
|
||||
|
||||
mdn-data@2.0.30:
|
||||
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
|
||||
@@ -5602,7 +5602,7 @@ snapshots:
|
||||
dependencies:
|
||||
tmpl: 1.0.5
|
||||
|
||||
matej-appwrite-console@0.6.10: {}
|
||||
matej-appwrite-console@0.6.13: {}
|
||||
|
||||
mdn-data@2.0.30: {}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
import { page } from '$app/stores';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { derived } from 'svelte/store';
|
||||
|
||||
export const runtimesList = derived(
|
||||
page,
|
||||
async ($page) => (await $page.data.runtimesList) as Models.RuntimeList
|
||||
);
|
||||
|
||||
export const baseRuntimesList = derived(runtimesList, async ($runtimesList) => {
|
||||
const baseRuntimes = new Map<string, Models.Runtime>();
|
||||
for (const runtime of (await $runtimesList).runtimes) {
|
||||
const runtimeBase = runtime.name.split('-')[0];
|
||||
baseRuntimes.set(runtimeBase, runtime);
|
||||
}
|
||||
return { runtimes: [...baseRuntimes.values()] };
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
import { page } from '$app/stores';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { derived } from 'svelte/store';
|
||||
|
||||
export const templatesList = derived(
|
||||
page,
|
||||
async ($page) => (await $page.data.templatesList) as Models.TemplateFunctionList
|
||||
);
|
||||
|
||||
export const featuredTemplatesList = derived(templatesList, async ($templatesList) => {
|
||||
return {
|
||||
templates: (await $templatesList).templates
|
||||
.filter((template) => template.id !== 'starter')
|
||||
.slice(0, 2)
|
||||
};
|
||||
});
|
||||
|
||||
export const starterTemplate = derived(templatesList, async ($templatesList) => {
|
||||
return (await $templatesList).templates.find((template) => template.id === 'starter');
|
||||
});
|
||||
@@ -1,7 +1,10 @@
|
||||
<script context="module" lang="ts">
|
||||
import CreateTemplate from './createTemplate.svelte';
|
||||
|
||||
export function connectTemplate(template: MarketplaceTemplate, runtime: string | null = null) {
|
||||
export function connectTemplate(
|
||||
template: Models.TemplateFunction,
|
||||
runtime: string | null = null
|
||||
) {
|
||||
const variables: Record<string, string> = {};
|
||||
template.variables.forEach((variable) => {
|
||||
variables[variable.name] = variable.value ?? '';
|
||||
@@ -28,10 +31,9 @@
|
||||
import { app } from '$lib/stores/app';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { repository, templateConfig, template as templateStore } from './store';
|
||||
import { marketplace, type MarketplaceTemplate } from '$lib/stores/marketplace';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { page } from '$app/stores';
|
||||
import { baseRuntimesList } from '$routes/(console)/project-[project]/functions/store';
|
||||
import { baseRuntimesList } from '$lib/stores/runtimes';
|
||||
import { trackEvent } from '$lib/actions/analytics';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import WizardCover from '$lib/layout/wizardCover.svelte';
|
||||
@@ -41,14 +43,12 @@
|
||||
import { tooltip } from '$lib/actions/tooltip';
|
||||
import { isSelfHosted } from '$lib/system';
|
||||
import { consoleVariables } from '$routes/(console)/store';
|
||||
import { featuredTemplatesList, starterTemplate } from '$lib/stores/templates';
|
||||
|
||||
const isVcsEnabled = $consoleVariables?._APP_VCS_ENABLED === true;
|
||||
let hasInstallations: boolean;
|
||||
let selectedRepository: string;
|
||||
|
||||
const quickStart = marketplace.find((template) => template.id === 'starter');
|
||||
const templates = marketplace.filter((template) => template.id !== 'starter').slice(0, 2);
|
||||
|
||||
function connect(event: CustomEvent<Models.ProviderRepository>) {
|
||||
trackEvent('click_connect_repository', {
|
||||
from: 'cover'
|
||||
@@ -112,7 +112,7 @@
|
||||
style:--grid-item-size="8rem"
|
||||
style:--grid-item-size-small-screens="9rem"
|
||||
style:--grid-gap=".5rem">
|
||||
{#await $baseRuntimesList}
|
||||
{#await Promise.all([$baseRuntimesList, $starterTemplate])}
|
||||
{#each Array(6) as _i}
|
||||
<li>
|
||||
<button
|
||||
@@ -126,7 +126,7 @@
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
{:then response}
|
||||
{:then [response, quickStart]}
|
||||
{@const runtimes = new Map(
|
||||
response.runtimes.map((r) => [r.$id, r])
|
||||
)}
|
||||
@@ -159,6 +159,9 @@
|
||||
</div>
|
||||
<div class="body-text-2">
|
||||
{runtimeDetail.name}
|
||||
{#if runtimeDetail.name.toLowerCase() === 'go'}
|
||||
<span class="inline-tag">New</span>
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
@@ -200,34 +203,56 @@
|
||||
</p>
|
||||
|
||||
<ul class="clickable-list u-margin-block-start-16">
|
||||
{#each templates as template}
|
||||
<li class="clickable-list-item">
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => {
|
||||
trackEvent('click_connect_template', {
|
||||
from: 'cover',
|
||||
template: template.id
|
||||
});
|
||||
}}
|
||||
on:click={() => connectTemplate(template)}
|
||||
class="clickable-list-button u-width-full-line u-flex u-gap-12">
|
||||
<div
|
||||
class="avatar is-size-small"
|
||||
style:--p-text-size="1.25rem">
|
||||
<span class={template.icon} />
|
||||
</div>
|
||||
<div class="u-flex u-flex-vertical u-gap-4">
|
||||
<div class="body-text-2 u-bold u-trim">
|
||||
{template.name}
|
||||
{#await $featuredTemplatesList}
|
||||
{#each Array(3) as _i}
|
||||
<li>
|
||||
<button
|
||||
disabled
|
||||
class="clickable-list-button u-width-full-line u-flex u-gap-12">
|
||||
<div class="avatar is-size-small">
|
||||
<div class="loader" />
|
||||
</div>
|
||||
<div class="u-trim-1 u-color-text-gray">
|
||||
{template.tagline}
|
||||
<div class="u-flex u-flex-vertical u-gap-4">
|
||||
<div class="body-text-2 u-bold u-trim">
|
||||
<div class="loader" />
|
||||
</div>
|
||||
<div class="u-trim-1 u-color-text-gray">
|
||||
<div class="loader" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
{:then templatesListWithoutStarter}
|
||||
{#each templatesListWithoutStarter.templates as template}
|
||||
<li class="clickable-list-item">
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => {
|
||||
trackEvent('click_connect_template', {
|
||||
from: 'cover',
|
||||
template: template.id
|
||||
});
|
||||
}}
|
||||
on:click={() => connectTemplate(template)}
|
||||
class="clickable-list-button u-width-full-line u-flex u-gap-12">
|
||||
<div
|
||||
class="avatar is-size-small"
|
||||
style:--p-text-size="1.25rem">
|
||||
<span class={template.icon} />
|
||||
</div>
|
||||
<div class="u-flex u-flex-vertical u-gap-4">
|
||||
<div class="body-text-2 u-bold u-trim">
|
||||
{template.name}
|
||||
</div>
|
||||
<div class="u-trim-1 u-color-text-gray">
|
||||
{template.tagline}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
{/await}
|
||||
</ul>
|
||||
</section>
|
||||
<Button
|
||||
@@ -261,7 +286,7 @@
|
||||
</div>
|
||||
</WizardCover>
|
||||
|
||||
<style>
|
||||
<style lang="scss">
|
||||
.git-container .overlay {
|
||||
background: linear-gradient(
|
||||
0,
|
||||
@@ -269,4 +294,9 @@
|
||||
hsl(var(--p-card-bg-color) / 0.5) 92.8%
|
||||
);
|
||||
}
|
||||
|
||||
.inline-tag {
|
||||
line-height: 140%;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
$template.providerRepositoryId || undefined,
|
||||
$template.providerOwner || undefined,
|
||||
runtimeDetail.providerRootDirectory || undefined,
|
||||
$template.providerBranch || undefined
|
||||
$template.providerVersion || undefined
|
||||
);
|
||||
|
||||
if ($templateConfig.variables) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { choices, createFunction, installation, repository } from '../store';
|
||||
import { runtimesList } from '$routes/(console)/project-[project]/functions/store';
|
||||
import { runtimesList } from '$lib/stores/runtimes';
|
||||
|
||||
let showCustomId = false;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { onMount } from 'svelte';
|
||||
import { createFunction } from '../store';
|
||||
import { runtimesList } from '$routes/(console)/project-[project]/functions/store';
|
||||
import { runtimesList } from '$lib/stores/runtimes';
|
||||
|
||||
let showCustomId = false;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Pill } from '$lib/elements';
|
||||
import { FormList, InputSelect, InputText } from '$lib/elements/forms';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { runtimesList } from '$routes/(console)/project-[project]/functions/store';
|
||||
import { runtimesList } from '$lib/stores/runtimes';
|
||||
import { template, templateConfig } from '../store';
|
||||
|
||||
let showCustomId = false;
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
$: requiredVariables = $template?.variables?.filter((v) => v.required);
|
||||
$: optionalVariables = $template?.variables?.filter((v) => !v.required);
|
||||
|
||||
function selectComponent(
|
||||
variableType: 'password' | 'text' | 'number' | 'email' | 'url' | 'phone'
|
||||
): typeof SvelteComponent<unknown> {
|
||||
function selectComponent(variableType: string): typeof SvelteComponent<unknown> {
|
||||
switch (variableType) {
|
||||
case 'password':
|
||||
return InputPassword;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { page } from '$app/stores';
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
import type { MarketplaceTemplate } from '$lib/stores/marketplace';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { derived, writable, type Writable } from 'svelte/store';
|
||||
|
||||
export const template = writable<MarketplaceTemplate>();
|
||||
export const template = writable<Models.TemplateFunction>();
|
||||
export const templateConfig = writable<{
|
||||
$id: string;
|
||||
name: string;
|
||||
|
||||
@@ -8,15 +8,17 @@ import type { LayoutLoad } from './$types';
|
||||
export const load: LayoutLoad = async ({ depends }) => {
|
||||
depends(Dependencies.FUNCTION_INSTALLATIONS);
|
||||
|
||||
const [runtimesList, installations] = await Promise.all([
|
||||
const [runtimesList, installations, templatesList] = await Promise.all([
|
||||
sdk.forProject.functions.listRuntimes(),
|
||||
sdk.forProject.vcs.listInstallations([Query.limit(100)])
|
||||
sdk.forProject.vcs.listInstallations([Query.limit(100)]),
|
||||
sdk.forProject.functions.listTemplates(undefined, undefined, 100)
|
||||
]);
|
||||
|
||||
return {
|
||||
header: Header,
|
||||
breadcrumbs: Breadcrumbs,
|
||||
runtimesList,
|
||||
installations
|
||||
installations,
|
||||
templatesList
|
||||
};
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import { toLocaleDateTime } from '$lib/helpers/date';
|
||||
import { Container, ContainerHeader } from '$lib/layout';
|
||||
import { isServiceLimited } from '$lib/stores/billing';
|
||||
import { marketplace } from '$lib/stores/marketplace.js';
|
||||
import { templatesList } from '$lib/stores/templates';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import Initial from '$lib/wizards/functions/cover.svelte';
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
const project = $page.params.project;
|
||||
|
||||
onMount(() => {
|
||||
onMount(async () => {
|
||||
const from = $page.url.searchParams.get('from');
|
||||
if (from === 'github') {
|
||||
const to = $page.url.searchParams.get('to');
|
||||
@@ -43,7 +43,9 @@
|
||||
const step = $page.url.searchParams.get('step');
|
||||
const template = $page.url.searchParams.get('template');
|
||||
const templateConfig = $page.url.searchParams.get('templateConfig');
|
||||
templateStore.set(marketplace.find((item) => item.id === template));
|
||||
templateStore.set(
|
||||
(await $templatesList).templates.find((item) => item.id === template)
|
||||
);
|
||||
templateConfigStore.set(JSON.parse(templateConfig));
|
||||
wizard.start(CreateTemplate);
|
||||
wizard.setStep(Number(step));
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { func } from '../store';
|
||||
import InputSelect from '$lib/elements/forms/inputSelect.svelte';
|
||||
import { runtimesList } from '../../store';
|
||||
import { runtimesList } from '$lib/stores/runtimes';
|
||||
import { isValueOfStringEnum } from '$lib/helpers/types';
|
||||
import { Runtime } from '@appwrite.io/console';
|
||||
|
||||
|
||||
@@ -2,18 +2,4 @@ import { page } from '$app/stores';
|
||||
import { derived } from 'svelte/store';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
|
||||
export const runtimesList = derived(
|
||||
page,
|
||||
async ($page) => (await $page.data.runtimesList) as Models.RuntimeList
|
||||
);
|
||||
|
||||
export const baseRuntimesList = derived(runtimesList, async ($runtimesList) => {
|
||||
const baseRuntimes = new Map<string, Models.Runtime>();
|
||||
for (const runtime of (await $runtimesList).runtimes) {
|
||||
const runtimeBase = runtime.name.split('-')[0];
|
||||
baseRuntimes.set(runtimeBase, runtime);
|
||||
}
|
||||
return { runtimes: [...baseRuntimes.values()] };
|
||||
});
|
||||
|
||||
export const functionsList = derived(page, ($page) => $page.data.functions as Models.FunctionList);
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
import { Container, ContainerButton } from '$lib/layout';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { isServiceLimited } from '$lib/stores/billing';
|
||||
import type { Runtime } from '$lib/stores/marketplace.js';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { connectTemplate } from '$lib/wizards/functions/cover.svelte';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { functionsList } from '../store';
|
||||
|
||||
export let data;
|
||||
@@ -43,8 +43,8 @@
|
||||
goto(target.toString());
|
||||
}
|
||||
|
||||
function getBaseRuntimes(runtimes: Runtime[]): Runtime[] {
|
||||
const baseRuntimes = new Map<string, Runtime>();
|
||||
function getBaseRuntimes(runtimes: Models.TemplateRuntime[]): Models.TemplateRuntime[] {
|
||||
const baseRuntimes = new Map<string, Models.TemplateRuntime>();
|
||||
for (const runtime of runtimes) {
|
||||
const [baseRuntime] = runtime.name.split('-');
|
||||
baseRuntimes.set(baseRuntime, {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { CARD_LIMIT, Dependencies } from '$lib/constants';
|
||||
import { getPage, getSearch, getView, pageToOffset, View } from '$lib/helpers/load';
|
||||
import { marketplace } from '$lib/stores/marketplace';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load: PageLoad = async ({ url, route, depends }) => {
|
||||
export const load: PageLoad = async ({ url, route, depends, parent }) => {
|
||||
depends(Dependencies.FUNCTIONS);
|
||||
|
||||
const limit = CARD_LIMIT;
|
||||
@@ -16,16 +15,19 @@ export const load: PageLoad = async ({ url, route, depends }) => {
|
||||
useCases: url.searchParams.getAll('useCase'),
|
||||
runtimes: url.searchParams.getAll('runtime')
|
||||
};
|
||||
const [runtimes, useCases] = marketplace.reduce(
|
||||
|
||||
const { templatesList } = await parent();
|
||||
|
||||
const [runtimes, useCases] = templatesList.templates.reduce(
|
||||
([rt, uc], next) => {
|
||||
next.runtimes.forEach((runtime) => rt.add(runtime.name));
|
||||
next.usecases.forEach((useCase) => uc.add(useCase));
|
||||
next.useCases.forEach((useCase) => uc.add(useCase));
|
||||
return [rt, uc];
|
||||
},
|
||||
[new Set<string>(), new Set<string>()]
|
||||
);
|
||||
|
||||
const templates = marketplace.filter((template) => {
|
||||
const templates = templatesList.templates.filter((template) => {
|
||||
if (
|
||||
filter.runtimes.length > 0 &&
|
||||
!template.runtimes.some((n) => filter.runtimes.includes(n.name))
|
||||
@@ -35,7 +37,7 @@ export const load: PageLoad = async ({ url, route, depends }) => {
|
||||
|
||||
if (
|
||||
filter.useCases.length > 0 &&
|
||||
!template.usecases.some((n) => filter.useCases.includes(n))
|
||||
!template.useCases.some((n) => filter.useCases.includes(n))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-2
@@ -23,10 +23,10 @@
|
||||
<Collapsible>
|
||||
<li class="collapsible-item">
|
||||
<h3 class="body-text-2 u-bold u-padding-block-12">
|
||||
Use cases <span class="inline-tag">{$template.usecases.length}</span>
|
||||
Use cases <span class="inline-tag">{$template.useCases.length}</span>
|
||||
</h3>
|
||||
<div class="collapsible-content u-flex u-flex-wrap u-gap-8">
|
||||
{#each $template.usecases as useCase}
|
||||
{#each $template.useCases as useCase}
|
||||
<Pill>{useCase}</Pill>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
+1
-2
@@ -1,5 +1,4 @@
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { marketplace } from '$lib/stores/marketplace';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
@@ -7,7 +6,7 @@ export const load: PageLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.FUNCTIONS);
|
||||
|
||||
return {
|
||||
template: marketplace.find((template) => template.id === params.template),
|
||||
template: await sdk.forProject.functions.getTemplate(params.template),
|
||||
functions: await sdk.forProject.functions.list()
|
||||
};
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { page } from '$app/stores';
|
||||
import type { MarketplaceTemplate } from '$lib/stores/marketplace';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { derived } from 'svelte/store';
|
||||
|
||||
export const template = derived(page, ($page) => $page.data.template as MarketplaceTemplate);
|
||||
export const template = derived(page, ($page) => $page.data.template as Models.TemplateFunction);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { onMount } from 'svelte';
|
||||
import { createFunction } from './store';
|
||||
import { runtimesList } from '../store';
|
||||
import { runtimesList } from '$lib/stores/runtimes';
|
||||
|
||||
let showCustomId = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user