mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
feat: deploy to cloud & export to self-hosted
This commit is contained in:
@@ -39,11 +39,11 @@
|
||||
{ done: 0, processing: 0 } as TotalCounter
|
||||
);
|
||||
|
||||
console.log({ statusCounters, totalCounter });
|
||||
|
||||
return Math.round(
|
||||
const res = Math.round(
|
||||
(totalCounter.done / (totalCounter.done + totalCounter.processing)) * 100
|
||||
);
|
||||
|
||||
return Number.isNaN(res) ? 0 : res;
|
||||
})();
|
||||
|
||||
const fetchMigrations = debounce(async () => {
|
||||
|
||||
@@ -3,62 +3,112 @@
|
||||
import { InputSelect } from '$lib/elements/forms';
|
||||
import InputText from '$lib/elements/forms/inputText.svelte';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { Query, type Models, ID } from '@appwrite.io/console';
|
||||
import { selectedProject } from '.';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
|
||||
const projects = $page.data.allProjects as Models.ProjectList;
|
||||
const hasProjects = projects.total > 0;
|
||||
const organizations = $page.data.organizations
|
||||
.teams as Models.TeamList<Models.Preferences>['teams'];
|
||||
let selectedOrg = organizations.length ? organizations[0].$id : null;
|
||||
|
||||
let projects = [] as Models.ProjectList['projects'];
|
||||
$: hasProjects = projects.length > 0;
|
||||
let loadingProjects = false;
|
||||
|
||||
let projectType = 'existing';
|
||||
let newProjName = '';
|
||||
|
||||
async function getProjects(orgId: string | null) {
|
||||
if (!orgId) {
|
||||
projects = [];
|
||||
} else {
|
||||
loadingProjects = true;
|
||||
projects = await sdk.forConsole.projects
|
||||
.list([Query.equal('teamId', orgId), Query.orderDesc('$createdAt')])
|
||||
.then((res) => res.projects);
|
||||
projectType = projects.length ? 'existing' : 'new';
|
||||
loadingProjects = false;
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
getProjects(selectedOrg);
|
||||
}
|
||||
|
||||
const beforeSubmit = async () => {
|
||||
if (projectType === 'existing') return;
|
||||
const project = await sdk.forConsole.projects.create(ID.unique(), newProjName, selectedOrg);
|
||||
selectedProject.set(project.$id);
|
||||
};
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<WizardStep {beforeSubmit}>
|
||||
<svelte:fragment slot="title">
|
||||
{hasProjects ? 'Select project' : 'Create project'}
|
||||
</svelte:fragment>
|
||||
<div class="radios">
|
||||
<div class="u-flex u-gap-8">
|
||||
<input
|
||||
type="radio"
|
||||
name="project_type"
|
||||
id="project_type--existing"
|
||||
bind:group={projectType}
|
||||
value="existing" />
|
||||
<label for="project_type--existing">
|
||||
<p class="u-bold">Existing project</p>
|
||||
<p>Import data to an existing project</p>
|
||||
</label>
|
||||
</div>
|
||||
<div class="u-flex u-gap-8">
|
||||
<input
|
||||
type="radio"
|
||||
name="project_type"
|
||||
id="project_type--new"
|
||||
bind:group={projectType}
|
||||
value="new" />
|
||||
<label for="project_type--new">
|
||||
<p class="u-bold">Create new project</p>
|
||||
<span>Import data to a new project</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="u-margin-block-start-24">
|
||||
{#if projectType === 'existing'}
|
||||
<div class="u-flex u-flex-vertical u-gap-24">
|
||||
{#if organizations.length > 1}
|
||||
<InputSelect
|
||||
id="project"
|
||||
bind:value={$selectedProject}
|
||||
label="Select a project"
|
||||
options={projects.projects.map((p) => ({
|
||||
id="organization"
|
||||
bind:value={selectedOrg}
|
||||
label="Select organization"
|
||||
options={organizations.map((p) => ({
|
||||
label: p.name,
|
||||
value: p.$id
|
||||
}))} />
|
||||
{:else}
|
||||
<InputText
|
||||
label="Project name"
|
||||
placeholder="Enter project name"
|
||||
id="project_name"
|
||||
required />
|
||||
}))}
|
||||
disabled={loadingProjects} />
|
||||
{/if}
|
||||
|
||||
{#if selectedOrg && !loadingProjects}
|
||||
{#if projects.length}
|
||||
<div class="radios">
|
||||
<div class="u-flex u-gap-8">
|
||||
<input
|
||||
type="radio"
|
||||
name="project_type"
|
||||
id="project_type--existing"
|
||||
bind:group={projectType}
|
||||
value="existing" />
|
||||
<label for="project_type--existing">
|
||||
<p class="u-bold">Existing project</p>
|
||||
<p>Import data to an existing project</p>
|
||||
</label>
|
||||
</div>
|
||||
<div class="u-flex u-gap-8">
|
||||
<input
|
||||
type="radio"
|
||||
name="project_type"
|
||||
id="project_type--new"
|
||||
bind:group={projectType}
|
||||
value="new" />
|
||||
<label for="project_type--new">
|
||||
<p class="u-bold">Create new project</p>
|
||||
<span>Import data to a new project</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div>
|
||||
{#if projectType === 'existing'}
|
||||
<InputSelect
|
||||
id="project"
|
||||
bind:value={$selectedProject}
|
||||
label="Select a project"
|
||||
options={projects.map((p) => ({
|
||||
label: p.name,
|
||||
value: p.$id
|
||||
}))} />
|
||||
{:else}
|
||||
<InputText
|
||||
label="Project name"
|
||||
placeholder="Enter project name"
|
||||
id="project_name"
|
||||
bind:value={newProjName}
|
||||
required />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</WizardStep>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { goto, invalidate, invalidateAll } from '$app/navigation';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
|
||||
import Wizard from '$lib/layout/wizard.svelte';
|
||||
import { migrationFormToResources } from '$lib/stores/migration';
|
||||
import { getSdkForProject } from '$lib/stores/sdk';
|
||||
import { onDestroy } from 'svelte';
|
||||
import { formData, provider } from '.';
|
||||
import { formData, provider, selectedProject } from '.';
|
||||
import Step1 from './step1.svelte';
|
||||
import Step2 from './step2.svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
|
||||
const onExit = () => {
|
||||
formData.reset();
|
||||
@@ -19,23 +19,24 @@
|
||||
const resources = migrationFormToResources($formData);
|
||||
if ($provider.provider !== 'appwrite') return;
|
||||
|
||||
const res = await sdk.forProject.migrations.migrateAppwrite(
|
||||
await getSdkForProject($selectedProject).migrations.migrateAppwrite(
|
||||
resources,
|
||||
$provider.endpoint,
|
||||
$provider.projectID,
|
||||
$provider.apiKey
|
||||
);
|
||||
console.log('appwrite', res);
|
||||
invalidate(Dependencies.MIGRATIONS);
|
||||
|
||||
await invalidateAll();
|
||||
wizard.hide();
|
||||
|
||||
goto(`/console/project-${$selectedProject}/settings/migrations`);
|
||||
};
|
||||
|
||||
onDestroy(onExit);
|
||||
|
||||
const hasProjects = $page.data.allProjects.total > 0;
|
||||
|
||||
const steps: WizardStepsType = new Map();
|
||||
steps.set(1, {
|
||||
label: hasProjects ? 'Select project' : 'Create project',
|
||||
label: 'Select project',
|
||||
component: Step1
|
||||
});
|
||||
steps.set(2, {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import Header from './header.svelte';
|
||||
import Breadcrumbs from './breadcrumbs.svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import type { LayoutLoad } from './$types';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import type { LayoutLoad } from './$types';
|
||||
import Breadcrumbs from './breadcrumbs.svelte';
|
||||
import Header from './header.svelte';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
depends(Dependencies.ORGANIZATION);
|
||||
@@ -14,11 +13,7 @@ export const load: LayoutLoad = async ({ params, depends }) => {
|
||||
header: Header,
|
||||
breadcrumbs: Breadcrumbs,
|
||||
organization: await sdk.forConsole.teams.get(params.organization),
|
||||
members: await sdk.forConsole.teams.listMemberships(params.organization),
|
||||
allProjects: await sdk.forConsole.projects.list([
|
||||
Query.equal('teamId', params.organization),
|
||||
Query.orderDesc('$createdAt')
|
||||
])
|
||||
members: await sdk.forConsole.teams.listMemberships(params.organization)
|
||||
};
|
||||
} catch (e) {
|
||||
localStorage.removeItem('organization');
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { capitalize } from '$lib/helpers/string';
|
||||
import { Container } from '$lib/layout';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { isSelfHosted } from '$lib/system';
|
||||
import { isCloud, isSelfHosted } from '$lib/system';
|
||||
import { onMount } from 'svelte';
|
||||
import { openImportWizard } from './(import)';
|
||||
import Details from './details.svelte';
|
||||
@@ -59,13 +59,21 @@
|
||||
callback: openImportWizard,
|
||||
group: 'migrations'
|
||||
},
|
||||
{
|
||||
label: 'Export data',
|
||||
icon: 'upload',
|
||||
keys: ['e', 'd'],
|
||||
callback: () => (showExport = true),
|
||||
group: 'migrations'
|
||||
}
|
||||
isSelfHosted
|
||||
? {
|
||||
label: 'Deploy to cloud',
|
||||
icon: 'cloud',
|
||||
keys: ['d', 'c'],
|
||||
callback: deployToCloud,
|
||||
group: 'migrations'
|
||||
}
|
||||
: {
|
||||
label: 'Export data',
|
||||
icon: 'upload',
|
||||
keys: ['e', 'd'],
|
||||
callback: () => (showExport = true),
|
||||
group: 'migrations'
|
||||
}
|
||||
]);
|
||||
|
||||
$: $updateCommandGroupRanks((prev) => ({
|
||||
|
||||
Reference in New Issue
Block a user