diff --git a/package-lock.json b/package-lock.json index 52821597cd..95b75fc735 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@analytics/google-analytics": "^1.0.5", - "@aw-labs/appwrite-console": "^13.1.0", + "@aw-labs/appwrite-console": "npm:matej-appwrite-console@7.1.74", "@aw-labs/icons": "0.0.0-77", "@aw-labs/ui": "0.0.0-77", "@popperjs/core": "^2.11.6", @@ -145,9 +145,10 @@ "integrity": "sha512-1Yw7u/COtxx06BfwlI+kVhsa/upKYzmCNrT4c8QDeCY2KMYlnijkUjtHiPU08HxyTIVB5j6d75O0YWVIHwQS8g==" }, "node_modules/@aw-labs/appwrite-console": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@aw-labs/appwrite-console/-/appwrite-console-13.1.0.tgz", - "integrity": "sha512-1FyKke5b3vx+D3VfNYd3YnFhzUOlsj9bD+KTRLWA4WRItb55thFVZJMWQQ4XnZtDiLPuJAn2XjbMSfMr+9XYwg==", + "name": "matej-appwrite-console", + "version": "7.1.74", + "resolved": "https://registry.npmjs.org/matej-appwrite-console/-/matej-appwrite-console-7.1.74.tgz", + "integrity": "sha512-cFpQNAf7lfnCoZDvXEu0JPiN3Bh1aWsX9VOa3h3C3UCDcpxtq8/UPnOeXJReMSrDgT4GoMUV2ug1oRvlzci4pw==", "dependencies": { "cross-fetch": "3.1.5", "isomorphic-form-data": "2.0.0" @@ -7740,9 +7741,9 @@ "integrity": "sha512-1Yw7u/COtxx06BfwlI+kVhsa/upKYzmCNrT4c8QDeCY2KMYlnijkUjtHiPU08HxyTIVB5j6d75O0YWVIHwQS8g==" }, "@aw-labs/appwrite-console": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@aw-labs/appwrite-console/-/appwrite-console-13.1.0.tgz", - "integrity": "sha512-1FyKke5b3vx+D3VfNYd3YnFhzUOlsj9bD+KTRLWA4WRItb55thFVZJMWQQ4XnZtDiLPuJAn2XjbMSfMr+9XYwg==", + "version": "npm:matej-appwrite-console@7.1.74", + "resolved": "https://registry.npmjs.org/matej-appwrite-console/-/matej-appwrite-console-7.1.74.tgz", + "integrity": "sha512-cFpQNAf7lfnCoZDvXEu0JPiN3Bh1aWsX9VOa3h3C3UCDcpxtq8/UPnOeXJReMSrDgT4GoMUV2ug1oRvlzci4pw==", "requires": { "cross-fetch": "3.1.5", "isomorphic-form-data": "2.0.0" diff --git a/package.json b/package.json index 266a4d3659..8eec45196a 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "node": ">=16" }, "scripts": { - "dev": "vite dev", + "dev": "vite dev --host 0.0.0.0", "build": "vite build", "preview": "vite preview", "sync": "svelte-kit sync", @@ -21,7 +21,7 @@ "dependencies": { "@analytics/google-analytics": "^1.0.5", "analytics": "^0.8.1", - "@aw-labs/appwrite-console": "^13.1.0", + "@aw-labs/appwrite-console": "npm:matej-appwrite-console@7.1.74", "@aw-labs/icons": "0.0.0-77", "@aw-labs/ui": "0.0.0-77", "@popperjs/core": "^2.11.6", diff --git a/src/lib/components/cardGrid.svelte b/src/lib/components/cardGrid.svelte index 2215cc6dcd..880463d321 100644 --- a/src/lib/components/cardGrid.svelte +++ b/src/lib/components/cardGrid.svelte @@ -14,7 +14,7 @@ {#if $$slots.actions} -
+
{/if} diff --git a/src/lib/components/code.svelte b/src/lib/components/code.svelte index 24debe415f..ab0505d91b 100644 --- a/src/lib/components/code.svelte +++ b/src/lib/components/code.svelte @@ -1,8 +1,11 @@ - + Delete Domain - {#if selectedDomain} -

- Are you sure you want to delete {selectedDomain.domain} from '{$project.name}'? -

- {/if} +

Are you sure you want to delete this domain?

diff --git a/src/routes/console/project-[project]/settings/domains/[[page]]/+page.svelte b/src/lib/components/domains/domainContainer.svelte similarity index 51% rename from src/routes/console/project-[project]/settings/domains/[[page]]/+page.svelte rename to src/lib/components/domains/domainContainer.svelte index 4ec970670f..68a8b78f36 100644 --- a/src/routes/console/project-[project]/settings/domains/[[page]]/+page.svelte +++ b/src/lib/components/domains/domainContainer.svelte @@ -1,5 +1,4 @@
- Custom Domains + Domains
- {#if data.domains.total} + {#if rules.total} - Domain Name - - Type - Name - Value - + Domain Name + Status + + Actions - {#each data.domains.domains as domain} + {#each rules.rules as rule} - {domain.domain} +
+

{rule.domain}

+
+ +
+
- - {domain.verification ? 'verified' : 'unverified'} + + {rule.status} - CNAME - - {domain.domain} - - - {target} - + +
- {#if isVerifying[domain.$id]} + {#if rule.status === 'verifying' || isVerifying[rule.$id]}
- {:else if !domain.certificateId} + {:else if rule.status === 'unverified' || rule.status === 'created'} {/if} + {#if rule.status === 'unverified' || rule.status === 'verified'} + + + {/if} + + + diff --git a/src/routes/console/project-[project]/settings/domains/wizard/cnameTable.svelte b/src/lib/components/domains/wizard/cnameTable.svelte similarity index 89% rename from src/routes/console/project-[project]/settings/domains/wizard/cnameTable.svelte rename to src/lib/components/domains/wizard/cnameTable.svelte index 55eff51702..11840e67fe 100644 --- a/src/routes/console/project-[project]/settings/domains/wizard/cnameTable.svelte +++ b/src/lib/components/domains/wizard/cnameTable.svelte @@ -10,12 +10,12 @@ TableHeader, TableRow } from '$lib/elements/table'; - import { domain } from './store'; + import { rule } from './store'; const target = window?.location.hostname ?? ''; - $: parts = $domain.domain.split('.'); + $: parts = $rule.domain.split('.'); $: registerable = [parts[parts.length - 2], parts[parts.length - 1]].join('.'); - $: cnameValue = $domain.domain.replace('.' + registerable, ''); + $: cnameValue = $rule.domain.replace('.' + registerable, ''); diff --git a/src/lib/components/domains/wizard/step1.svelte b/src/lib/components/domains/wizard/step1.svelte new file mode 100644 index 0000000000..e4d45e8d7a --- /dev/null +++ b/src/lib/components/domains/wizard/step1.svelte @@ -0,0 +1,71 @@ + + + + Add {typeVerbose} domain + + Use your self-owned domain as the endpoint of your Appwrite {typeVerbose}. + + + + + +
+

+ You can find a list of domain providers and their DNS setting documentation here. If your domain provider isn't listed, please contact us, and we'll include their + settings as well. +

+
+
diff --git a/src/routes/console/project-[project]/settings/domains/wizard/step2.svelte b/src/lib/components/domains/wizard/step2.svelte similarity index 100% rename from src/routes/console/project-[project]/settings/domains/wizard/step2.svelte rename to src/lib/components/domains/wizard/step2.svelte diff --git a/src/routes/console/project-[project]/settings/domains/wizard/step3.svelte b/src/lib/components/domains/wizard/step3.svelte similarity index 89% rename from src/routes/console/project-[project]/settings/domains/wizard/step3.svelte rename to src/lib/components/domains/wizard/step3.svelte index 74598ab47a..0b894b232c 100644 --- a/src/routes/console/project-[project]/settings/domains/wizard/step3.svelte +++ b/src/lib/components/domains/wizard/step3.svelte @@ -3,7 +3,6 @@ import CnameTable from './cnameTable.svelte'; import VerificationBox from './verificationBox.svelte'; - let isVerifying = false; let isVerified = false; @@ -19,7 +18,7 @@

Changes may take some time to take effect depending on your provider.

- +
diff --git a/src/lib/components/domains/wizard/step4.svelte b/src/lib/components/domains/wizard/step4.svelte new file mode 100644 index 0000000000..74da9cf261 --- /dev/null +++ b/src/lib/components/domains/wizard/step4.svelte @@ -0,0 +1,68 @@ + + + + Add a CNAME record + + In order to continue, set the following record on your DNS provider + + + + +
+ +
+
+ {#if status === 'verifying'} +
+

Generating SSL certificate

+ {:else if status === 'unverified'} +
+
+
+ diff --git a/src/lib/components/domains/wizard/store.ts b/src/lib/components/domains/wizard/store.ts new file mode 100644 index 0000000000..74905df329 --- /dev/null +++ b/src/lib/components/domains/wizard/store.ts @@ -0,0 +1,8 @@ +import type { Models } from '@aw-labs/appwrite-console'; +import { writable } from 'svelte/store'; + +export const rule = writable>({ $id: '', domain: '' }); +export const ruleResource = writable<{ + type: string; + id: string; +}>({ type: '', id: '' }); diff --git a/src/routes/console/project-[project]/settings/domains/wizard/verificationBox.svelte b/src/lib/components/domains/wizard/verificationBox.svelte similarity index 70% rename from src/routes/console/project-[project]/settings/domains/wizard/verificationBox.svelte rename to src/lib/components/domains/wizard/verificationBox.svelte index 4501562a5c..47a933ac97 100644 --- a/src/routes/console/project-[project]/settings/domains/wizard/verificationBox.svelte +++ b/src/lib/components/domains/wizard/verificationBox.svelte @@ -1,24 +1,21 @@ + + + Code Snippet + + (language = Language.NodeJs)} selected={language === Language.NodeJs}> + Node.js + + (language = Language.PHP)} selected={language === Language.PHP}> + PHP + + (language = Language.Python)} selected={language === Language.Python}> + Python + + (language = Language.Ruby)} selected={language === Language.Ruby}> + Ruby + + (language = Language.Deno)} selected={language === Language.Deno}> + Deno + + (language = Language.Dart)} selected={language === Language.Dart}> + Dart + + (language = Language.Kotlin)} selected={language === Language.Kotlin}> + Kotlin + + (language = Language.Swift)} selected={language === Language.Swift}> + Swift + + + +

