mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge branch 'ui-fixes' into fix-destructive-action-color
This commit is contained in:
+3
-1
@@ -34,7 +34,9 @@ export default ts.config(
|
||||
'svelte/no-reactive-reassign': 'off',
|
||||
'svelte/no-reactive-literals': 'off',
|
||||
// TODO: @itznotabug, this requires a big refactor!
|
||||
'svelte/no-navigation-without-resolve': 'off'
|
||||
'svelte/no-navigation-without-resolve': 'off',
|
||||
'svelte/prefer-svelte-reactivity': 'off',
|
||||
'svelte/prefer-writable-derived': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ai-sdk/svelte": "^1.1.24",
|
||||
"@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@636ed39",
|
||||
"@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752",
|
||||
"@appwrite.io/pink-icons": "0.25.0",
|
||||
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@8f82877",
|
||||
"@appwrite.io/pink-legacy": "^1.0.3",
|
||||
|
||||
Generated
+6
-6
@@ -12,8 +12,8 @@ importers:
|
||||
specifier: ^1.1.24
|
||||
version: 1.1.24(svelte@5.39.11)(zod@4.1.12)
|
||||
'@appwrite.io/console':
|
||||
specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@636ed39
|
||||
version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@636ed39
|
||||
specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752
|
||||
version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752
|
||||
'@appwrite.io/pink-icons':
|
||||
specifier: 0.25.0
|
||||
version: 0.25.0
|
||||
@@ -272,8 +272,8 @@ packages:
|
||||
'@analytics/type-utils@0.6.4':
|
||||
resolution: {integrity: sha512-Ou1gQxFakOWLcPnbFVsrPb8g1wLLUZYYJXDPjHkG07+5mustGs5yqACx42UAu4A6NszNN6Z5gGxhyH45zPWRxw==}
|
||||
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@636ed39':
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@636ed39}
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752':
|
||||
resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752}
|
||||
version: 1.10.0
|
||||
|
||||
'@appwrite.io/pink-icons-svelte@2.0.0-RC.1':
|
||||
@@ -3710,7 +3710,7 @@ snapshots:
|
||||
|
||||
'@analytics/type-utils@0.6.4': {}
|
||||
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@636ed39': {}
|
||||
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2752': {}
|
||||
|
||||
'@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.39.11)':
|
||||
dependencies:
|
||||
@@ -4664,7 +4664,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@sentry/browser': 8.55.0
|
||||
'@sentry/core': 8.55.0
|
||||
magic-string: 0.30.7
|
||||
magic-string: 0.30.19
|
||||
svelte: 5.39.11
|
||||
|
||||
'@sentry/sveltekit@8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0)(@sveltejs/kit@2.46.4(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2)))(svelte@5.39.11)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.93.2))':
|
||||
|
||||
@@ -271,7 +271,7 @@
|
||||
|
||||
{#key derivedKey}
|
||||
<div use:melt={$menubar}>
|
||||
{#if !$isSmallViewport}
|
||||
{#if !$isSmallViewport && resolvedProfile.showOrgInBreadcrumbs}
|
||||
<span class="breadcrumb-separator">/</span>
|
||||
<button
|
||||
type="button"
|
||||
@@ -288,7 +288,7 @@
|
||||
{/if}</span>
|
||||
<Icon icon={IconChevronDown} size="s" color="--fgcolor-neutral-secondary" />
|
||||
</button>
|
||||
{:else}
|
||||
{:else if resolvedProfile.showOrgInBreadcrumbs}
|
||||
<button
|
||||
type="button"
|
||||
class="trigger"
|
||||
@@ -461,7 +461,11 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<BottomSheet.Menu bind:isOpen={organisationBottomSheetOpen} menu={organizationsBottomSheet} />
|
||||
{#if resolvedProfile.showOrgInBreadcrumbs}
|
||||
<BottomSheet.Menu
|
||||
bind:isOpen={organisationBottomSheetOpen}
|
||||
menu={organizationsBottomSheet} />
|
||||
{/if}
|
||||
|
||||
{#await projectsBottomSheet then menu}
|
||||
{#if menu}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
import {
|
||||
IconChevronRight,
|
||||
IconCreditCard,
|
||||
IconGlobe,
|
||||
IconGlobeAlt,
|
||||
IconLogoutRight,
|
||||
IconMenuAlt4,
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
link: 'https://appwrite.io/discord',
|
||||
description: 'Get support from our community through Discord'
|
||||
},
|
||||
...(resolvedProfile.showGithubIssueSupport
|
||||
...(!resolvedProfile.showGithubIssueSupport
|
||||
? []
|
||||
: [
|
||||
{
|
||||
|
||||
@@ -65,11 +65,10 @@ export async function gzipUpload(files: FileList) {
|
||||
data: f.buffer
|
||||
}))
|
||||
);
|
||||
const blob = new Blob([tar], { type: 'application/gzip' });
|
||||
const file = new File([blob], 'deployment.tar.gz', {
|
||||
const blob = new Blob([new Uint8Array(tar)], { type: 'application/gzip' });
|
||||
uploadFile = new File([blob], 'deployment.tar.gz', {
|
||||
type: 'application/gzip'
|
||||
});
|
||||
uploadFile = file;
|
||||
} catch (e) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import { isSmallViewport } from '$lib/stores/viewport';
|
||||
import { page } from '$app/state';
|
||||
import { resolvedProfile } from '$lib/profiles/index.svelte.ts';
|
||||
import { resolvedProfile } from '$lib/profiles/index.svelte';
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ export type Profile = {
|
||||
showExtendedAccountsMenu: boolean;
|
||||
showGeneralAvailability: boolean;
|
||||
showConnectProjectOnToolbar: boolean;
|
||||
showOrgInBreadcrumbs: boolean;
|
||||
minimalOrgHeader: boolean;
|
||||
getProjectRoute: (params: { region: string; project: string }) => ResolvedPathname;
|
||||
};
|
||||
|
||||
@@ -42,6 +44,8 @@ export const base: Profile = {
|
||||
showExtendedAccountsMenu: false,
|
||||
showGeneralAvailability: true,
|
||||
showConnectProjectOnToolbar: true,
|
||||
showOrgInBreadcrumbs: true,
|
||||
minimalOrgHeader: false,
|
||||
getProjectRoute({ region, project }) {
|
||||
return resolve(`/(console)/project-[region]-[project]/overview`, {
|
||||
region,
|
||||
@@ -66,6 +70,8 @@ export const studio: Profile = {
|
||||
showExtendedAccountsMenu: true,
|
||||
showGeneralAvailability: false,
|
||||
showConnectProjectOnToolbar: false,
|
||||
showOrgInBreadcrumbs: false,
|
||||
minimalOrgHeader: true,
|
||||
getProjectRoute({ region, project }) {
|
||||
return resolve(`/(console)/project-[region]-[project]/(studio)/studio`, {
|
||||
region,
|
||||
|
||||
@@ -17,6 +17,7 @@ const CDN_URL =
|
||||
const DEV_OVERRIDE_WEB_COMPONENTS = env?.PUBLIC_AI_OVERRIDE_WEB_COMPONENTS === 'true';
|
||||
|
||||
let component: HTMLElement | null = null;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let webComponentsModule: Record<string, any> | null = null;
|
||||
let configInitialized = false;
|
||||
let routingInitialized = false;
|
||||
@@ -119,6 +120,7 @@ export async function getWebComponents() {
|
||||
/**
|
||||
* Navigate to a route in the web components
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export async function navigateToRoute(...args: any[]) {
|
||||
try {
|
||||
const { navigateToRoute: navigate } = await getWebComponents();
|
||||
|
||||
@@ -6,12 +6,28 @@ import { isOrganization, tierToPlan } from '$lib/stores/billing';
|
||||
import { ID, Query, type Models } from '@appwrite.io/console';
|
||||
import { BillingPlan } from '$lib/constants';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import { base } from '$app/paths';
|
||||
import { base, resolve } from '$app/paths';
|
||||
import { resolvedProfile } from '$lib/profiles/index.svelte';
|
||||
|
||||
// TODO: this needs to be cleaned up!
|
||||
export const load: PageLoad = async ({ parent }) => {
|
||||
const { account, organizations } = await parent();
|
||||
|
||||
const firstOrganization = organizations?.teams[0]?.$id;
|
||||
|
||||
if (!resolvedProfile.showOnboarding) {
|
||||
if (!organizations?.total) {
|
||||
redirect(303, resolve('/(console)/create-organization'));
|
||||
} else {
|
||||
redirect(
|
||||
303,
|
||||
resolve('/(console)/organization-[organization]', {
|
||||
organization: firstOrganization
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const accountPrefs = account.prefs;
|
||||
const hasCompletedOnboarding = accountPrefs['newOnboardingCompleted'] ?? false;
|
||||
|
||||
@@ -19,7 +35,7 @@ export const load: PageLoad = async ({ parent }) => {
|
||||
if (hasCompletedOnboarding && !organizations?.total) {
|
||||
redirect(303, `${base}/onboarding/create-organization`);
|
||||
} else if (hasCompletedOnboarding && organizations?.total) {
|
||||
redirect(303, `${base}/organization-${organizations.teams[0].$id}`);
|
||||
redirect(303, `${base}/organization-${firstOrganization}`);
|
||||
}
|
||||
|
||||
if (!organizations?.total) {
|
||||
|
||||
@@ -14,7 +14,6 @@ import { defaultRoles, defaultScopes } from '$lib/constants';
|
||||
import type { Plan } from '$lib/sdk/billing';
|
||||
import { loadAvailableRegions } from '$routes/(console)/regions';
|
||||
import type { Organization } from '$lib/stores/organization';
|
||||
import { resolvedProfile } from '$lib/profiles/index.svelte';
|
||||
|
||||
export const load: LayoutLoad = async ({ params, depends, parent }) => {
|
||||
const { preferences: prefs } = await parent();
|
||||
@@ -52,10 +51,8 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => {
|
||||
loadAvailableRegions(params.organization)
|
||||
]);
|
||||
|
||||
const header = resolvedProfile.id === 'studio' ? undefined : Header;
|
||||
|
||||
return {
|
||||
header,
|
||||
header: Header,
|
||||
breadcrumbs: Breadcrumbs,
|
||||
organization,
|
||||
currentPlan,
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
import { GRACE_PERIOD_OVERRIDE, isCloud } from '$lib/system';
|
||||
import { IconGithub, IconPlus } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Badge, Icon, Layout, Tooltip, Typography } from '@appwrite.io/pink-svelte';
|
||||
import { resolvedProfile } from '$lib/profiles/index.svelte';
|
||||
|
||||
let areMembersLimited: boolean = $state(false);
|
||||
|
||||
@@ -88,33 +89,44 @@
|
||||
);
|
||||
|
||||
const avatars = $derived($members.memberships?.map((m) => m.userName || m.userEmail) ?? []);
|
||||
|
||||
const titleName = $derived(resolvedProfile.minimalOrgHeader ? 'Billing' : organization?.name);
|
||||
|
||||
const blockSize = $derived(resolvedProfile.minimalOrgHeader ? 'unset' : '152px');
|
||||
|
||||
const shouldShowCover = $derived(resolvedProfile.minimalOrgHeader ? true : organization.$id);
|
||||
</script>
|
||||
|
||||
{#if organization?.$id}
|
||||
<Cover>
|
||||
{#if shouldShowCover}
|
||||
<Cover blocksize={blockSize}>
|
||||
<svelte:fragment slot="header">
|
||||
<span class="u-flex u-cross-center u-gap-8 u-min-width-0">
|
||||
<Typography.Title color="--fgcolor-neutral-primary" size="xl" truncate>
|
||||
{organization.name}
|
||||
{titleName}
|
||||
</Typography.Title>
|
||||
{#if isCloud && organization?.billingPlan === BillingPlan.GITHUB_EDUCATION}
|
||||
<Badge variant="secondary" content="Education">
|
||||
<Icon icon={IconGithub} size="s" slot="start" />
|
||||
</Badge>
|
||||
{:else if isCloud && organization?.billingPlan === BillingPlan.FREE}
|
||||
<Badge variant="secondary" content="Free"></Badge>
|
||||
{/if}
|
||||
{#if isCloud && organization?.billingTrialStartDate && $daysLeftInTrial > 0 && organization.billingPlan !== BillingPlan.FREE && $plansInfo.get(organization.billingPlan)?.trialDays}
|
||||
<Tooltip>
|
||||
<Badge variant="secondary" content="Trial" />
|
||||
<svelte:fragment slot="tooltip">
|
||||
{`Your trial ends on ${toLocaleDate(
|
||||
organization.billingStartDate
|
||||
)}. ${$daysLeftInTrial} days remaining.`}
|
||||
</svelte:fragment>
|
||||
</Tooltip>
|
||||
|
||||
{#if !resolvedProfile.minimalOrgHeader}
|
||||
{#if isCloud && organization?.billingPlan === BillingPlan.GITHUB_EDUCATION}
|
||||
<Badge variant="secondary" content="Education">
|
||||
<Icon icon={IconGithub} size="s" slot="start" />
|
||||
</Badge>
|
||||
{:else if isCloud && organization?.billingPlan === BillingPlan.FREE}
|
||||
<Badge variant="secondary" content="Free"></Badge>
|
||||
{/if}
|
||||
|
||||
{#if isCloud && organization?.billingTrialStartDate && $daysLeftInTrial > 0 && organization.billingPlan !== BillingPlan.FREE && $plansInfo.get(organization.billingPlan)?.trialDays}
|
||||
<Tooltip>
|
||||
<Badge variant="secondary" content="Trial" />
|
||||
<svelte:fragment slot="tooltip">
|
||||
{`Your trial ends on ${toLocaleDate(
|
||||
organization.billingStartDate
|
||||
)}. ${$daysLeftInTrial} days remaining.`}
|
||||
</svelte:fragment>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
<div class="u-margin-inline-start-auto">
|
||||
<Layout.Stack direction="row" alignItems="center" gap="xl">
|
||||
{#if $members.total > 1}
|
||||
@@ -123,7 +135,7 @@
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
{#if $isOwner}
|
||||
{#if $isOwner && !resolvedProfile.minimalOrgHeader}
|
||||
<Tooltip disabled={!areMembersLimited} placement="bottom-end">
|
||||
<div>
|
||||
<Button
|
||||
@@ -147,15 +159,18 @@
|
||||
</Layout.Stack>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<Tabs>
|
||||
{#each tabs as tab}
|
||||
<Tab
|
||||
href={tab.href}
|
||||
selected={isTabSelected(tab, page.url.pathname, path, tabs)}
|
||||
event={tab.event}>
|
||||
{tab.title}
|
||||
</Tab>
|
||||
{/each}
|
||||
</Tabs>
|
||||
|
||||
{#if !resolvedProfile.minimalOrgHeader}
|
||||
<Tabs>
|
||||
{#each tabs as tab}
|
||||
<Tab
|
||||
href={tab.href}
|
||||
selected={isTabSelected(tab, page.url.pathname, path, tabs)}
|
||||
event={tab.event}>
|
||||
{tab.title}
|
||||
</Tab>
|
||||
{/each}
|
||||
</Tabs>
|
||||
{/if}
|
||||
</Cover>
|
||||
{/if}
|
||||
|
||||
@@ -319,8 +319,11 @@
|
||||
organization={data.organization}
|
||||
currentPlan={$currentPlan} />
|
||||
</Container>
|
||||
|
||||
<CreateOrganization bind:show={addOrganization} />
|
||||
|
||||
<CreateProject bind:show={showCreate} teamId={page.params.organization} />
|
||||
|
||||
<CreateProjectCloud
|
||||
projects={data.projects.total}
|
||||
bind:showCreateProjectCloud
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
import Breadcrumbs from '../overview/breadcrumbs.svelte';
|
||||
import Header from '../overview/header.svelte';
|
||||
import type { LayoutLoad } from './$types';
|
||||
import { resolvedProfile } from '$lib/profiles/index.svelte';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import { resolve } from '$app/paths';
|
||||
|
||||
export const load: LayoutLoad = async ({ params }) => {
|
||||
if (resolvedProfile.id === 'studio') {
|
||||
redirect(
|
||||
303,
|
||||
resolve('/(console)/project-[region]-[project]/(studio)', {
|
||||
region: params.region,
|
||||
project: params.project
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export const load: LayoutLoad = async () => {
|
||||
return {
|
||||
header: Header,
|
||||
breadcrumbs: Breadcrumbs
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import CreateWeb from './createWeb.svelte';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import { Click, trackEvent } from '$lib/actions/analytics';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
|
||||
export enum Platform {
|
||||
Web,
|
||||
@@ -29,7 +30,7 @@
|
||||
platform: Platform,
|
||||
name: string,
|
||||
key: string,
|
||||
type: string
|
||||
type: PlatformType
|
||||
) {
|
||||
createPlatform.set({
|
||||
name: name,
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
<svelte:fragment slot="tooltip" let:toggle>
|
||||
<ActionMenu.Root>
|
||||
{#if domain.status !== 'verified' && domain.status !== 'verifiying'}
|
||||
{#if domain.status !== 'verified' && domain.status !== 'verifying'}
|
||||
<ActionMenu.Item.Button
|
||||
leadingIcon={IconRefresh}
|
||||
on:click={(e) => {
|
||||
|
||||
Reference in New Issue
Block a user