Merge pull request #1266 from appwrite/feat-use-functions-listtemplates

feat: use functions listtemplates
This commit is contained in:
Christy Jacob
2024-08-16 23:59:05 +04:00
committed by GitHub
22 changed files with 142 additions and 2416 deletions
+1 -1
View File
@@ -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",
+5 -5
View File
@@ -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
+17
View File
@@ -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()] };
});
+20
View File
@@ -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');
});
+65 -35
View File
@@ -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 -2
View File
@@ -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));
@@ -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;
}
@@ -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,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()
};
};
@@ -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;