Merge branch 'main' of github.com:appwrite/console into fix-qa-last-fixes

This commit is contained in:
Arman
2023-08-29 15:50:42 +02:00
49 changed files with 333 additions and 156 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ We would ❤️ for you to contribute to Appwrite and help make it better! We wa
## How to Start?
If you are worried about or dont know where to start, check out the next section that explains what kind of help is needed and how you can get involved. You can reach out with any questions on our [Discord](https://appwrite.io/discord) server. You can also submit an issue and a maintainer can guide you!
If you are worried about or don't know where to start, check out the next section that explains what kind of help is needed and how you can get involved. You can reach out with any questions on our [Discord](https://appwrite.io/discord) server. You can also submit an issue and a maintainer can guide you!
## Repo Structure
@@ -242,7 +242,7 @@ When blogging, speaking about, or creating tutorials about one of Appwrite's man
### Presenting at Meetups
Presenting at meetups and conferences about your Appwrite projects is another excellent way to get the word out about Appwrite. Your unique challenges and successes in building things with Appwrite can provide great speaking material. Wed love to review your talk abstract/CFP, so get in touch with us if youd like some help!
Presenting at meetups and conferences about your Appwrite projects is another excellent way to get the word out about Appwrite. Your unique challenges and successes in building things with Appwrite can provide great speaking material. We'd love to review your talk abstract/CFP, so get in touch with us if you'd like some help!
### Sending Feedback & Reporting Bugs
+1 -1
View File
@@ -31,7 +31,7 @@ Console 2.0 is designed to be accessible, from design to code. Console 2.0 is al
### Scalability and Collaboration
The new console is more maintainable and welcoming to community contributions. Console 2.0 is built using Svelte instead of our own library. Its better documented and well-known, making it easier for developers to contribute to Appwrite.
The new console is more maintainable and welcoming to community contributions. Console 2.0 is built using Svelte instead of our own library. It's better documented and well-known, making it easier for developers to contribute to Appwrite.
## Contributing
+7 -8
View File
@@ -8,7 +8,7 @@
"dependencies": {
"@analytics/google-analytics": "^1.0.5",
"@analytics/google-tag-manager": "^0.5.3",
"@appwrite.io/console": "npm:matej-appwrite-console@7.1.130",
"@appwrite.io/console": "^0.3.0",
"@appwrite.io/pink": "0.1.0-next.8",
"@appwrite.io/pink-icons": "^0.1.0-next.8",
"@popperjs/core": "^2.11.6",
@@ -169,10 +169,9 @@
"integrity": "sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg=="
},
"node_modules/@appwrite.io/console": {
"name": "matej-appwrite-console",
"version": "7.1.130",
"resolved": "https://registry.npmjs.org/matej-appwrite-console/-/matej-appwrite-console-7.1.130.tgz",
"integrity": "sha512-XsaGxuUNznKKiQpbYAy7VYtj5f0CitrMcIh+9UiHzI0dVXe4ck8humDv6l8XVFp0aQZWxc6RfiPuHo9oreEKuw==",
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.3.0.tgz",
"integrity": "sha512-XHKQHirzQliXoDpMLakSdXwpq9aPoeTABNhW8Z7MK3p6oBfp2gMplDD43Fbd91JREXoJ+RG8okX0z0nIc6hDiQ==",
"dependencies": {
"cross-fetch": "3.1.5",
"isomorphic-form-data": "2.0.0"
@@ -8985,9 +8984,9 @@
"integrity": "sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg=="
},
"@appwrite.io/console": {
"version": "npm:matej-appwrite-console@7.1.130",
"resolved": "https://registry.npmjs.org/matej-appwrite-console/-/matej-appwrite-console-7.1.130.tgz",
"integrity": "sha512-XsaGxuUNznKKiQpbYAy7VYtj5f0CitrMcIh+9UiHzI0dVXe4ck8humDv6l8XVFp0aQZWxc6RfiPuHo9oreEKuw==",
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.3.0.tgz",
"integrity": "sha512-XHKQHirzQliXoDpMLakSdXwpq9aPoeTABNhW8Z7MK3p6oBfp2gMplDD43Fbd91JREXoJ+RG8okX0z0nIc6hDiQ==",
"requires": {
"cross-fetch": "3.1.5",
"isomorphic-form-data": "2.0.0"
+1 -1
View File
@@ -20,7 +20,7 @@
"dependencies": {
"@analytics/google-analytics": "^1.0.5",
"@analytics/google-tag-manager": "^0.5.3",
"@appwrite.io/console": "npm:matej-appwrite-console@7.1.130",
"@appwrite.io/console": "^0.3.0",
"@appwrite.io/pink": "0.1.0-next.8",
"@appwrite.io/pink-icons": "^0.1.0-next.8",
"@popperjs/core": "^2.11.6",
+3 -1
View File
@@ -40,7 +40,9 @@ export enum Dependencies {
WEBHOOK = 'dependency:webhook',
WEBHOOKS = 'dependency:webhooks',
MIGRATIONS = 'dependency:migrations',
COLLECTIONS = 'dependency:collections'
COLLECTIONS = 'dependency:collections',
RUNTIMES = 'dependency:runtimes',
CONSOLE_VARIABLES = 'dependency:console_variables'
}
export const scopes: {
+2 -2
View File
@@ -1,6 +1,6 @@
export function debounce<F extends (...params: any[]) => void>(fn: F, delay: number) {
export function debounce<F extends (...params: unknown[]) => void>(fn: F, delay: number) {
let timeoutID: ReturnType<typeof setTimeout> = null;
const debounceFn = function (this: any, ...args: any[]) {
const debounceFn = function (this: unknown, ...args: unknown[]) {
clearTimeout(timeoutID);
timeoutID = window.setTimeout(() => fn.apply(this, args), delay) as unknown as ReturnType<
typeof setTimeout
+1 -1
View File
@@ -45,7 +45,7 @@ export function deepMap<T, U>(
return result;
}
export function parseIfString(value: unknown): any {
export function parseIfString(value: unknown): unknown {
if (typeof value === 'string') {
try {
return JSON.parse(value);
+1 -1
View File
@@ -1,5 +1,5 @@
export function getProjectId() {
const pathname = window.location.pathname;
const pathname = window.location.pathname + '/';
const projectMatch = pathname.match(/\/project-(.*?)\//);
return projectMatch?.[1] || null;
}
+1 -1
View File
@@ -9,7 +9,7 @@ import { deepClone, objectEntries } from './object';
*
* @export
*/
export function createConservative<Obj extends Record<string, any>>(obj: Obj) {
export function createConservative<Obj extends Record<string, unknown>>(obj: Obj) {
const stores = Object.fromEntries(
objectEntries(obj).map(([key, value]) => [key, writable(value)])
) as {
+9 -5
View File
@@ -9,6 +9,7 @@
import { onMount } from 'svelte';
import { ProxyTypes } from '../index.svelte';
import { domain, typeStore } from './store';
import { consoleVariables } from '$routes/console/store';
let error = null;
let isDomainsEnabled = false;
@@ -17,9 +18,8 @@
if (!isSelfHosted) {
return;
}
const vars = await sdk.forConsole.console.variables();
//@ts-expect-error needs an sdk release
isDomainsEnabled = vars?._APP_DOMAIN_ENABLED === true;
isDomainsEnabled = (await $consoleVariables)?._APP_DOMAIN_ENABLED === true;
});
async function createDomain() {
@@ -78,8 +78,12 @@
To add a domain to a locally hosted Appwrite project, you must first configure your server
domain.
<svelte:fragment slot="buttons">
<!-- TODO: add link to docs -->
<Button href="#/" external text>Learn more</Button>
<Button
href="https://appwrite.io/docs/environment-variables#vcs_(version_control_system)"
external
text>
Learn more
</Button>
</svelte:fragment>
</Alert>
{/if}
+83 -16
View File
@@ -1,4 +1,4 @@
export const marketplace = [
export const marketplace: MarketplaceTemplate[] = [
{
icon: 'icon-lightning-bolt',
id: 'starter',
@@ -9,7 +9,7 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Starter'],
runtimes: [
{
name: 'node-18.0',
@@ -66,13 +66,31 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['AI'],
runtimes: [
{
name: 'node-18.0',
commands: 'npm install',
entrypoint: 'src/main.js',
providerRootDirectory: 'node/prompt-chatgpt'
},
{
name: 'python-3.9',
commands: 'pip install -r requirements.txt',
entrypoint: 'src/main.py',
providerRootDirectory: 'python/prompt_chatgpt'
},
{
name: 'php-8.0',
commands: 'composer install',
entrypoint: 'src/index.php',
providerRootDirectory: 'php/prompt-chatgpt'
},
{
name: 'dart-2.17',
commands: 'dart pub get',
entrypoint: 'lib/main.dart',
providerRootDirectory: 'dart/prompt_chatgpt'
}
],
instructions: `For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/prompt-chatgpt">file</a>.`,
@@ -106,13 +124,19 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Messaging'],
runtimes: [
{
name: 'node-18.0',
commands: 'npm install && npm run setup',
entrypoint: 'src/main.js',
entrypoint: 'src/main.js && npm run setup',
providerRootDirectory: 'node/discord-command-bot'
},
{
name: 'python-3.9',
commands: 'pip install -r requirements.txt && python src/setup.py',
entrypoint: 'src/main.py',
providerRootDirectory: 'python/discord_command_bot'
}
],
instructions: `For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/discord-command-bot">file</a>.`,
@@ -139,7 +163,7 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['AI'],
runtimes: [
{
name: 'node-18.0',
@@ -173,13 +197,25 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['AI'],
runtimes: [
{
name: 'node-18.0',
commands: 'npm install',
entrypoint: 'src/main.js',
providerRootDirectory: 'node/censor-with-redact'
},
{
name: 'python-3.9',
commands: 'pip install -r requirements.txt',
entrypoint: 'src/main.py',
providerRootDirectory: 'python/censor_with_redact'
},
{
name: 'dart-2.17',
commands: 'dart pub get',
entrypoint: 'lib/main.dart',
providerRootDirectory: 'dart/censor_with_redact'
}
],
instructions: `For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/censor-with-redact">file</a>.`,
@@ -206,7 +242,7 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Utilities'],
runtimes: [
{
name: 'node-18.0',
@@ -232,7 +268,7 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Dev Tools'],
runtimes: [
{
name: 'node-18.0',
@@ -272,7 +308,7 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Utilities'],
runtimes: [
{
name: 'node-18.0',
@@ -314,6 +350,13 @@ export const marketplace = [
value: 'urls',
placeholder: 'urls',
required: false
},
{
name: 'SHORT_BASE_URL',
description: `The domain to use for the short URLs. You can use your functions subdomain or a custom domain.`,
value: '',
placeholder: 'https://shortdomain.io',
required: true
}
]
},
@@ -326,13 +369,25 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Databases'],
runtimes: [
{
name: 'node-18.0',
commands: 'npm install',
entrypoint: 'src/main.js',
providerRootDirectory: 'node/sync-with-algolia'
},
{
name: 'python-3.9',
commands: 'pip install -r requirements.txt',
entrypoint: 'src/main.py',
providerRootDirectory: 'python/sync_with_algolia'
},
{
name: 'php-8.0',
commands: 'composer install',
entrypoint: 'src/index.php',
providerRootDirectory: 'php/sync-with-algolia'
}
],
instructions: `For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/sync-with-algolia">file</a>.`,
@@ -369,7 +424,7 @@ export const marketplace = [
{
name: 'ALGOLIA_INDEX_ID',
description: `The ID of the index in Algolia where the documents are to be synced. <a class="u-bold" target="_blank" href="https://www.algolia.com/doc/api-client/methods/indexing/">Learn more</a>.`,
placeholder: 'appwrite_index',
placeholder: 'my_index',
required: true
},
{
@@ -396,7 +451,7 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Databases'],
runtimes: [
{
name: 'node-18.0',
@@ -472,7 +527,7 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Messaging'],
runtimes: [
{
name: 'node-18.0',
@@ -523,7 +578,7 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Messaging'],
runtimes: [
{
name: 'node-18.0',
@@ -574,13 +629,25 @@ export const marketplace = [
events: [],
cron: '',
timeout: 15,
usecases: ['placeholder'],
usecases: ['Utilities'],
runtimes: [
{
name: 'node-18.0',
commands: 'npm install',
entrypoint: 'src/main.js',
providerRootDirectory: 'node/email-contact-form'
},
{
name: 'python-3.9',
commands: 'pip install -r requirements.txt',
entrypoint: 'src/main.py',
providerRootDirectory: 'python/email_contact_form'
},
{
name: 'php-8.0',
commands: 'composer install',
entrypoint: 'src/index.php',
providerRootDirectory: 'php/email-contact-form'
}
],
instructions: `For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/email-contact-form">file</a>.`,
+28 -5
View File
@@ -2,7 +2,7 @@
import CreateTemplate from './createTemplate.svelte';
export function connectTemplate(template: MarketplaceTemplate, runtime: string | null = null) {
const variables: any = {};
const variables: Record<string, string> = {};
template.variables.forEach((variable) => {
variables[variable.name] = variable.value ?? '';
});
@@ -29,17 +29,19 @@
<script lang="ts">
import { base } from '$app/paths';
import { AvatarGroup, Box, Heading } from '$lib/components';
import WizardCover from '$lib/layout/wizardCover.svelte';
import { app } from '$lib/stores/app';
import { wizard } from '$lib/stores/wizard';
import { repository, runtimes, templateConfig, template as templateStore } from './store';
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 { runtimes } from '$routes/console/project-[project]/functions/store';
import { trackEvent } from '$lib/actions/analytics';
import type { Models } from '@appwrite.io/console';
import WizardCover from '$lib/layout/wizardCover.svelte';
import Repositories from './components/repositories.svelte';
import CreateManual from './createManual.svelte';
import CreateGit from './createGit.svelte';
import { Button } from '$lib/elements/forms';
import { page } from '$app/stores';
let hasInstallations: boolean;
let selectedRepository: string;
@@ -48,6 +50,9 @@
const templates = marketplace.filter((template) => template.id !== 'starter').slice(0, 2);
function connect(event: CustomEvent<Models.ProviderRepository>) {
trackEvent('click_connect_repository', {
from: 'cover'
});
repository.set(event.detail);
wizard.start(CreateGit);
}
@@ -109,6 +114,13 @@
)}
<li>
<button
on:click={() => {
trackEvent('click_connect_template', {
from: 'cover',
template: quickStart.id,
runtime: runtime.name
});
}}
on:click={() => connectTemplate(quickStart, runtime.name)}
class="box u-width-full-line u-flex u-cross-center u-gap-8"
style:--box-padding="1rem"
@@ -157,6 +169,12 @@
<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">
@@ -185,6 +203,11 @@
<p class="u-margin-block-start-16">
You can also create a function <button
class="link"
on:click={() => {
trackEvent('click_create_function_manual', {
from: 'cover'
});
}}
on:click={() => wizard.start(CreateManual)}>manually</button>
or using the CLI.
<a
@@ -4,7 +4,8 @@
import { InputText, InputSelect, FormList } from '$lib/elements/forms';
import { WizardStep } from '$lib/layout';
import { onMount } from 'svelte';
import { createFunction, runtimes } from '../store';
import { createFunction } from '../store';
import { runtimes } from '$routes/console/project-[project]/functions/store';
let showCustomId = false;
@@ -6,7 +6,8 @@
import { WizardStep } from '$lib/layout';
import { onMount } from 'svelte';
import { sdk } from '$lib/stores/sdk';
import { choices, createFunction, installation, repository, runtimes } from '../store';
import { choices, createFunction, installation, repository } from '../store';
import { runtimes } from '$routes/console/project-[project]/functions/store';
let showCustomId = false;
@@ -3,7 +3,8 @@
import { Pill } from '$lib/elements';
import { FormList, InputSelect, InputText } from '$lib/elements/forms';
import { WizardStep } from '$lib/layout';
import { runtimes, template, templateConfig } from '../store';
import { runtimes } from '$routes/console/project-[project]/functions/store';
import { template, templateConfig } from '../store';
let showCustomId = false;
-5
View File
@@ -33,11 +33,6 @@ export const installations = derived(
($page) => $page.data.installations as Models.InstallationList
);
export const runtimes = derived(
page,
($page) => $page.data.runtimes as Promise<Models.RuntimeList>
);
const initialCreateFunction: Partial<Models.Function> = {
$id: null,
name: null,
+1 -1
View File
@@ -25,7 +25,7 @@
onMount(async () => {
if ($page.url.searchParams.has('migrate')) {
const migrateData = $page.url.searchParams.get('migrate');
requestedMigration.set(parseIfString(migrateData));
requestedMigration.set(parseIfString(migrateData) as Record<string, string>);
}
/**
* Reporting Web Vitals.
@@ -15,6 +15,7 @@
resourcesToMigrationForm
} from '$lib/stores/migration';
import { wizard } from '$lib/stores/wizard';
import type { Models } from '@appwrite.io/console';
export let formData: ReturnType<typeof createMigrationFormStore>;
export let provider: ReturnType<typeof createMigrationProviderStore>;
@@ -76,7 +77,7 @@
$formData = resourcesToMigrationForm(resources, version);
}
let report: any;
let report: Models.MigrationReport;
$: version = report?.version || '0.0.0';
let isOpen = false;
@@ -86,18 +87,16 @@
isOpen = true;
try {
switch ($provider.provider) {
case 'appwrite': {
const res = await projectSdk.migrations.getAppwriteReport(
case 'appwrite':
report = await projectSdk.migrations.getAppwriteReport(
providerResources.appwrite,
$provider.endpoint,
$provider.projectID,
$provider.apiKey
);
report = res;
break;
}
case 'supabase': {
const res = await projectSdk.migrations.getSupabaseReport(
case 'supabase':
report = await projectSdk.migrations.getSupabaseReport(
providerResources.supabase,
$provider.endpoint,
$provider.apiKey,
@@ -106,31 +105,25 @@
$provider.password,
$provider.port
);
report = res;
break;
}
case 'firebase': {
case 'firebase':
if ($provider.projectId) {
// OAuth
const res = await sdk.forProject.migrations.getFirebaseReportOAuth(
report = await sdk.forProject.migrations.getFirebaseReportOAuth(
providerResources.firebase,
$provider.projectId
);
report = res;
} else if ($provider.serviceAccount) {
// Manual auth
const res = await projectSdk.migrations.getFirebaseReport(
report = await projectSdk.migrations.getFirebaseReport(
providerResources.firebase,
$provider.serviceAccount
);
report = res;
}
break;
}
case 'nhost': {
const res = await projectSdk.migrations.getNHostReport(
case 'nhost':
report = await projectSdk.migrations.getNHostReport(
providerResources.nhost,
$provider.subdomain,
$provider.region,
@@ -139,8 +132,6 @@
$provider.username,
$provider.password
);
report = res;
}
}
} catch (e) {
if (!isOpen) return;
@@ -7,6 +7,16 @@
</script>
<WizardStep>
<svelte:fragment slot="title">Select data</svelte:fragment>
<svelte:fragment slot="title">Select resources</svelte:fragment>
<svelte:fragment slot="subtitle">
Select the resources you need to migrate to Appwrite. Some resources can be migrated, but
with limitations. <a
class="link"
href="https://appwrite.io/docs/migrations"
target="_blank"
rel="noopener noreferrer">
Learn about which resources are supported</a
>.
</svelte:fragment>
<ResourceForm {provider} {formData} projectSdk={getSdkForProject($selectedProject)} />
</WizardStep>
+2 -3
View File
@@ -23,8 +23,8 @@
import { addNotification } from '$lib/stores/notifications';
import { openMigrationWizard } from './(migration-wizard)';
import { project } from './project-[project]/store';
import { sdk } from '$lib/stores/sdk';
import { feedback } from '$lib/stores/feedback';
import { consoleVariables } from './store';
function kebabToSentenceCase(str: string) {
return str
@@ -35,8 +35,7 @@
let isAssistantEnabled = false;
onMount(async () => {
const vars = await sdk.forConsole.console.variables();
isAssistantEnabled = vars._APP_ASSISTANT_ENABLED === true;
isAssistantEnabled = (await $consoleVariables)?._APP_ASSISTANT_ENABLED === true;
});
$: isOnSettingsLayout = $project?.$id
+6 -1
View File
@@ -1,8 +1,12 @@
import { Dependencies } from '$lib/constants';
import { sdk } from '$lib/stores/sdk';
import type { LayoutLoad } from './$types';
export const load: LayoutLoad = async ({ fetch }) => {
export const load: LayoutLoad = async ({ fetch, depends }) => {
depends(Dependencies.RUNTIMES);
depends(Dependencies.CONSOLE_VARIABLES);
const { endpoint, project } = sdk.forConsole.client.config;
const response = await fetch(`${endpoint}/health/version`, {
headers: {
@@ -12,6 +16,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
const data = await response.json();
return {
consoleVariables: sdk.forConsole.console.variables(),
version: data?.version ?? null
};
};
@@ -79,7 +79,7 @@
{:else if data.search}
<EmptySearch>
<div class="u-text-center">
<b>Sorry, we couldnt find {data.search}</b>
<b>Sorry, we couldn't find {data.search}'</b>
<p>There are no teams that match your search.</p>
</div>
<Button secondary href={`/console/project-${$page.params.project}/auth/teams`}>
@@ -95,7 +95,7 @@
{:else if data.search}
<EmptySearch>
<div class="u-text-center">
<b>Sorry, we couldnt find {data.search}</b>
<b>Sorry, we couldn't find {data.search}'</b>
<p>There are no members that match your search.</p>
</div>
<Button
@@ -73,7 +73,7 @@
};
$: operatorsForColumn = Object.entries(operators)
.filter(([_, v]) => v.types.includes(column?.type))
.filter(([, v]) => v.types.includes(column?.type))
.map(([k]) => ({
label: k,
value: k
@@ -76,7 +76,6 @@ export const queries = initQueries();
export const queriesAreDirty = derived([queries, page], ([$queries, $page]) => {
const paramQueries = $page.url.searchParams.get('query');
const parsedQueries = queryParamToMap(paramQueries || '[]');
console.log({ $queries, parsedQueries, notDirty: deepEqual($queries, parsedQueries) });
return !deepEqual($queries, parsedQueries);
});
@@ -1,9 +1,8 @@
import { Query, type Models } from '@appwrite.io/console';
import { Query } from '@appwrite.io/console';
import { sdk } from '$lib/stores/sdk';
import { getLimit, getPage, pageToOffset } from '$lib/helpers/load';
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
import type { PageLoad } from './$types';
import { isSelfHosted } from '$lib/system';
export const load: PageLoad = async ({ params, depends, url, route, parent }) => {
await parent();
@@ -11,10 +10,6 @@ export const load: PageLoad = async ({ params, depends, url, route, parent }) =>
const page = getPage(url);
const limit = getLimit(url, route, PAGE_LIMIT);
const offset = pageToOffset(page, limit);
let consoleVariables: Models.ConsoleVariables = null;
if (isSelfHosted) {
consoleVariables = await sdk.forConsole.console.variables();
}
return {
offset,
@@ -23,7 +18,6 @@ export const load: PageLoad = async ({ params, depends, url, route, parent }) =>
Query.limit(limit),
Query.offset(offset),
Query.orderDesc('')
]),
consoleVariables
])
};
};
@@ -80,12 +80,13 @@
required />
{#if $func.version !== 'v3'}
<Alert type="info">
<svelte:fragment slot="title"
>Build commands now available for functions v3.0</svelte:fragment>
<svelte:fragment slot="title">
Build commands now available for functions v3.0
</svelte:fragment>
Update your function version to make use of new features including build commands.
<svelte:fragment slot="buttons">
<!-- TODO: add link to docs -->
<Button href="#/" external text>Learn more</Button>
<Button href="https://appwrite.io/docs/functions-develop#upgrade" external text
>Learn more</Button>
</svelte:fragment>
</Alert>
{:else}
@@ -34,7 +34,7 @@
`functions.${$page.params.function}.deployments.${$page.params.deployment}.update`
)
) {
logs = (message.payload as any).logs as string;
logs = message.payload.buildLogs;
if (message.payload.status === 'ready') {
invalidate(Dependencies.DEPLOYMENT);
}
@@ -113,8 +113,9 @@
Update your function version to make use of new features including customizable HTTP
data in your executions.
<svelte:fragment slot="buttons">
<!-- TODO: add link to docs -->
<Button href="#/" external text>Learn more</Button>
<Button href="https://appwrite.io/docs/functions-develop#upgrade" external text>
Learn more
</Button>
</svelte:fragment>
</Alert>
<InputTextarea
@@ -47,11 +47,16 @@
<svelte:fragment slot="title">Your function is outdated</svelte:fragment>
Update your function version to make use of new features including build commands and HTTP
data in your executions. To update, follow the steps outlined in our
<!-- TODO: Add link to docs -->
<a href="#/" target="_blank" rel="noopener noreferrer" class="link">documentation</a>.
<a
href="https://appwrite.io/docs/functions-develop#upgrade"
target="_blank"
rel="noopener noreferrer"
class="link">documentation</a
>.
<svelte:fragment slot="buttons">
<!-- TODO: Add link to docs -->
<Button href="#/" external text>Learn more</Button>
<Button href="https://appwrite.io/docs/functions-develop#upgrade" external text>
Learn more
</Button>
</svelte:fragment>
</Alert>
{/if}
@@ -49,7 +49,7 @@
import InputSelectSearch from '$lib/elements/forms/inputSelectSearch.svelte';
import { installations } from '$lib/wizards/functions/store';
import { isSelfHosted } from '$lib/system';
import { consoleVariables } from '$lib/stores/consoleVariables';
import { consoleVariables, isVcsEnabled } from '$routes/console/store';
const functionId = $page.params.function;
@@ -172,8 +172,6 @@
selectedBranch !== $func?.providerBranch ||
silentMode !== $func?.providerSilentMode ||
selectedDir !== $func?.providerRootDirectory;
$: isVcsEnabled = $consoleVariables?._APP_VCS_ENABLED === true;
</script>
<Form onSubmit={updateConfiguration}>
@@ -282,7 +280,7 @@
</div>
</Box>
{:else}
{#if isSelfHosted && !isVcsEnabled}
{#if isSelfHosted && !isVcsEnabled($consoleVariables)}
<Alert class="common-section" type="info">
<svelte:fragment slot="title">
Installing Git to a self-hosted instance
@@ -290,8 +288,12 @@
When installing Git in a locally hosted Appwrite project, you must
first configure your environment variables.
<svelte:fragment slot="buttons">
<!-- TODO: add link to docs -->
<Button href="#/" external text>Learn more</Button>
<Button
href="https://appwrite.io/docs/environment-variables#vcs_(version_control_system)"
external
text>
Learn more
</Button>
</svelte:fragment>
</Alert>
{/if}
@@ -313,6 +315,7 @@
</div>
<Button
secondary
disabled={isSelfHosted && !isVcsEnabled}
on:click={() => wizard.start(ConnectExisting)}>
<span class="text">Connect Git</span>
</Button>
@@ -2,7 +2,7 @@ import { page } from '$app/stores';
import { derived } from 'svelte/store';
import type { Models } from '@appwrite.io/console';
export const consoleVariables = derived(
export const runtimes = derived(
page,
($page) => $page.data.consoleVariables as Models.ConsoleVariables
async ($page) => (await $page.data.runtimes) as Models.RuntimeList
);
@@ -4,12 +4,10 @@
import { Pill } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import { Container } from '$lib/layout';
import { consoleVariables } from '$lib/stores/consoleVariables';
import { isSelfHosted } from '$lib/system';
import { connectTemplate } from '$lib/wizards/functions/cover.svelte';
import { consoleVariables, isVcsEnabled } from '$routes/console/store';
import { template } from './store';
$: isVcsEnabled = $consoleVariables?._APP_VCS_ENABLED === true;
</script>
<Container>
@@ -62,7 +60,7 @@
</span>
</Heading>
<p class="u-margin-block-start-24">{$template.tagline}</p>
{#if isSelfHosted && !isVcsEnabled}
{#if isSelfHosted && !isVcsEnabled($consoleVariables)}
<Alert class="u-margin-block-start-24" type="info">
<svelte:fragment slot="title">
Cloning templates to a self-hosted instance
@@ -70,8 +68,12 @@
In order to clone a template to a locally hosted Appwrite project, you must set
up a Git integration and configure your environment variables.
<svelte:fragment slot="buttons">
<!-- TODO: add link to docs -->
<Button href="#/" external text>Learn more</Button>
<Button
href="https://appwrite.io/docs/environment-variables"
external
text>
Learn more
</Button>
</svelte:fragment>
</Alert>
{/if}
@@ -83,7 +85,10 @@
View source
<span class="icon-external-link" />
</Button>
<Button secondary on:click={() => connectTemplate($template)}>
<Button
disabled={isSelfHosted && !isVcsEnabled}
secondary
on:click={() => connectTemplate($template)}>
Create function
</Button>
</div>
@@ -5,7 +5,7 @@
import { WizardStep } from '$lib/layout';
import { onMount } from 'svelte';
import { createFunction } from './store';
import { runtimes } from '$lib/wizards/functions/store';
import { runtimes } from '../store';
let showCustomId = false;
@@ -20,8 +20,8 @@
</script>
<WizardStep>
<svelte:fragment slot="title">Create your function</svelte:fragment>
<svelte:fragment slot="subtitle">Let's create a function.</svelte:fragment>
<svelte:fragment slot="title">Configuration function</svelte:fragment>
<svelte:fragment slot="subtitle">Create your new Appwrite Function.</svelte:fragment>
<FormList>
<InputText
label="Name"
@@ -5,15 +5,15 @@
</script>
<WizardStep>
<svelte:fragment slot="title">Execute access</svelte:fragment>
<svelte:fragment slot="title">Permissions</svelte:fragment>
<svelte:fragment slot="subtitle">
Choose who can execute this function using the client API. For more information, check out
the <a
Choose which users have permission to execute this function using Client SDKs. For more
information, check out the <a
href="https://appwrite.io/docs/permissions"
target="_blank"
rel="noopener noreferrer"
class="link">
Permissions guide
permissions documentation
</a>.
</svelte:fragment>
@@ -19,7 +19,13 @@
<WizardStep>
<svelte:fragment slot="title">Events</svelte:fragment>
<svelte:fragment slot="subtitle">
Set the events that will trigger your function. Maximum 100 events allowed.
Set the events that will trigger your function. Maximum 100 events allowed.<a
href="https://appwrite.io/docs/events"
target="_blank"
rel="noopener noreferrer"
class="link">
Learn more about events.
</a>.
</svelte:fragment>
{#if $createFunction?.events?.length}
@@ -45,7 +45,13 @@
<WizardStep>
<svelte:fragment slot="title">Variables</svelte:fragment>
<svelte:fragment slot="subtitle">
Create the environment variables or secret keys that will be passed to your function
Create the environment variables or secret keys that will be passed to your function. <a
href="https://appwrite.io/docs/permissions"
target="_blank"
rel="noopener noreferrer"
class="link">
permissions documentation
</a>.
</svelte:fragment>
{#if $createFunction.vars.length}
<Table noStyles>
@@ -12,9 +12,13 @@
export let showEditor = false;
export let variableList: Models.VariableList;
export let sdkCreateVariable: (key: string, value: string) => Promise<any>;
export let sdkUpdateVariable: (variableId: string, key: string, value: string) => Promise<any>;
export let sdkDeleteVariable: (variableId: string) => Promise<any>;
export let sdkCreateVariable: (key: string, value: string) => Promise<unknown>;
export let sdkUpdateVariable: (
variableId: string,
key: string,
value: string
) => Promise<unknown>;
export let sdkDeleteVariable: (variableId: string) => Promise<unknown>;
let error = '';
let envCode = variableList.variables
@@ -1,18 +1,13 @@
import { Dependencies, PAGE_LIMIT } from '$lib/constants';
import { sdk } from '$lib/stores/sdk';
import { Query, type Models } from '@appwrite.io/console';
import { Query } from '@appwrite.io/console';
import type { PageLoad } from './$types';
import { isSelfHosted } from '$lib/system';
export const load: PageLoad = async ({ depends, url }) => {
depends(Dependencies.PROJECT_VARIABLES);
depends(Dependencies.PROJECT_INSTALLATIONS);
const limit = PAGE_LIMIT;
const offset = Number(url.searchParams.get('offset') ?? 0);
let consoleVariables: Models.ConsoleVariables = null;
if (isSelfHosted) {
consoleVariables = await sdk.forConsole.console.variables();
}
return {
limit,
@@ -21,7 +16,6 @@ export const load: PageLoad = async ({ depends, url }) => {
installations: await sdk.forProject.vcs.listInstallations([
Query.limit(limit),
Query.offset(offset)
]),
consoleVariables
])
};
};
@@ -52,7 +52,16 @@
</script>
<WizardStep>
<svelte:fragment slot="title">Choose provider</svelte:fragment>
<svelte:fragment slot="title">Select source</svelte:fragment>
<svelte:fragment slot="subtitle">
Select a source platform with the project you want to migrate. <a
class="link"
href="https://appwrite.io/docs/migrations"
target="_blank"
rel="noopener noreferrer">
Learn about which platforms are supported</a
>.
</svelte:fragment>
<div class="u-flex u-flex-vertical u-gap-8">
{#each Object.entries(providers) as [key, value]}
<label class="u-flex u-cross-center u-cursor-pointer u-gap-8">
@@ -7,6 +7,16 @@
</script>
<WizardStep>
<svelte:fragment slot="title">Select data</svelte:fragment>
<svelte:fragment slot="title">Select source</svelte:fragment>
<svelte:fragment slot="subtitle">
Select the resources you need to migrate to Appwrite. Some resources can be migrated, but
with limitations. <a
class="link"
href="https://appwrite.io/docs/migrations"
target="_blank"
rel="noopener noreferrer">
Learn about which resources are supported</a
>.
</svelte:fragment>
<ResourceForm {formData} {provider} projectSdk={sdk.forProject} />
</WizardStep>
@@ -140,7 +140,15 @@
<CardGrid>
<Heading tag="h3" size="7">Import project data</Heading>
<p class="text">Import data from other products or from a different Appwrite instance</p>
<p class="text">
Import data from another platform or from a different Appwrite instance. <a
class="link"
href="https://appwrite.io/docs/migrations"
target="_blank"
rel="noopener noreferrer">
Learn about which platforms are supported</a
>.
</p>
<svelte:fragment slot="aside">
{#if data.migrations.length}
<div class="u-flex">
@@ -224,7 +232,14 @@
{#if isSelfHosted}
<CardGrid>
<Heading tag="h3" size="7">Deploy to Cloud</Heading>
<p class="text">Export data from your project to Appwrite Cloud</p>
<p class="text">
Export data from your project to Appwrite Cloud. <a
class="link"
href="https://appwrite.io/docs/migrations-local-to-cloud"
target="_blank"
rel="noopener noreferrer">
Learn more in our documentation.</a>
</p>
<svelte:fragment slot="aside">
<div class="import-box">
<div class="u-flex u-cross-center u-gap-8">
@@ -244,7 +259,14 @@
{:else}
<CardGrid>
<Heading tag="h3" size="7">Export to self-hosted instance</Heading>
<p class="text">Export data from your project to a self-hosted instance</p>
<p class="text">
Export data from your project to a self-hosted instance. <a
class="link"
href="https://appwrite.io/docs/migrations-cloud-to-local"
target="_blank"
rel="noopener noreferrer">
Learn more in our documentation.</a>
</p>
<svelte:fragment slot="aside">
<div class="import-box">
<div class="u-flex u-cross-center u-gap-8">
@@ -29,7 +29,7 @@
import GitDisconnectModal from './GitDisconnectModal.svelte';
import dayjs from 'dayjs';
import { isSelfHosted } from '$lib/system';
import { consoleVariables } from '$lib/stores/consoleVariables';
import { consoleVariables, isVcsEnabled } from '$routes/console/store';
export let total: number;
export let limit: number;
@@ -76,8 +76,6 @@
noScroll: true
});
}
$: isVcsEnabled = $consoleVariables?._APP_VCS_ENABLED === true;
</script>
<CardGrid>
@@ -181,7 +179,7 @@
bind:offset />
</div>
{:else}
{#if isSelfHosted && !isVcsEnabled}
{#if isSelfHosted && !isVcsEnabled($consoleVariables)}
<Alert type="info">
<svelte:fragment slot="title">
Installing Git to a self-hosted instance
@@ -189,8 +187,12 @@
When installing Git in a locally hosted Appwrite project, you must first configure
your environment variables.
<svelte:fragment slot="buttons">
<!-- TODO: add link to docs -->
<Button href="#/" external text>Learn more</Button>
<Button
href="https://appwrite.io/docs/environment-variables#vcs_(version_control_system)"
external
text>
Learn more
</Button>
</svelte:fragment>
</Alert>
{/if}
@@ -202,7 +204,10 @@
<div class="avatar"><SvgIcon name="appwrite" type="color" size={80} /></div>
</div>
<Button on:click={() => (showGitIstall = true)} secondary>
<Button
disabled={isSelfHosted && !isVcsEnabled($consoleVariables)}
on:click={() => (showGitIstall = true)}
secondary>
<span class="text">Add Installation</span>
</Button>
</div>
@@ -200,7 +200,7 @@
{:else if data.search}
<EmptySearch>
<div class="u-text-center">
<b>Sorry, we couldnt find {data.search}</b>
<b>Sorry, we couldn't find {data.search}'</b>
<p>There are no files that match your search.</p>
</div>
<div class="u-flex u-gap-16">
@@ -4,7 +4,6 @@ import type { BarSeriesOption } from 'echarts/charts';
import { derived, writable } from 'svelte/store';
export const project = derived(page, ($page) => $page.data.project as Models.Project);
export const onboarding = derived(
project,
($project) => $project?.platforms?.length === 0 && $project?.keys?.length === 0
@@ -37,9 +37,13 @@
export let globalVariableList: Models.VariableList | undefined = undefined;
export let isGlobal: boolean;
export let sdkCreateVariable: (key: string, value: string) => Promise<any>;
export let sdkUpdateVariable: (variableId: string, key: string, value: string) => Promise<any>;
export let sdkDeleteVariable: (variableId: string) => Promise<any>;
export let sdkCreateVariable: (key: string, value: string) => Promise<unknown>;
export let sdkUpdateVariable: (
variableId: string,
key: string,
value: string
) => Promise<unknown>;
export let sdkDeleteVariable: (variableId: string) => Promise<unknown>;
let showVariablesDropdown = [];
let selectedVar: Models.Variable = null;
@@ -9,8 +9,12 @@
export let isGlobal: boolean;
export let show = false;
export let variableList: Models.VariableList;
export let sdkCreateVariable: (key: string, value: string) => Promise<any>;
export let sdkUpdateVariable: (variableId: string, key: string, value: string) => Promise<any>;
export let sdkCreateVariable: (key: string, value: string) => Promise<unknown>;
export let sdkUpdateVariable: (
variableId: string,
key: string,
value: string
) => Promise<unknown>;
let files: FileList;
let error: string;
+8
View File
@@ -1,4 +1,12 @@
import { page } from '$app/stores';
import type { Models } from '@appwrite.io/console';
import { derived } from 'svelte/store';
export const version = derived(page, ($page) => $page.data.version as string | null);
export const consoleVariables = derived(
page,
async ($page) => (await $page.data.consoleVariables) as Models.ConsoleVariables
);
export async function isVcsEnabled(store: Promise<Models.ConsoleVariables>) {
return (await store)?._APP_VCS_ENABLED === true;
}
+1 -1
View File
@@ -7,4 +7,4 @@ export const loading = writable(true);
export const organizations = derived(page, ($page) => {
return $page.data.organizations as Models.TeamList<Models.Preferences>;
});
export const requestedMigration = writable<Record<string, any> | null>(null);
export const requestedMigration = writable<Record<string, string> | null>(null);