Code snippet showing how to read environment variables in Appwrite Functions.

+ + {#if language === Language.NodeJs} + + {:else if language === Language.PHP} + + {:else if language === Language.Python} + + {:else if language === Language.Ruby} + + {:else if language === Language.Deno} + + {:else if language === Language.Dart} + + {:else if language === Language.Kotlin} + + {:else if language === Language.Swift} + + {/if} + + + + +
diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/uploadVariables.svelte b/src/lib/components/environmentVariables/upload.svelte similarity index 86% rename from src/routes/console/project-[project]/functions/function-[function]/settings/uploadVariables.svelte rename to src/lib/components/environmentVariables/upload.svelte index 5c61222359..2081bb727c 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/uploadVariables.svelte +++ b/src/lib/components/environmentVariables/upload.svelte @@ -1,4 +1,6 @@ - Upload Variables + Upload Environment Variables

- Upload multiple variables via a .env file that will be passed to your function at runtime. + Upload multiple environment variables via a .env file that will be passed to your function + at runtime and during build.

diff --git a/src/lib/components/environmentVariables/variables.svelte b/src/lib/components/environmentVariables/variables.svelte new file mode 100644 index 0000000000..4edfb80fe7 --- /dev/null +++ b/src/lib/components/environmentVariables/variables.svelte @@ -0,0 +1,313 @@ + + +{#if variables.variables.length} + {#if !isWizard} +
+ + +
+ {/if} +
+ + + + + + + + {#if variables.total} + {#each variables.variables as variable, i} + + + + + + {/each} + {/if} + +
+ Key + + Value + +
+ {variable.key} + +
+ {#if showVariablesValue[i]} + {variable.value} + {:else} + •••••••• + {/if} +
+ + + + +
+
+
+ + + + { + snippetKey = variable.key; + showSnippet = true; + showVariablesDropdown[i] = false; + }}> + Code snippets + + { + selectedVar = variable; + showVariablesDropdown[i] = false; + showVariablesModal = true; + }}> + Edit + + { + handleVariableDeleted(variable); + showVariablesDropdown[i] = false; + }}> + Delete + + {#if !isGlobal && !isWizard} + { + showPromote = true; + promoteVariable = variable; + }}>Promote + {/if} + + +
+
+ +
+{:else} + (showVariablesModal = !showVariablesModal)} + >Create an environment variable to get started +{/if} + +{#if !isGlobal && !isWizard} + + Global variables from project settings are also + available. When there is name conflict, function variable is used. + +{/if} + + +{#if showVariablesModal} + +{/if} + +{#if !isGlobal} + handlePromote(promoteVariable)} warning> + Promote To Global Variable +

+ Are you sure you want to promote {promoteVariable.key}? This will move + variable into project settings and make it visible to all services. +

+ + + + +
+{/if} diff --git a/src/lib/components/eventModal.svelte b/src/lib/components/eventModal.svelte index 72b4e8d36b..6e7ab6c882 100644 --- a/src/lib/components/eventModal.svelte +++ b/src/lib/components/eventModal.svelte @@ -83,6 +83,11 @@ { name: 'update', attributes: ['email', 'name', 'password', 'status', 'prefs'] }, { name: 'delete' } ] + }, + { + name: 'rules', + resources: [], + actions } ]; @@ -200,23 +205,25 @@
{#if selectedService} -
-

Choose a resource (optional)

-
- {#each selectedService.resources as resource} - { - selectedResource === resource - ? (selectedResource = null) - : (selectedResource = resource); - inputData = null; - }}>{resource.name} - {/each} + {#if selectedService.resources.length > 0} +
+

Choose a resource (optional)

+
+ {#each selectedService.resources as resource} + { + selectedResource === resource + ? (selectedResource = null) + : (selectedResource = resource); + inputData = null; + }}>{resource.name} + {/each} +
-
+ {/if}

Choose an action (optional)

diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 428ae63923..f21f9de1e8 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -28,6 +28,7 @@ export enum Dependencies { BUCKET = 'dependency:bucket', FILE = 'dependency:file', FILES = 'dependency:files', + INSTALLATIONS = 'dependency:installations', FUNCTION = 'dependency:function', FUNCTIONS = 'dependency:functions', VARIABLES = 'dependency:variables', @@ -37,9 +38,9 @@ export enum Dependencies { PLATFORMS = 'dependency:platforms', KEY = 'dependency:key', KEYS = 'dependency:keys', - DOMAINS = 'dependency:domains', WEBHOOK = 'dependency:webhook', - WEBHOOKS = 'dependency:webhooks' + WEBHOOKS = 'dependency:webhooks', + RULES = 'dependency:rules' } export const scopes: { @@ -174,5 +175,15 @@ export const scopes: { scope: 'health.read', description: "Access to read your project's health status", category: 'Other' + }, + { + scope: 'rules.read', + description: "Access to read your project's proxy rules", + category: 'Other' + }, + { + scope: 'rules.write', + description: "Access to create, update, and delete your project's proxy rules", + category: 'Other' } ]; diff --git a/src/lib/elements/forms/inputDomain.svelte b/src/lib/elements/forms/inputDomain.svelte index 697059a130..670eeadf94 100644 --- a/src/lib/elements/forms/inputDomain.svelte +++ b/src/lib/elements/forms/inputDomain.svelte @@ -15,7 +15,7 @@ export let maxlength: number = null; // https://www.geeksforgeeks.org/how-to-validate-a-domain-name-using-regular-expression/ - const pattern = String.raw`^(?!-)[A-Za-z0-9-]+([\-\.]{1}[a-z0-9]+)*\.[A-Za-z]{2,6}$`; + const pattern = String.raw`^(?!-)[A-Za-z0-9-]+([\-\.]{1}[a-z0-9]+)*\.[A-Za-z]{2,9}$`; let element: HTMLInputElement; let error: string; diff --git a/src/lib/layout/logs.svelte b/src/lib/layout/logs.svelte index 4297e0dc66..3879bcf0a3 100644 --- a/src/lib/layout/logs.svelte +++ b/src/lib/layout/logs.svelte @@ -14,7 +14,9 @@ let selectedTab: string; let rawData: string; - function isDeployment(data: Models.Deployment | Models.Execution): data is Models.Deployment { + function isDeployment( + data: Models.Deployment | Models.Execution + ): data is Models.Deployment { if ('buildId' in data) { selectedTab = 'logs'; rawData = `${sdkForConsole.client.config.endpoint}/functions/${$log.func.$id}/deployment/${$log.data.$id}?mode=admin&project=${$page.params.project}`; @@ -22,9 +24,11 @@ } } - function isExecution(data: Models.Deployment | Models.Execution): data is Models.Execution { + function isExecution( + data: Models.Deployment | Models.Execution + ): data is Models.Execution { if ('trigger' in data) { - selectedTab = 'response'; + selectedTab = 'logs'; rawData = `${sdkForConsole.client.config.endpoint}/functions/${$log.func.$id}/execution/${$log.data.$id}?mode=admin&project=${$page.params.project}`; return true; } @@ -153,16 +157,30 @@
{$log.data.status} -
(selectedTab = 'response')}> - Response + selected={selectedTab === 'method'} + on:click={() => (selectedTab = 'method')}> + Method + + (selectedTab = 'path')}> + Path and query + + (selectedTab = 'agent')}> + Agent + + (selectedTab = 'statusCode')}> + Status Code {#if selectedTab === 'logs'} - {$log.data.stdout ?? 'No logs recorded'} + {$log.data.logs ? $log.data.logs : 'No logs.'} {:else if selectedTab === 'errors'} - {$log.data.stderr ?? 'No errors recorded'} + {$log.data.errors ? $log.data.errors : 'No errors.'} - {:else} + {:else if selectedTab === 'statusCode'} + + {$log.data.statusCode + ? $log.data.statusCode + : 'No response status code.'} + + {:else if selectedTab === 'method'} + + {$log.data.method ? $log.data.method : 'No request method.'} + + {:else if selectedTab === 'agent'} + + {$log.data.agent ? $log.data.agent : 'No request agent.'} + + {:else if selectedTab === 'path'} - {$log.data.response ?? 'No response recorded'} + {$log.data.path ? $log.data.path : 'No request path.'} {/if} diff --git a/src/lib/stores/logs.ts b/src/lib/stores/logs.ts index 7fd421a6e4..ea841a2850 100644 --- a/src/lib/stores/logs.ts +++ b/src/lib/stores/logs.ts @@ -4,7 +4,7 @@ import { writable } from 'svelte/store'; export const log = writable<{ show: boolean; func: Models.Function; - data: Models.Execution | Models.Deployment; + data: Models.Execution | Models.Deployment; }>({ show: false, func: null, diff --git a/src/lib/stores/project-services.ts b/src/lib/stores/project-services.ts index ef8a1c4440..30364b1e1e 100644 --- a/src/lib/stores/project-services.ts +++ b/src/lib/stores/project-services.ts @@ -59,6 +59,11 @@ function createServices() { label: 'GraphQL', method: 'graphql', value: null + }, + { + label: 'Proxy', + method: 'proxy', + value: null } ] }); @@ -117,6 +122,11 @@ function createServices() { label: 'GraphQL', method: 'graphql', value: project.serviceStatusForGraphql + }, + { + label: 'Proxy', + method: 'proxy', + value: project.serviceStatusForProxy } ]; set({ list }); diff --git a/src/lib/stores/sdk.ts b/src/lib/stores/sdk.ts index 05d99d6630..96e3d8beb2 100644 --- a/src/lib/stores/sdk.ts +++ b/src/lib/stores/sdk.ts @@ -7,13 +7,14 @@ import { Health, Locale, Projects, + Project, + Proxy, Storage, Teams, - Users + Users, + Vcs } from '@aw-labs/appwrite-console'; -import { Project } from './project'; - const endpoint = import.meta.env.VITE_APPWRITE_ENDPOINT?.toString() ?? `${window?.location?.origin}/v1`; const clientConsole = new Client(); @@ -33,7 +34,8 @@ const sdkForConsole = { locale: new Locale(clientConsole), projects: new Projects(clientConsole), teams: new Teams(clientConsole), - users: new Users(clientConsole) + users: new Users(clientConsole), + proxy: new Proxy(clientConsole) }; const sdkForProject = { @@ -48,7 +50,9 @@ const sdkForProject = { projects: new Projects(clientProject), storage: new Storage(clientProject), teams: new Teams(clientProject), - users: new Users(clientProject) + users: new Users(clientProject), + proxy: new Proxy(clientProject), + vcs: new Vcs(clientProject) }; export { sdkForConsole, sdkForProject, setProject, endpoint }; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index c679384685..a3569cbd30 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -53,7 +53,6 @@ !$page.url.pathname.startsWith('/console') && !$page.url.pathname.startsWith('/invite') ) { - console.log('test'); await goto(`${base}/console`, { replaceState: true }); diff --git a/src/routes/console/project-[project]/functions/+layout.svelte b/src/routes/console/project-[project]/functions/+layout.svelte index 8ccdfb6926..68c237bf3f 100644 --- a/src/routes/console/project-[project]/functions/+layout.svelte +++ b/src/routes/console/project-[project]/functions/+layout.svelte @@ -10,6 +10,8 @@ unsubscribe = sdkForConsole.client.subscribe('console', (response) => { if (response.events.includes('functions.*.deployments.*')) { invalidate(Dependencies.DEPLOYMENTS); + } else if (response.events.includes('rules.*')) { + invalidate(Dependencies.RULES); } }); }); diff --git a/src/routes/console/project-[project]/functions/[[page]]/+page.svelte b/src/routes/console/project-[project]/functions/[[page]]/+page.svelte index 0efa6e7ff2..0d27d2008d 100644 --- a/src/routes/console/project-[project]/functions/[[page]]/+page.svelte +++ b/src/routes/console/project-[project]/functions/[[page]]/+page.svelte @@ -5,11 +5,9 @@ import { Pill } from '$lib/elements'; 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 Create from '../createFunction.svelte'; import type { PageData } from './$types'; import { CARD_LIMIT } from '$lib/constants'; @@ -58,19 +56,6 @@ {func.name}
- - {#if func.scheduleNext} -
  • -
  • - {/if} -
    Function ID diff --git a/src/routes/console/project-[project]/functions/createFunction.svelte b/src/routes/console/project-[project]/functions/createFunction.svelte index e7a33229eb..00c5d27208 100644 --- a/src/routes/console/project-[project]/functions/createFunction.svelte +++ b/src/routes/console/project-[project]/functions/createFunction.svelte @@ -27,8 +27,8 @@ const response = await sdkForProject.functions.create( $createFunction.id ?? 'unique()', $createFunction.name, - $createFunction.execute, $createFunction.runtime, + $createFunction.execute, $createFunction.events, $createFunction.schedule, $createFunction.timeout @@ -87,7 +87,7 @@ optional: true }); stepsComponents.set(5, { - label: 'Variables', + label: 'Environment Variables', component: Step5, optional: true }); diff --git a/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.svelte index 1ffec2be61..7da2c7ce78 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/[[page]]/+page.svelte @@ -35,10 +35,11 @@ import Create from '../create.svelte'; import Activate from '../activate.svelte'; import { browser } from '$app/environment'; - import { sdkForConsole } from '$lib/stores/sdk'; + import { sdkForConsole, sdkForProject } from '$lib/stores/sdk'; import { page } from '$app/stores'; import Output from '$lib/components/output.svelte'; import { calculateTime } from '$lib/helpers/timeConversion'; + import { onDestroy, onMount, tick } from 'svelte'; export let data: PageData; @@ -49,6 +50,32 @@ let selectedDeployment: Models.Deployment = null; + let unsubscribe: { (): void }; + + onMount(() => { + unsubscribe = sdkForConsole.client.subscribe('console', async (response) => { + if (response.events.includes('functions.*.deployments.*')) { + if ($log.data && $log.data.$id === response.payload.deploymentId) { + $log.data = await sdkForProject.functions.getDeployment( + $func.$id, + $log.data.$id + ); + + await tick(); + + document.querySelector('.code-panel-content').scrollTop = + document.querySelector('.code-panel-content').scrollHeight; + } + } + }); + }); + + onDestroy(() => { + if (unsubscribe) { + unsubscribe(); + } + }); + const handleActivate = () => { invalidate(Dependencies.DEPLOYMENTS); }; diff --git a/src/routes/console/project-[project]/functions/function-[function]/create.svelte b/src/routes/console/project-[project]/functions/function-[function]/create.svelte index c8e2f9e089..567200b6e4 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/create.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/create.svelte @@ -1,5 +1,5 @@ + + diff --git a/src/routes/console/project-[project]/functions/function-[function]/domains/+page.ts b/src/routes/console/project-[project]/functions/function-[function]/domains/+page.ts new file mode 100644 index 0000000000..8eab30d26d --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/domains/+page.ts @@ -0,0 +1,16 @@ +import { Dependencies } from '$lib/constants'; +import { sdkForProject } from '$lib/stores/sdk'; +import { Query } from '@aw-labs/appwrite-console'; +import type { PageLoad } from './$types'; + +export const load: PageLoad = async ({ params, parent, depends }) => { + await parent(); + depends(Dependencies.RULES); + + return { + rules: await sdkForProject.proxy.listRules([ + Query.equal('resourceType', 'function'), + Query.equal('resourceId', params.function) + ]) + }; +}; diff --git a/src/routes/console/project-[project]/functions/function-[function]/domains/store.ts b/src/routes/console/project-[project]/functions/function-[function]/domains/store.ts new file mode 100644 index 0000000000..0dd72124bd --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/domains/store.ts @@ -0,0 +1,6 @@ +import { page } from '$app/stores'; +import { derived, writable, type Writable } from 'svelte/store'; +import type { Models } from '@aw-labs/appwrite-console'; + +export const func = derived(page, ($page) => $page.data.function as Models.Function); +export const execute: Writable = writable(); diff --git a/src/routes/console/project-[project]/functions/function-[function]/execute.svelte b/src/routes/console/project-[project]/functions/function-[function]/execute.svelte index 24f026f25c..eb37270667 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/execute.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/execute.svelte @@ -1,37 +1,45 @@ + + + +
      + {#if headers} + {#each headers as [key, value], index} +
    • +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
      + +
      +
    • + {/each} + {/if} +
    + diff --git a/src/routes/console/project-[project]/functions/function-[function]/executions/[[page]]/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/executions/[[page]]/+page.svelte index a85816e1bf..bbc6c1c89e 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/executions/[[page]]/+page.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/executions/[[page]]/+page.svelte @@ -54,8 +54,8 @@ Execution ID Created Status - Trigger - Duration + Trigger + Duration @@ -74,13 +74,16 @@ - {execution.status} + {execution.status} ({execution.statusCode}) {execution.trigger} + + {execution.method} + {calculateTime(execution.duration)} diff --git a/src/routes/console/project-[project]/functions/function-[function]/header.svelte b/src/routes/console/project-[project]/functions/function-[function]/header.svelte index d1ab37a1bd..ff9c1bc2d3 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/header.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/header.svelte @@ -16,6 +16,12 @@ event: 'deployments', hasChildren: true }, + { + href: `${path}/domains`, + title: 'Domains', + event: 'domains', + hasChildren: true + }, { href: `${path}/usage`, title: 'Usage', diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte index 9313c97a00..8ecdbc8435 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte @@ -1,13 +1,5 @@ @@ -341,6 +433,107 @@ + {#if vcsInstallationId} +
    + + Git Integration +

    SOME TEXT

    + +
      +

      Branch: {vcsBranch}

      +

      Silent mode: {vcsSilentMode ? 'yes' : 'no'}

      +

      Root directory: {vcsRootDirectory}

      +

      Repository: {data.installation.organization}/{data.repository.name}

      +
    +
    + + + +
    +
    + {:else} +
    (showGitConnection = true)}> + + Git Integration +

    SOME TEXT

    + +
      +

      (Some info about connecting to git)

      +
    +
    + + + +
    +
    + {/if} + +
    + + Update Deployment Settings +

    + These settings are used default values when creating a deployment. They can be + ovewritten when creating deployment. +

    + +
      + +
    +
      + +
    +
      + +
    +
    + + + +
    +
    + +
    + + Update Logging + + + + +

    + When logging is enabled, every execution response will be stored and can be + accessed later. When logging is disabed, no data is stored about executions. +

    +

    + Disabled logging can be useful when transfering privacy-critical data, or for + performance reasons. +

    +
    + + + +
    +
    +
    Execute Access @@ -453,120 +646,19 @@ - Update Function Variables -

    Set the variables (or secret keys) that will be passed to your function at runtime.

    + Update Function Environment Variables +

    + Set the environment variables (or secret keys) that will be passed to your function at + runtime and during build. +

    + -
    - - -
    - - - - - - - - - {#if data.variables.total} - {#each data.variables.variables as variable, i} - - - - - - {/each} - {/if} - -
    - Key - - Value - -
    - {variable.key} - -
    - {#if showVariablesValue[i]} - {variable.value} - {:else} - •••••••• - {/if} -
    - - - - -
    -
    -
    - - - - { - selectedVar = variable; - showVariablesDropdown[i] = false; - showVariablesModal = true; - }}> - Edit - - { - handleVariableDeleted(variable); - showVariablesDropdown[i] = false; - }}> - Delete - - - -
    -
    - -
    +
    @@ -592,12 +684,10 @@
    -{#if showVariablesModal} - -{/if} + + +{#if showGitConnection} + +{/if} diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.ts b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.ts index 897dbb0586..45f7676c40 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.ts +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.ts @@ -3,10 +3,21 @@ import { Dependencies } from '$lib/constants'; import type { PageLoad } from './$types'; export const load: PageLoad = async ({ params, parent, depends }) => { - await parent(); + const parentData = await parent(); + depends(Dependencies.FUNCTION); depends(Dependencies.VARIABLES); return { - variables: await sdkForProject.functions.listVariables(params.function) + variables: await sdkForProject.functions.listVariables(params.function), + installations: await sdkForProject.vcs.listInstallations(), + repository: parentData.function.vcsInstallationId + ? await sdkForProject.vcs.getRepository( + parentData.function.vcsInstallationId, + parentData.function.vcsRepositoryId + ) + : null, + installation: parentData.function.vcsInstallationId + ? await sdkForProject.vcs.getInstallation(parentData.function.vcsInstallationId) + : null }; }; diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/gitConnection.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/gitConnection.svelte new file mode 100644 index 0000000000..4458339ed8 --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/gitConnection.svelte @@ -0,0 +1,203 @@ + + + + Connect Git + + {#if selectedInstallation === null} +

    1. Select installation:

    + {#if installations.installations.length > 0} +
    + + + {#each installations.installations as installation (installation.$id)} + + + + + + {/each} + +
    + + + +
    +
    + {:else} + + goto( + `${base}/console/project-${$page.params.project}/settings/git-installations` + )}> +
    +
    +

    No installation found. Create one to continue.

    +
    +
    +
    + {/if} + {:else if !selectedRepository} +

    + 2. Select repository: + + + {#if repositories === null} +

    Loading...

    + {:else if repositories.repositories.length > 0} +
    + + + {#each repositories.repositories as repository (repository.id)} + + + + + + {/each} + +
    + + + +
    +
    + {:else} + +
    +
    +

    + No repository found. You might be missing permissions on your Git + provider. +

    +
    +
    +
    + {/if} +

    + {:else} +
    +

    3. Enter branch:

    + + +

    4. Enter root directory

    + + +

    5. Silent mode?

    + + + +
    + {/if} + + +
    diff --git a/src/routes/console/project-[project]/functions/wizard/step5.svelte b/src/routes/console/project-[project]/functions/wizard/step5.svelte index f3cf1c9aeb..c2f7095842 100644 --- a/src/routes/console/project-[project]/functions/wizard/step5.svelte +++ b/src/routes/console/project-[project]/functions/wizard/step5.svelte @@ -1,120 +1,46 @@ - Variables + Environment Variables - Create a variable (or secret key) that will be passed to your function at runtime. + Create an environment variable (or secret key) that will be passed to your function at + runtime and during build. - {#if $createFunction.vars.length} - - - Key - Value - - - - {#each $createFunction.vars as variable, i} - - - {variable.key} - - - - - - - - - { - selectedVar = $createFunction.vars[i]; - showDropdown[i] = false; - showCreate = true; - }}> - Edit - - { - $createFunction.vars.splice(i, 1); - $createFunction = $createFunction; - showDropdown[i] = false; - }}> - Delete - - - - - - {/each} - -
    -
    - -
    - {:else} - (showCreate = !showCreate)}>Create a variable to get started - {/if} +
    - -{#if showCreate} - -{/if} diff --git a/src/routes/console/project-[project]/settings/domains/+page.svelte b/src/routes/console/project-[project]/settings/domains/+page.svelte new file mode 100644 index 0000000000..42e0656fcc --- /dev/null +++ b/src/routes/console/project-[project]/settings/domains/+page.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/routes/console/project-[project]/settings/domains/+page.ts b/src/routes/console/project-[project]/settings/domains/+page.ts new file mode 100644 index 0000000000..c9449a1348 --- /dev/null +++ b/src/routes/console/project-[project]/settings/domains/+page.ts @@ -0,0 +1,13 @@ +import { Dependencies } from '$lib/constants'; +import { sdkForProject } from '$lib/stores/sdk'; +import { Query } from '@aw-labs/appwrite-console'; +import type { PageLoad } from './$types'; + +export const load: PageLoad = async ({ parent, depends }) => { + await parent(); + depends(Dependencies.RULES); + + return { + rules: await sdkForProject.proxy.listRules([Query.equal('resourceType', 'api')]) + }; +}; diff --git a/src/routes/console/project-[project]/settings/domains/[[page]]/+page.ts b/src/routes/console/project-[project]/settings/domains/[[page]]/+page.ts deleted file mode 100644 index 21650e7ce1..0000000000 --- a/src/routes/console/project-[project]/settings/domains/[[page]]/+page.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Dependencies } from '$lib/constants'; -import { sdkForConsole } from '$lib/stores/sdk'; -import type { PageLoad } from './$types'; - -export const load: PageLoad = async ({ params, parent, depends }) => { - await parent(); - depends(Dependencies.DOMAINS); - - return { - domains: await sdkForConsole.projects.listDomains(params.project) - }; -}; diff --git a/src/routes/console/project-[project]/settings/domains/wizard/step1.svelte b/src/routes/console/project-[project]/settings/domains/wizard/step1.svelte deleted file mode 100644 index ed800c177d..0000000000 --- a/src/routes/console/project-[project]/settings/domains/wizard/step1.svelte +++ /dev/null @@ -1,47 +0,0 @@ - - - - Add your domain - - Use your self-owned domain as the endpoint of your Appwrite API. - - - - - -
    -

    - You can find a list of domain providers and their DNS setting documentation here. If your domain provider isn't listed, please contact us, and we'll include their - settings as well. -

    -
    -
    diff --git a/src/routes/console/project-[project]/settings/domains/wizard/step4.svelte b/src/routes/console/project-[project]/settings/domains/wizard/step4.svelte deleted file mode 100644 index 0ab0e0b98b..0000000000 --- a/src/routes/console/project-[project]/settings/domains/wizard/step4.svelte +++ /dev/null @@ -1,53 +0,0 @@ - - - - Add a CNAME record - - In order to continue, set the following record on your DNS provider - - - - -
    - -
    -
    - {#if !certificate} -
    - {:else} -
    -
    -
    - diff --git a/src/routes/console/project-[project]/settings/domains/wizard/store.ts b/src/routes/console/project-[project]/settings/domains/wizard/store.ts deleted file mode 100644 index 9c2d5d8d44..0000000000 --- a/src/routes/console/project-[project]/settings/domains/wizard/store.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { Models } from '@aw-labs/appwrite-console'; -import { writable } from 'svelte/store'; - -export const domain = writable>({ $id: '', domain: '' }); diff --git a/src/routes/console/project-[project]/settings/git-installations/+page.svelte b/src/routes/console/project-[project]/settings/git-installations/+page.svelte new file mode 100644 index 0000000000..d4c8f0f454 --- /dev/null +++ b/src/routes/console/project-[project]/settings/git-installations/+page.svelte @@ -0,0 +1,122 @@ + + + +
    + Git Installations + + + + + + + {#each providers as provider} + { + provider.redirect(); + showCreateDropdown = false; + }}> + {provider.name} + + {/each} + + +
    + {#if data.installations.total} + + + Installation ID + Installation Organization + Provider + + + + {#each data.installations.installations as installation} + + + {installation.$id} + + + {installation.organization} + + {installation.provider} + +
    + + +
    +
    +
    + {/each} +
    +
    + {:else} + + {/if} +
    + + diff --git a/src/routes/console/project-[project]/settings/git-installations/+page.ts b/src/routes/console/project-[project]/settings/git-installations/+page.ts new file mode 100644 index 0000000000..ede7d3e711 --- /dev/null +++ b/src/routes/console/project-[project]/settings/git-installations/+page.ts @@ -0,0 +1,11 @@ +import { Dependencies } from '$lib/constants'; +import { sdkForProject } from '$lib/stores/sdk'; +import type { PageLoad } from './$types'; + +export const load: PageLoad = async ({ depends }) => { + depends(Dependencies.INSTALLATIONS); + + return { + installations: await sdkForProject.vcs.listInstallations() + }; +}; diff --git a/src/routes/console/project-[project]/settings/git-installations/delete.svelte b/src/routes/console/project-[project]/settings/git-installations/delete.svelte new file mode 100644 index 0000000000..b17cbf454c --- /dev/null +++ b/src/routes/console/project-[project]/settings/git-installations/delete.svelte @@ -0,0 +1,45 @@ + + + + Delete Installation + {#if selectedInstallation} +

    + Are you sure you want to delete {selectedInstallation.$id} from '{$project.name}'? +

    + {/if} + + + + +
    diff --git a/src/routes/console/project-[project]/settings/header.svelte b/src/routes/console/project-[project]/settings/header.svelte index b6c51f014b..fa189d1614 100644 --- a/src/routes/console/project-[project]/settings/header.svelte +++ b/src/routes/console/project-[project]/settings/header.svelte @@ -14,13 +14,23 @@ }, { href: `${path}/domains`, - title: 'Custom Domains', + title: 'Domains', event: 'domains' }, { href: `${path}/webhooks`, title: 'Webhooks', event: 'webhooks' + }, + { + href: `${path}/git-installations`, + title: 'Git Installations', + event: 'vcs' + }, + { + href: `${path}/variables`, + title: 'Global Variables', + event: 'globalVariables' } ]; diff --git a/src/routes/console/project-[project]/settings/variables/+page.svelte b/src/routes/console/project-[project]/settings/variables/+page.svelte new file mode 100644 index 0000000000..d84459f13a --- /dev/null +++ b/src/routes/console/project-[project]/settings/variables/+page.svelte @@ -0,0 +1,38 @@ + + + + + Update Global Environment Variables +

    Set the environment variables (or secret keys) that will be passed to all resources.

    + + + + +
    +
    diff --git a/src/routes/console/project-[project]/settings/variables/+page.ts b/src/routes/console/project-[project]/settings/variables/+page.ts new file mode 100644 index 0000000000..db6b04dd5d --- /dev/null +++ b/src/routes/console/project-[project]/settings/variables/+page.ts @@ -0,0 +1,12 @@ +import { Dependencies } from '$lib/constants'; +import { sdkForProject } from '$lib/stores/sdk'; +import type { PageLoad } from './$types'; + +export const load: PageLoad = async ({ parent, depends }) => { + await parent(); + depends(Dependencies.VARIABLES); + + return { + variables: await sdkForProject.project.listVariables() + }; +};