diff --git a/package.json b/package.json index 1b65b2542..ddabeec1a 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,11 @@ "e2e:ui": "playwright test tests/e2e --ui" }, "dependencies": { - "@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@ae1eb53", + "@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153", "@appwrite.io/pink-icons": "0.25.0", - "@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f29290", + "@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0102c9f", "@appwrite.io/pink-legacy": "^1.0.1", - "@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@35f29290", + "@appwrite.io/pink-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@f99d781", "@popperjs/core": "^2.11.8", "@sentry/sveltekit": "^8.38.0", "@stripe/stripe-js": "^3.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6bfda9144..1ccb298e3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,20 +9,20 @@ importers: .: dependencies: '@appwrite.io/console': - specifier: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@ae1eb53 - version: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@ae1eb53 + specifier: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153 + version: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153 '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 '@appwrite.io/pink-icons-svelte': - specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f29290 - version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f29290(svelte@4.2.19) + specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0102c9f + version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0102c9f(svelte@4.2.19) '@appwrite.io/pink-legacy': specifier: ^1.0.1 version: 1.0.1 '@appwrite.io/pink-svelte': - specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@35f29290 - version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@35f29290(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19) + specifier: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@f99d781 + version: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@f99d781(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19) '@popperjs/core': specifier: ^2.11.8 version: 2.11.8 @@ -211,18 +211,18 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@ae1eb53': - resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@ae1eb53} + '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153': + resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153} version: 1.2.1 - '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f29290': - resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f29290} + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0102c9f': + resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0102c9f} version: 1.0.0-next.7 peerDependencies: svelte: ^4.0.0 - '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f2929064b9d126a377b6a3e85f59198c5901a2': - resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f2929064b9d126a377b6a3e85f59198c5901a2} + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f99d781924ba95e7ed83708ca8e4c26f80293c3c': + resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f99d781924ba95e7ed83708ca8e4c26f80293c3c} version: 1.0.0-next.7 peerDependencies: svelte: ^4.0.0 @@ -236,8 +236,8 @@ packages: '@appwrite.io/pink-legacy@1.0.1': resolution: {integrity: sha512-e5IZx2drqSxgl2WXvmr0eLfg/WiOCzuqQE8oksD+9GoFBkcL9HWvXul5GjFni3RBAN9XFRL3nUExGk4T0H8sFw==} - '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@35f29290': - resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@35f29290} + '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@f99d781': + resolution: {tarball: https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@f99d781} version: 1.0.0-next.85 peerDependencies: react-dom: ^18.0.0 @@ -4097,13 +4097,13 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@ae1eb53': {} + '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@08ec153': {} - '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f29290(svelte@4.2.19)': + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f0102c9f(svelte@4.2.19)': dependencies: svelte: 4.2.19 - '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f2929064b9d126a377b6a3e85f59198c5901a2(svelte@4.2.19)': + '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f99d781924ba95e7ed83708ca8e4c26f80293c3c(svelte@4.2.19)': dependencies: svelte: 4.2.19 @@ -4116,9 +4116,9 @@ snapshots: '@appwrite.io/pink-icons': 1.0.0 the-new-css-reset: 1.11.3 - '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@35f29290(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19)': + '@appwrite.io/pink-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-svelte@f99d781(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19)': dependencies: - '@appwrite.io/pink-icons-svelte': https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@35f2929064b9d126a377b6a3e85f59198c5901a2(svelte@4.2.19) + '@appwrite.io/pink-icons-svelte': https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@f99d781924ba95e7ed83708ca8e4c26f80293c3c(svelte@4.2.19) '@floating-ui/dom': 1.6.13 '@melt-ui/pp': 0.3.2(@melt-ui/svelte@0.86.3(svelte@4.2.19))(svelte@4.2.19) '@melt-ui/svelte': 0.86.3(svelte@4.2.19) diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts index c0f5ea4d4..19975c6ee 100644 --- a/src/lib/actions/analytics.ts +++ b/src/lib/actions/analytics.ts @@ -343,5 +343,6 @@ export enum Submit { SiteDisconnectRepo = 'submit_site_disconnect_repo', SiteActivateDeployment = 'submit_site_activate_deployment', RecordCreate = 'submit_dns_record_create', + RecordUpdate = 'submit_dns_record_update', RecordDelete = 'submit_dns_record_delete' } diff --git a/src/lib/charts/base.json b/src/lib/charts/base.json index 0cbfc0897..ff3d8fbcc 100644 --- a/src/lib/charts/base.json +++ b/src/lib/charts/base.json @@ -1,5 +1,121 @@ { - "backgroundColor": "rgba(255,255,255,0)", + "backgroundColor": "var(--color-bgcolor-neutral-primary)", + "categoryAxis": { + "axisLine": { + "lineStyle": { + "color": "var(--color-fgcolor-neutral-tertiary)" + }, + "show": true + }, + "axisTick": { + "lineStyle": { + "color": "var(--color-fgcolor-neutral-tertiary)" + }, + "show": true + }, + "axisLabel": { + "color": "var(--color-fgcolor-neutral-tertiary)", + "show": true + }, + "splitLine": { + "show": false + }, + "splitArea": { + "show": false + } + }, + "valueAxis": { + "axisLabel": { + "color": "var(--color-fgcolor-neutral-tertiary)", + "show": true + }, + "splitLine": { + "lineStyle": { + "color": ["var(--color-border-neutral)"] + }, + "show": true + }, + "axisLine": { + "show": false + }, + "axisTick": { + "show": false + }, + "splitArea": { + "show": false + } + }, + "logAxis": { + "axisLine": { + "lineStyle": { + "color": "var(--color-fgcolor-neutral-tertiary)" + }, + "show": true + }, + "axisTick": { + "lineStyle": { + "color": "var(--color-fgcolor-neutral-tertiary)" + }, + "show": true + }, + "axisLabel": { + "color": "var(--color-fgcolor-neutral-tertiary)", + "show": true + }, + "splitLine": { + "lineStyle": { + "color": ["var(--color-border-neutral)"] + }, + "show": true + }, + "splitArea": { + "show": false + } + }, + "timeAxis": { + "axisLine": { + "lineStyle": { + "color": "var(--color-fgcolor-neutral-tertiary)" + }, + "show": true + }, + "axisTick": { + "lineStyle": { + "color": "var(--color-fgcolor-neutral-tertiary)" + }, + "show": true + }, + "axisLabel": { + "color": "var(--color-fgcolor-neutral-tertiary)", + "show": true + }, + "splitLine": { + "lineStyle": { + "color": ["var(--color-border-neutral)"] + }, + "show": true + }, + "splitArea": { + "show": false + } + }, + "tooltip": { + "backgroundColor": "var(--color-bgcolor-neutral-primary)", + "borderColor": "var(--color-border-neutral)", + "textStyle": { + "color": "var(--color-fgcolor-neutral-secondary)" + }, + "axisPointer": { + "lineStyle": { + "color": "var(--color-border-neutral-strong)", + "width": 1 + }, + "crossStyle": { + "color": "var(--color-border-neutral-strong)", + "width": 1 + } + } + }, "textStyle": {}, "line": { "itemStyle": { @@ -12,89 +128,6 @@ "symbol": "emptyCircle", "smooth": true }, - "bar": { - "itemStyle": { - "barBorderColor": "#ccc" - } - }, - "categoryAxis": { - "axisLine": { - "show": true - }, - "axisTick": { - "show": true - }, - "axisLabel": { - "show": true - }, - "splitLine": { - "show": false - }, - "splitArea": { - "show": false - } - }, - "valueAxis": { - "axisLine": { - "show": false - }, - "axisTick": { - "show": false - }, - "axisLabel": { - "show": true - }, - "splitLine": { - "show": true - }, - "splitArea": { - "show": false - } - }, - "logAxis": { - "axisLine": { - "show": true - }, - "axisTick": { - "show": true - }, - "axisLabel": { - "show": true - }, - "splitLine": { - "show": true - }, - "splitArea": { - "show": false - } - }, - "timeAxis": { - "axisLine": { - "show": true - }, - "axisTick": { - "show": true - }, - "axisLabel": { - "show": true - }, - "splitLine": { - "show": true - }, - "splitArea": { - "show": false - } - }, - "tooltip": { - "axisPointer": { - "lineStyle": { - "width": 1 - }, - "crossStyle": { - "width": 1 - } - } - }, "timeline": { "lineStyle": { "width": 1 diff --git a/src/lib/charts/base.svelte b/src/lib/charts/base.svelte index 3c25fedde..64cfd8a20 100644 --- a/src/lib/charts/base.svelte +++ b/src/lib/charts/base.svelte @@ -4,15 +4,13 @@ import { app } from '$lib/stores/app'; import { dailyFormat, hourlyFormat, defaultConfig } from './config'; import base from './base.json'; - import light from './light.json'; - import dark from './dark.json'; import type { ECharts } from 'echarts/core'; import type { BarSeriesOption, LineSeriesOption } from 'echarts/charts'; import type { EChartsOption } from 'echarts'; import { wizard } from '$lib/stores/wizard'; - registerTheme('light', { ...base, ...light }); - registerTheme('dark', { ...base, ...dark }); + registerTheme('light', base); + registerTheme('dark', base); export let options: EChartsOption; export let series: (BarSeriesOption | LineSeriesOption)[]; diff --git a/src/lib/charts/dark.json b/src/lib/charts/dark.json index ec07fda73..9d09ce2ef 100644 --- a/src/lib/charts/dark.json +++ b/src/lib/charts/dark.json @@ -120,10 +120,10 @@ "color": "#444444" } }, - "backgroundColor": "#373B4D", - "borderColor": "#373B4D", + "backgroundColor": "var(--color-bgcolor-neutral-primary)", + "borderColor": "var(--color-border-neutral)", "textStyle": { - "color": "#F2F2F8" + "color": "var(--color-fgcolor-neutral-secondary)" } }, "timeline": { diff --git a/src/lib/charts/light.json b/src/lib/charts/light.json index e6ddb057a..d81dd9f85 100644 --- a/src/lib/charts/light.json +++ b/src/lib/charts/light.json @@ -1,149 +1,82 @@ { - "backgroundColor": "rgba(255,255,255,0)", - "title": { - "textStyle": { - "color": "#373b4d" - }, - "subtextStyle": { - "color": "#616b7c" - } - }, - "bar": { - "itemStyle": { - "barBorderColor": "#ccc" - } - }, + "backgroundColor": "var(--color-bgcolor-neutral-primary)", "categoryAxis": { "axisLine": { "lineStyle": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" } }, "axisTick": { "lineStyle": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" } }, "axisLabel": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" } }, "valueAxis": { "axisLabel": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" }, "splitLine": { "lineStyle": { - "color": ["#E8E9F0"] + "color": ["var(--color-border-neutral)"] } } }, "logAxis": { "axisLine": { "lineStyle": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" } }, "axisTick": { "lineStyle": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" } }, "axisLabel": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" }, "splitLine": { "lineStyle": { - "color": ["#E0E6F1"] + "color": ["var(--color-border-neutral)"] } } }, "timeAxis": { "axisLine": { "lineStyle": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" } }, "axisTick": { "lineStyle": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" } }, "axisLabel": { - "color": "#6E7079" + "color": "var(--color-fgcolor-neutral-tertiary)" }, "splitLine": { "lineStyle": { - "color": ["#E0E6F1"] + "color": ["var(--color-border-neutral)"] } } }, - "toolbox": { - "iconStyle": { - "borderColor": "#999" - }, - "emphasis": { - "iconStyle": { - "borderColor": "#666" - } - } - }, - "legend": { - "textStyle": { - "color": "#333" - } - }, "tooltip": { + "backgroundColor": "var(--color-bgcolor-neutral-primary)", + "borderColor": "var(--color-border-neutral)", + "textStyle": { + "color": "var(--color-fgcolor-neutral-secondary)" + }, "axisPointer": { "lineStyle": { - "color": "#ccc" + "color": "var(--color-border-neutral-strong)" }, "crossStyle": { - "color": "#ccc" - } - } - }, - "timeline": { - "lineStyle": { - "color": "#DAE1F5" - }, - "itemStyle": { - "color": "#A4B1D7" - }, - "controlStyle": { - "color": "#A4B1D7", - "borderColor": "#A4B1D7" - }, - "checkpointStyle": { - "color": "#316bf3", - "borderColor": "#fff" - }, - "label": { - "color": "#A4B1D7" - }, - "emphasis": { - "itemStyle": { - "color": "#FFF" - }, - "controlStyle": { - "color": "#A4B1D7", - "borderColor": "#A4B1D7" - }, - "label": { - "color": "#A4B1D7" - } - } - }, - "visualMap": { - "color": ["#bf444c", "#d88273", "#f6efa6"] - }, - "markPoint": { - "label": { - "color": "#eee" - }, - "emphasis": { - "label": { - "color": "#eee" + "color": "var(--color-border-neutral-strong)" } } } diff --git a/src/lib/components/avatar.svelte b/src/lib/components/avatar.svelte index dc43da457..0ff36651a 100644 --- a/src/lib/components/avatar.svelte +++ b/src/lib/components/avatar.svelte @@ -3,8 +3,10 @@ import type { AvatarProps } from '@appwrite.io/pink-svelte/dist/avatar/Avatar.svelte'; export let size: AvatarProps['size'] = 'm'; - export let src: AvatarProps['src']; + export let src: AvatarProps['src'] = undefined; export let alt: AvatarProps['alt']; - + + + diff --git a/src/lib/components/avatarGroup.svelte b/src/lib/components/avatarGroup.svelte index 6c19d6b05..499cd5e95 100644 --- a/src/lib/components/avatarGroup.svelte +++ b/src/lib/components/avatarGroup.svelte @@ -24,7 +24,9 @@ {#if total > 2} - +{total - 2} + + +{total - 2} + {/if} diff --git a/src/lib/components/confirm.svelte b/src/lib/components/confirm.svelte index c0e552bf1..6e37223d5 100644 --- a/src/lib/components/confirm.svelte +++ b/src/lib/components/confirm.svelte @@ -1,5 +1,5 @@
@@ -25,13 +29,32 @@ {error} {/if} - + + + + + {#if confirmDeletion} + + {/if} + + - - {#if canDelete} - - {/if} + + + {#if canDelete} + + {/if} + diff --git a/src/lib/components/copyInput.svelte b/src/lib/components/copyInput.svelte index ed07b9737..51d80c74b 100644 --- a/src/lib/components/copyInput.svelte +++ b/src/lib/components/copyInput.svelte @@ -8,7 +8,7 @@ export let optionalText: string | undefined = undefined; - + diff --git a/src/lib/components/empty.svelte b/src/lib/components/empty.svelte index dc8cd1374..5b21a2ee4 100644 --- a/src/lib/components/empty.svelte +++ b/src/lib/components/empty.svelte @@ -27,7 +27,7 @@ {#if single} - + - + {:else} - - - - + + {/if} diff --git a/src/lib/components/filters/filters.svelte b/src/lib/components/filters/filters.svelte index 7c83db052..e6f4587e9 100644 --- a/src/lib/components/filters/filters.svelte +++ b/src/lib/components/filters/filters.svelte @@ -14,7 +14,7 @@ ValidOperators } from './store'; import { createEventDispatcher } from 'svelte'; - import { Icon } from '@appwrite.io/pink-svelte'; + import { Icon, Popover } from '@appwrite.io/pink-svelte'; import { IconFilter } from '@appwrite.io/pink-icons-svelte'; export let query = '[]'; @@ -117,19 +117,17 @@
- - - - - + + +
{#if displayQuickFilters} @@ -171,7 +169,7 @@
- +
diff --git a/src/lib/components/gridItem1.svelte b/src/lib/components/gridItem1.svelte index 03c10ef87..96a8118b6 100644 --- a/src/lib/components/gridItem1.svelte +++ b/src/lib/components/gridItem1.svelte @@ -1,9 +1,10 @@ - +
@@ -26,7 +27,7 @@
-
+ diff --git a/src/lib/components/roles/upgrade.svelte b/src/lib/components/roles/upgrade.svelte index 9e5487476..d3dcf861b 100644 --- a/src/lib/components/roles/upgrade.svelte +++ b/src/lib/components/roles/upgrade.svelte @@ -5,58 +5,62 @@ import { organization } from '$lib/stores/organization'; import { BillingPlan } from '$lib/constants'; import Button from '$lib/elements/forms/button.svelte'; + import { Badge, Layout, Link, Tag, Typography } from '@appwrite.io/pink-svelte'; - {#if isCloud} - {#if $organization?.billingPlan !== BillingPlan.FREE} -
-

- Roles - {#if $organization?.billingPlan === BillingPlan.FREE} - Pro plan - {/if} -

-

Owner, Developer, Editor, Analyst and Billing.

-
-

- about roles. -

- {:else} -
-

- Roles - {#if $organization?.billingPlan === BillingPlan.FREE} - Pro plan - {/if} -

-

+ + {#if isCloud} + {#if $organization?.billingPlan !== BillingPlan.FREE} + Roles + Owner, Developer, Editor, Analyst and Billing. + + Learn more + + {:else} + + + Roles + + + + Upgrade to Pro to assign new roles to members such as Owner, Developer, Editor or Analyst. + + +

+ +

-
+ {/if} + {:else} + + + Roles + + + + + Upgrade to Cloud to assign new roles to members or ask us about our enterprise self + hosted offering. +

- - + +

{/if} - {:else} -
-

- Roles - Appwrite Cloud -

-

- Upgrade to Cloud to assign new roles to members or ask us about our entriprise self - hosted offering. -

-
-

- - -

- {/if} + diff --git a/src/lib/components/secret.svelte b/src/lib/components/secret.svelte index c9e328a8c..4717a874b 100644 --- a/src/lib/components/secret.svelte +++ b/src/lib/components/secret.svelte @@ -1,37 +1,16 @@ -
- {#if show} - {value} - {:else} - •••••••••••• - {/if} -
- - - {show ? 'Hide secret' : 'Show secret'} - + +
- +
-
+ diff --git a/src/lib/components/sidebar.svelte b/src/lib/components/sidebar.svelte index 559969663..e8ffdc332 100644 --- a/src/lib/components/sidebar.svelte +++ b/src/lib/components/sidebar.svelte @@ -34,6 +34,7 @@ import MobileFeedbackModal from '$routes/(console)/wizard/feedback/mobileFeedbackModal.svelte'; import { getSidebarState, updateSidebarState } from '$lib/helpers/sidebar'; import { isTabletViewport } from '$lib/stores/viewport'; + import { trackEvent } from '$lib/actions/analytics'; type $$Props = HTMLElement & { state?: 'closed' | 'open' | 'icons'; @@ -66,6 +67,7 @@ $: state = $isTabletViewport ? 'closed' : getSidebarState(); $: pathname = $page.url.pathname; + $: isOnProjectSettings = /^\/console\/project-[a-zA-Z0-9-]+\/settings$/.test(pathname); const projectOptions = [ { name: 'Auth', icon: IconUserGroup, slug: 'auth' }, @@ -106,11 +108,12 @@
{#if progressCard} - + { + trackEvent('click_menu_get_started'); sideBarIsOpen = false; }}> {#each projectOptions as projectOption} - + { + trackEvent(`click_menu_${projectOption.slug}`); sideBarIsOpen = false; }} >
- - + { + trackEvent('click_menu_settings'); + }} + class="link" > toggleFeedback()} + on:click={() => { + toggleFeedback(); + trackEvent('click_menu_feedback', { source: 'side_nav' }); + }} >Feedback @@ -212,7 +225,10 @@ ($showSupportModal = true)}> + on:click={() => { + $showSupportModal = true; + trackEvent('click_menu_support', { source: 'side_nav' }); + }}> Support @@ -228,11 +244,14 @@ + {#if subNavigation} - - dispatch('change', '24h')}>24h - dispatch('change', '30d')}>30d - dispatch('change', '90d')}>90d + + + {period} + + + + + dispatch('change', '24h')} + >24h + dispatch('change', '30d')} + >30d + dispatch('change', '90d')} + >90d + - -
+ + {#if bandwidth.value !== '0'}
{#if !$page.url.pathname.includes('get-started')} @@ -45,6 +46,7 @@ variant="secondary" size="s" on:click={async () => { + trackEvent('onboarding_hub_platform_dismiss'); await setHasOnboardingDismissed($project.$id); goto(`${base}/project-${$project.$id}/overview`); requestAnimationFrame(() => { diff --git a/src/routes/(console)/project-[project]/overview/keys/+page.svelte b/src/routes/(console)/project-[project]/overview/keys/+page.svelte index 2471446f1..031560695 100644 --- a/src/routes/(console)/project-[project]/overview/keys/+page.svelte +++ b/src/routes/(console)/project-[project]/overview/keys/+page.svelte @@ -1,23 +1,14 @@ - - {#if $canWriteKeys} - diff --git a/src/routes/(console)/project-[project]/overview/keys/create/+page.svelte b/src/routes/(console)/project-[project]/overview/keys/create/+page.svelte new file mode 100644 index 000000000..1355a93bc --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/keys/create/+page.svelte @@ -0,0 +1,98 @@ + + + + + +
+ + + + +
+ +
+ + + Choose which permission scopes to grant your application. It is best + practice to allow only the permissions you need to meet your project goals. + + + +
+
+ + + + + + +
diff --git a/src/routes/(console)/project-[project]/overview/keys/expirationInput.svelte b/src/routes/(console)/project-[project]/overview/keys/expirationInput.svelte index 843cc9f3d..0d76951b3 100644 --- a/src/routes/(console)/project-[project]/overview/keys/expirationInput.svelte +++ b/src/routes/(console)/project-[project]/overview/keys/expirationInput.svelte @@ -73,7 +73,7 @@ } - + {#if expirationSelect !== 'custom' && expirationSelect !== null} Your key will expire in {toLocaleDate(value)} diff --git a/src/routes/(console)/project-[project]/overview/keys/scopes.svelte b/src/routes/(console)/project-[project]/overview/keys/scopes.svelte index c948d7ea6..7bc921b5e 100644 --- a/src/routes/(console)/project-[project]/overview/keys/scopes.svelte +++ b/src/routes/(console)/project-[project]/overview/keys/scopes.svelte @@ -5,6 +5,7 @@ import { onMount } from 'svelte'; import { symmetricDifference } from '$lib/helpers/array'; import Checkbox from './checkbox.svelte'; + import { Accordion, Divider, Input, Layout, Selector } from '@appwrite.io/pink-svelte'; export let scopes: string[]; @@ -40,7 +41,7 @@ } } - function categoryState(category: string, s: string[]): boolean | null { + function categoryState(category: string, s: string[]): boolean | 'indeterminate' { const scopesByCategory = allScopes.filter((n) => n.category === category); const filtered = scopesByCategory.filter((n) => s.includes(n.scope)); if (filtered.length === 0) { @@ -48,16 +49,15 @@ } else if (filtered.length === scopesByCategory.length) { return true; } else { - return null; + return 'indeterminate'; } } - function onCategoryChange(event: Event, category: Category) { + function onCategoryChange(event: CustomEvent, category: Category) { + if (event.detail === 'indeterminate') return; allScopes.forEach((s) => { if (s.category === category) { - activeScopes[s.scope] = ( - event.currentTarget as EventTarget & HTMLInputElement - ).checked; + activeScopes[s.scope] = event.detail; } }); } @@ -81,47 +81,39 @@ } -
    -
  • - -
  • -
  • - -
  • -
+ + + + + + + + + + - - {#each [Category.Auth, Category.Database, Category.Functions, Category.Storage, Category.Messaging, Category.Other] as category} - {@const checked = categoryState(category, scopes)} - - - onCategoryChange(e, category)} /> - - - {category} - - - {@const scopesLength = allScopes.filter( - (n) => n.category === category && scopes.includes(n.scope) - ).length} - ({scopesLength} - {scopesLength === 1 ? 'Scope' : 'Scopes'}) - -
- + {#each [Category.Auth, Category.Database, Category.Functions, Category.Storage, Category.Messaging, Category.Other] as category} + {@const checked = categoryState(category, scopes)} + {@const scopesLength = allScopes.filter( + (n) => n.category === category && scopes.includes(n.scope) + ).length} + onCategoryChange(event, category)}> + {#each allScopes.filter((s) => s.category === category) as scope} - - {scope.description} - + description={scope.description} + bind:checked={activeScopes[scope.scope]} /> {/each} - -
-
- {/each} -
+
+ + {/each} +
+ diff --git a/src/routes/(console)/project-[project]/overview/keys/wizard.svelte b/src/routes/(console)/project-[project]/overview/keys/wizard.svelte deleted file mode 100644 index dba8656bd..000000000 --- a/src/routes/(console)/project-[project]/overview/keys/wizard.svelte +++ /dev/null @@ -1,56 +0,0 @@ - - - diff --git a/src/routes/(console)/project-[project]/overview/keys/wizard/step1.svelte b/src/routes/(console)/project-[project]/overview/keys/wizard/step1.svelte deleted file mode 100644 index cb53ed034..000000000 --- a/src/routes/(console)/project-[project]/overview/keys/wizard/step1.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - API key - Let's create an API key. - - - - - diff --git a/src/routes/(console)/project-[project]/overview/keys/wizard/step2.svelte b/src/routes/(console)/project-[project]/overview/keys/wizard/step2.svelte deleted file mode 100644 index 383a8d426..000000000 --- a/src/routes/(console)/project-[project]/overview/keys/wizard/step2.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - - Scopes - - Choose which permission scopes to grant your application. It is best practice to allow only - the permissions you need to meet your project goals. - - - - - diff --git a/src/routes/(console)/project-[project]/overview/keys/wizard/store.ts b/src/routes/(console)/project-[project]/overview/keys/wizard/store.ts deleted file mode 100644 index 49f23c0e9..000000000 --- a/src/routes/(console)/project-[project]/overview/keys/wizard/store.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { writable } from 'svelte/store'; -import type { Models } from '@appwrite.io/console'; - -function createKeyStore() { - const { subscribe, update, set } = writable>({ - name: null, - expire: null, - scopes: [] - }); - - return { - subscribe, - update, - set, - reset() { - set({ - name: null, - expire: null, - scopes: [] - }); - } - }; -} - -export const key = createKeyStore(); diff --git a/src/routes/(console)/project-[project]/overview/onboard.svelte b/src/routes/(console)/project-[project]/overview/onboard.svelte index feeb49746..6bb95c213 100644 --- a/src/routes/(console)/project-[project]/overview/onboard.svelte +++ b/src/routes/(console)/project-[project]/overview/onboard.svelte @@ -31,15 +31,21 @@ import PlatformFlutterImgSource from './assets/platform-flutter.svg'; import PlatformFlutterImgSourceDark from './assets/platform-flutter-dark.svg'; import { base } from '$app/paths'; - import Wizard from './keys/wizard.svelte'; - import { wizard } from '$lib/stores/wizard'; import { isSmallViewport } from '$lib/stores/viewport'; import { AvatarGroup } from '$lib/components'; import type { Models } from '@appwrite.io/console'; import { getPlatformInfo } from '$lib/helpers/platform'; + import { trackEvent } from '$lib/actions/analytics'; + import { goto } from '$app/navigation'; function createKey() { - wizard.start(Wizard); + trackEvent('onboarding_hub_platform', { + platform: 'server', + state: 'add' + }); + goto(`${base}/project-${projectId}/overview/keys/create`, { + replaceState: true + }); } export let projectId: string; @@ -386,7 +392,12 @@ - addPlatform(0)} padding="s" + { + trackEvent('onboarding_hub_setup_databases'); + goto(`${base}/project-${projectId}/databases`); + }} + padding="s" >
{ + trackEvent( + 'onboarding_hub_api_references' + ); + }} target="_blank">API references { + trackEvent('onboarding_hub_tutorials'); + }} target="_blank">Tutorials { + trackEvent( + 'onboarding_hub_storage_quick_start' + ); + }} target="_blank" >Storage quick start { + trackEvent( + 'onboarding_hub_functions_quick_start' + ); + }} target="_blank" >Functions quick start @@ -458,16 +487,29 @@ { + trackEvent( + 'onboarding_hub_auth_email_password' + ); + }} >E-mail and password OAuth 2 + on:click={() => { + trackEvent( + 'onboarding_hub_auth_oauth2' + ); + }}>OAuth 2 View all methods + on:click={() => { + trackEvent( + 'onboarding_hub_auth_all_methods' + ); + }}>View all methods
- + { + trackEvent('onboarding_hub_discord'); + }}>
diff --git a/src/routes/(console)/project-[project]/overview/platforms/+page.svelte b/src/routes/(console)/project-[project]/overview/platforms/+page.svelte index d6a951bc1..0842bffc4 100644 --- a/src/routes/(console)/project-[project]/overview/platforms/+page.svelte +++ b/src/routes/(console)/project-[project]/overview/platforms/+page.svelte @@ -1,12 +1,12 @@ @@ -112,7 +135,10 @@ {platform.name} - {PlatformTypes[platform.type]} + + + {PlatformTypes[platform.type]} + {platform.$updatedAt ? toLocaleDate(platform.$updatedAt) : 'never'} @@ -121,49 +147,49 @@ {/each} {:else} -
-
- {#if $app.themeInUse === 'dark'} - - {:else} - - {/if} - -
- Create a platform to get started. -

- Need a hand? Learn more in our documentation. -

-
-
- - - {#if $canWritePlatforms} - - {/if} - - addPlatform(Platform.Flutter)}> + + + + + + {#if $canWritePlatforms} + + {/if} + + + addPlatform(Platform.Web)} + leadingIcon={IconCode}> + Web + + addPlatform(Platform.Flutter)} + leadingIcon={IconFlutter}> Flutter - - addPlatform(Platform.Android)}> + + addPlatform(Platform.Android)} + leadingIcon={IconAndroid}> Android - - addPlatform(Platform.Apple)}> + + addPlatform(Platform.Apple)} + leadingIcon={IconApple}> Apple - - addPlatform(Platform.ReactNative)}> + + addPlatform(Platform.ReactNative)} + leadingIcon={IconReact}> React Native - - - -
-
-
-
+ + + + + + + {/if} diff --git a/src/routes/(console)/project-[project]/overview/platforms/[platform]/android.svelte b/src/routes/(console)/project-[project]/overview/platforms/[platform]/android.svelte index 39fba99aa..b3ff88a6c 100644 --- a/src/routes/(console)/project-[project]/overview/platforms/[platform]/android.svelte +++ b/src/routes/(console)/project-[project]/overview/platforms/[platform]/android.svelte @@ -49,14 +49,12 @@ Package name Your package name is generally the applicationId in your app-level build.gradle file. - - - + diff --git a/src/routes/(console)/project-[project]/overview/platforms/[platform]/flutterAndroid.svelte b/src/routes/(console)/project-[project]/overview/platforms/[platform]/flutterAndroid.svelte index 81b3f1fc8..fa45bc68f 100644 --- a/src/routes/(console)/project-[project]/overview/platforms/[platform]/flutterAndroid.svelte +++ b/src/routes/(console)/project-[project]/overview/platforms/[platform]/flutterAndroid.svelte @@ -49,14 +49,12 @@ Package name Your package name is generally the applicationId in your app-level build.gradle file. - - - + diff --git a/src/routes/(console)/project-[project]/overview/platforms/action.svelte b/src/routes/(console)/project-[project]/overview/platforms/action.svelte index 7e2b723ce..dedbef189 100644 --- a/src/routes/(console)/project-[project]/overview/platforms/action.svelte +++ b/src/routes/(console)/project-[project]/overview/platforms/action.svelte @@ -3,25 +3,56 @@ import DropListItem from '$lib/components/dropListItem.svelte'; import Button from '$lib/elements/forms/button.svelte'; import { canWritePlatforms } from '$lib/stores/roles'; - import { Icon } from '@appwrite.io/pink-svelte'; + import { ActionMenu, Icon, Popover } from '@appwrite.io/pink-svelte'; import { addPlatform, Platform } from './+page.svelte'; - import { IconPlus } from '@appwrite.io/pink-icons-svelte'; + import { + IconAndroid, + IconApple, + IconCode, + IconFlutter, + IconPlus, + IconReact + } from '@appwrite.io/pink-icons-svelte'; let showDropdown = false; {#if $canWritePlatforms} - - - - addPlatform(Platform.Flutter)}>Flutter app - addPlatform(Platform.Android)}>Android app - addPlatform(Platform.Apple)}>Apple app - addPlatform(Platform.ReactNative)} - >React Native app - - + + {#if $canWritePlatforms} + + {/if} +
+ + addPlatform(Platform.Web)} + leadingIcon={IconCode}> + Web + + addPlatform(Platform.Flutter)} + leadingIcon={IconFlutter}> + Flutter + + addPlatform(Platform.Android)} + leadingIcon={IconAndroid}> + Android + + addPlatform(Platform.Apple)} + leadingIcon={IconApple}> + Apple + + addPlatform(Platform.ReactNative)} + leadingIcon={IconReact}> + React Native + + +
+
{/if} diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/AngularFrameworkIcon.svelte b/src/routes/(console)/project-[project]/overview/platforms/components/AngularFrameworkIcon.svelte new file mode 100644 index 000000000..66ed5831c --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/AngularFrameworkIcon.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/NextjsFrameworkIcon.svelte b/src/routes/(console)/project-[project]/overview/platforms/components/NextjsFrameworkIcon.svelte new file mode 100644 index 000000000..43655f0f5 --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/NextjsFrameworkIcon.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/NoFrameworkIcon.svelte b/src/routes/(console)/project-[project]/overview/platforms/components/NoFrameworkIcon.svelte new file mode 100644 index 000000000..2daf0fbd9 --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/NoFrameworkIcon.svelte @@ -0,0 +1,11 @@ + + +{#if $app.themeInUse === 'light'} + +{:else} + +{/if} diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/NuxtFrameworkIcon.svelte b/src/routes/(console)/project-[project]/overview/platforms/components/NuxtFrameworkIcon.svelte new file mode 100644 index 000000000..eb9be4fed --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/NuxtFrameworkIcon.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/ReactFrameworkIcon.svelte b/src/routes/(console)/project-[project]/overview/platforms/components/ReactFrameworkIcon.svelte new file mode 100644 index 000000000..ea37c9534 --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/ReactFrameworkIcon.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/SvelteFrameworkIcon.svelte b/src/routes/(console)/project-[project]/overview/platforms/components/SvelteFrameworkIcon.svelte new file mode 100644 index 000000000..0a2d0b3de --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/SvelteFrameworkIcon.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/VueFrameworkIcon.svelte b/src/routes/(console)/project-[project]/overview/platforms/components/VueFrameworkIcon.svelte new file mode 100644 index 000000000..3a4469231 --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/VueFrameworkIcon.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/noFrameworkIcon.svg b/src/routes/(console)/project-[project]/overview/platforms/components/noFrameworkIcon.svg new file mode 100644 index 000000000..20ab4b4f7 --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/noFrameworkIcon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/routes/(console)/project-[project]/overview/platforms/components/noFrameworkIconDark.svg b/src/routes/(console)/project-[project]/overview/platforms/components/noFrameworkIconDark.svg new file mode 100644 index 000000000..ae29faf6e --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/components/noFrameworkIconDark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/routes/(console)/project-[project]/overview/platforms/createWeb.svelte b/src/routes/(console)/project-[project]/overview/platforms/createWeb.svelte new file mode 100644 index 000000000..05564bb98 --- /dev/null +++ b/src/routes/(console)/project-[project]/overview/platforms/createWeb.svelte @@ -0,0 +1,361 @@ + + + +
+ + + {#if !isPlatformCreated || isChangingFramework} +
+ +
+ {#each frameworks as framework} + + {/each} +
+ + + {#if isChangingFramework} + { + isChangingFramework = false; + }}> + Change framework instructions + {:else} + Create platform + {/if} + +
+
+ {:else} + + + + {selectedFramework.label} + + { + isChangingFramework = true; + }}>Change + + {/if} + + + {#if isPlatformCreated && !isChangingFramework} +
+ + + 1. Clone the starter kit from GitHub using the terminal or VSCode. + + + +
+ +
+ + {#if selectedFramework.key === 'angular'} + 2. Change + to reflect the values below: + {:else} + 2. Rename into and update the values. + {/if} + + +
+ +
+ + 3. Install project dependencies + + +
+ +
+ + 3. Run the app, then click the button to verify the setup. +
+
+ + + Demo app runs on http://localhost:{selectedFramework.portNumber} + Open + {/if} +
+ + + + + + + + + + + + + {#if isPlatformCreated} + + {#if !connectionSuccessful} + Waiting for connection... + {:else} + +
+ Congratulations! + + You connected your app successfully. +
+ {/if} +
+ {/if} +
+
+
+ + + {#if isPlatformCreated} + Go to dashboard + {/if} + +
+ + diff --git a/src/routes/(console)/project-[project]/overview/realtime.svelte b/src/routes/(console)/project-[project]/overview/realtime.svelte index 852065d0b..14b5f50f3 100644 --- a/src/routes/(console)/project-[project]/overview/realtime.svelte +++ b/src/routes/(console)/project-[project]/overview/realtime.svelte @@ -3,6 +3,7 @@ import { BarChart } from '$lib/charts'; import { Card } from '$lib/components'; import { formatNum } from '$lib/helpers/string'; + import { Link, Typography } from '@appwrite.io/pink-svelte'; import { stats } from '../store'; $: projectId = $page.params.project; @@ -34,12 +35,11 @@ class="icon-chart-square-bar text-large" aria-hidden="true" style="font-size: 32px;" /> -

No data to show

-
No data to show + Get started with Realtime + rel="noopener noreferrer">Get started with Realtime
{/if} diff --git a/src/routes/(console)/project-[project]/overview/requests.svelte b/src/routes/(console)/project-[project]/overview/requests.svelte index 7fe57efda..9a484763a 100644 --- a/src/routes/(console)/project-[project]/overview/requests.svelte +++ b/src/routes/(console)/project-[project]/overview/requests.svelte @@ -1,47 +1,54 @@ -
+
-
+ {formatNum(totalMetrics($usage?.requests))} -
-
Requests
+ + Requests
- - - - dispatch('change', '24h')}>24h - dispatch('change', '30d')}>30d - dispatch('change', '90d')}>90d - - -
+ + + {period} + + + + dispatch('change', '24h')} + >24h + dispatch('change', '30d')} + >30d + dispatch('change', '90d')} + >90d + + + + {#if totalMetrics($usage?.requests) !== 0}
@@ -162,29 +162,30 @@ - + {#if tab === 'env'} {:else if tab === 'json'} {/if} - - - - diff --git a/src/routes/(console)/project-[project]/settings/+page.svelte b/src/routes/(console)/project-[project]/settings/+page.svelte index c15216083..e57f122fb 100644 --- a/src/routes/(console)/project-[project]/settings/+page.svelte +++ b/src/routes/(console)/project-[project]/settings/+page.svelte @@ -90,16 +90,18 @@ Transfer project Transfer your project to another organization that you own. - - ({ + team.$id !== $project.teamId) + .map((team) => ({ value: team.$id, label: team.name }))} /> - diff --git a/src/routes/(console)/project-[project]/settings/GitInstallationModal.svelte b/src/routes/(console)/project-[project]/settings/GitInstallationModal.svelte index bcaed0c52..0308652d7 100644 --- a/src/routes/(console)/project-[project]/settings/GitInstallationModal.svelte +++ b/src/routes/(console)/project-[project]/settings/GitInstallationModal.svelte @@ -21,20 +21,20 @@

Select a provider to import an existing git repository.

-
- - - - diff --git a/src/routes/(console)/project-[project]/settings/deleteProject.svelte b/src/routes/(console)/project-[project]/settings/deleteProject.svelte index be810db42..79972e545 100644 --- a/src/routes/(console)/project-[project]/settings/deleteProject.svelte +++ b/src/routes/(console)/project-[project]/settings/deleteProject.svelte @@ -62,7 +62,12 @@ - +

This project will be deleted, along with all of its metadata, stats, and other diff --git a/src/routes/(console)/project-[project]/settings/transferProject.svelte b/src/routes/(console)/project-[project]/settings/transferProject.svelte index a5790eebc..877294fc5 100644 --- a/src/routes/(console)/project-[project]/settings/transferProject.svelte +++ b/src/routes/(console)/project-[project]/settings/transferProject.svelte @@ -6,6 +6,7 @@ import { Button } from '$lib/elements/forms'; import { addNotification } from '$lib/stores/notifications'; import { sdk } from '$lib/stores/sdk'; + import { Typography } from '@appwrite.io/pink-svelte'; import { project } from '../store'; export let show = false; @@ -33,11 +34,13 @@ -

Are you sure you want to transfer {$project.name} to {teamName}?

-

+ Are you sure you want to transfer {$project.name} to + {teamName}? + Members who are not part of the destination organization must be invited to gain access to this project. -

+ diff --git a/src/routes/(console)/project-[project]/settings/updateInstallations.svelte b/src/routes/(console)/project-[project]/settings/updateInstallations.svelte index 12e25c4b4..6a537ca38 100644 --- a/src/routes/(console)/project-[project]/settings/updateInstallations.svelte +++ b/src/routes/(console)/project-[project]/settings/updateInstallations.svelte @@ -6,24 +6,10 @@ Arrow, AvatarGroup, CardGrid, - DropList, - DropListItem, - DropListLink, - Heading, - Id, PaginationInline, SvgIcon } from '$lib/components'; import { Button } from '$lib/elements/forms'; - import { - Table, - TableBody, - TableCell, - TableCellHead, - TableCellText, - TableHeader, - TableRow - } from '$lib/elements/table'; import { sdk } from '$lib/stores/sdk'; import type { Models } from '@appwrite.io/console'; import GitInstallationModal from './GitInstallationModal.svelte'; @@ -31,14 +17,19 @@ import dayjs from 'dayjs'; import { isSelfHosted } from '$lib/system'; import { consoleVariables } from '$routes/(console)/store'; - import { Icon } from '@appwrite.io/pink-svelte'; + import { ActionMenu, Icon, Popover, Table } from '@appwrite.io/pink-svelte'; import { + IconAppwrite, IconAzure, IconBitBucket, + IconExternalLink, IconGithub, IconGitlab, - IconPlus + IconPlus, + IconXCircle } from '@appwrite.io/pink-icons-svelte'; + import Avatar from '$lib/components/avatar.svelte'; + import { iconPath } from '$lib/stores/app'; export let total: number; export let limit: number; @@ -106,90 +97,75 @@
-
- - - Installation ID - Repository - Updated - - - - {#each installations as installation, i} - - - {installation.$id} - - - - - - {dayjs().to(installation.$updatedAt)} - - - - - - - { - showInstallationDropdown[i] = false; - }}> - Configure - - { - showInstallationDropdown[i] = false; - showGitDisconnect = true; - selectedInstallation = installation; - }}> - Disconnect - - - - - - {/each} - -
+ + + Repository + Updated + + + {#each installations as installation, i} + + + + + + {dayjs().to(installation.$updatedAt)} + + + + + + (showInstallationDropdown[i] = false)}> + Configure + + { + showInstallationDropdown[i] = false; + showGitDisconnect = true; + selectedInstallation = installation; + }}> + Disconnect + + + + + + {/each} + +
+ {#if total > limit} +
+

Total installations: {total}

+
-
-
-

Total installations: {total}

- -
+ {/if} {:else} {#if isSelfHosted && !isVcsEnabled} @@ -213,13 +189,15 @@
-
+ + +
diff --git a/src/routes/(console)/project-[project]/settings/updateServices.svelte b/src/routes/(console)/project-[project]/settings/updateServices.svelte index 660c943d3..d5f47a51b 100644 --- a/src/routes/(console)/project-[project]/settings/updateServices.svelte +++ b/src/routes/(console)/project-[project]/settings/updateServices.svelte @@ -85,22 +85,27 @@ Choose services you wish to enable or disable for the client API. When disabled, the services are not accessible to client SDKs but remain accessible to server SDKs. - - - - + + + + + + + - - - {#each $services.list as service} - { - serviceUpdate(service); - }} /> - {/each} + + + + {#each $services.list as service} + + serviceUpdate(service)} /> + + {/each} + diff --git a/src/routes/(console)/project-[project]/sites/(components)/connectRepoModal.svelte b/src/routes/(console)/project-[project]/sites/(components)/connectRepoModal.svelte index fce286b89..b855373c9 100644 --- a/src/routes/(console)/project-[project]/sites/(components)/connectRepoModal.svelte +++ b/src/routes/(console)/project-[project]/sites/(components)/connectRepoModal.svelte @@ -29,6 +29,7 @@ let selectedRepository = ''; let installations = { installations: [], total: 0 }; let hasInstallations = !!installations?.total; + let error = ''; onMount(async () => { installations = await sdk.forProject.vcs.listInstallations(); @@ -54,18 +55,17 @@ repository.set(repo); selectedRepository = repo.id; } - console.log(Object.keys(Framework)); const s = await sdk.forProject.sites.update( site.$id, site.name, - Framework[site.framework], + site.framework as Framework, site.enabled, site.timeout, site.installCommand, site.buildCommand, site.outputDirectory, - BuildRuntime[site.buildRuntime], + site.buildRuntime as BuildRuntime, site.adapter, site.fallbackFile, selectedInstallationId, @@ -79,20 +79,20 @@ type: 'success', message: 'Repository connected successfully' }); - } catch (error) { - addNotification({ - type: 'error', - message: error.message - }); + } catch (e) { + error = e.message; } } + + $: console.log(selectedInstallationId); + onSubmit={connectRepo} + bind:error> Connect to a new repository or an existing one. {#if hasInstallations} diff --git a/src/routes/(console)/project-[project]/sites/(components)/deploymentCreatedBy.svelte b/src/routes/(console)/project-[project]/sites/(components)/deploymentCreatedBy.svelte index 750493df2..607d9501e 100644 --- a/src/routes/(console)/project-[project]/sites/(components)/deploymentCreatedBy.svelte +++ b/src/routes/(console)/project-[project]/sites/(components)/deploymentCreatedBy.svelte @@ -1,22 +1,29 @@

{#if deployment.providerCommitAuthor} - - {capitalize(timeFromNow(deployment.$updatedAt))} - + + + {capitalize(timeFromNow(deployment.$updatedAt))} + + {toLocaleDateTime(deployment.$updatedAt)} + by {deployment.providerCommitAuthor} {:else} - - {capitalize(timeFromNow(deployment.$updatedAt))} - + + + {capitalize(timeFromNow(deployment.$updatedAt))} + + {toLocaleDateTime(deployment.$updatedAt)} + {/if}

diff --git a/src/routes/(console)/project-[project]/sites/(components)/deploymentSource.svelte b/src/routes/(console)/project-[project]/sites/(components)/deploymentSource.svelte index 2cd0bca2c..3dce20f83 100644 --- a/src/routes/(console)/project-[project]/sites/(components)/deploymentSource.svelte +++ b/src/routes/(console)/project-[project]/sites/(components)/deploymentSource.svelte @@ -22,13 +22,13 @@ e.preventDefault(); toggle(e); }}> - + GitHub - + {#if deployment?.providerCommitMessage && deployment?.providerCommitHash && deployment?.providerCommitUrl} -
{#key buildLogs} - + {/key} {#if ['processing', 'building'].includes(status)} diff --git a/src/routes/(console)/project-[project]/sites/(components)/siteCard.svelte b/src/routes/(console)/project-[project]/sites/(components)/siteCard.svelte index 94572cbec..11e4a2dc8 100644 --- a/src/routes/(console)/project-[project]/sites/(components)/siteCard.svelte +++ b/src/routes/(console)/project-[project]/sites/(components)/siteCard.svelte @@ -24,6 +24,7 @@ import { app } from '$lib/stores/app'; import { base } from '$app/paths'; import { isCloud } from '$lib/system'; + import { getApiEndpoint } from '$lib/stores/sdk'; export let deployment: Models.Deployment; export let proxyRuleList: Models.ProxyRuleList = { total: 0, rules: [] }; @@ -34,6 +35,27 @@ deployment.domain ?? (proxyRuleList.total > 0 ? proxyRuleList.rules[0].domain : undefined); $: totalSize = humanFileSize((deployment?.buildSize ?? 0) + (deployment?.size ?? 0)); + + function getScreenshot(theme: string, deployment: Models.Deployment) { + if (theme === 'dark') { + return deployment.screenshotDark + ? getFilePreview(deployment.screenshotDark) + : `${base}/images/sites/screenshot-placeholder-dark.svg`; + } + + return deployment.screenshotLight + ? getFilePreview(deployment.screenshotLight) + : `${base}/images/sites/screenshot-placeholder-light.svg`; + } + + function getFilePreview(fileId: string) { + // TODO: @Meldiron use sdk.forConsole.storage.getFilePreview + const endpoint = getApiEndpoint(); + return ( + endpoint + + `/storage/buckets/screenshots/files/${fileId}/view?project=console&mode=admin` + ); + } @@ -45,10 +67,7 @@ radius="s" ratio="16/9" style="width: 100%; align-self: start" - src={deployment?.preview || - ($app.themeInUse === 'dark' - ? `${base}/images/sites/screenshot-placeholder-dark.svg` - : `${base}/images/sites/screenshot-placeholder-light.svg`)} + src={getScreenshot($app.themeInUse, deployment)} alt="Screenshot" /> @@ -84,7 +103,7 @@ {#if siteUrl && !hideQRCode} {/if} @@ -114,7 +133,7 @@ {/if} - + {#if deployment?.buildTime} .card-grid { display: grid; - grid-template-columns: 45% 55%; + grid-template-columns: 45% auto; // justify-content: center; align-items: center; gap: var(--gap-xl); diff --git a/src/routes/(console)/project-[project]/sites/+page.svelte b/src/routes/(console)/project-[project]/sites/+page.svelte index 495a854ef..9d611ced6 100644 --- a/src/routes/(console)/project-[project]/sites/+page.svelte +++ b/src/routes/(console)/project-[project]/sites/+page.svelte @@ -65,7 +65,7 @@ {#if data.siteList.total} {#if data.view === View.Grid} - + {:else} {/if} diff --git a/src/routes/(console)/project-[project]/sites/+page.ts b/src/routes/(console)/project-[project]/sites/+page.ts index a75a10f95..e0c637f43 100644 --- a/src/routes/(console)/project-[project]/sites/+page.ts +++ b/src/routes/(console)/project-[project]/sites/+page.ts @@ -1,4 +1,4 @@ -import { Query } from '@appwrite.io/console'; +import { Query, type Models } from '@appwrite.io/console'; import { sdk } from '$lib/stores/sdk'; import { getLimit, getPage, getSearch, getView, pageToOffset, View } from '$lib/helpers/load'; import { CARD_LIMIT, Dependencies } from '$lib/constants'; @@ -17,11 +17,35 @@ export const load = async ({ url, depends, route }) => { search || undefined ); + // TODO: @Meldiron Discuss better solution for getting screnshot IDs + const deployments: Models.Deployment[] = []; + await Promise.all( + siteList.sites.map(async (site) => { + if (!site.deploymentId) { + return; + } + + // TODO: @Meldiron Tripple-check if this can ever happened + // It happened to me but on QA that might have corrupted data + try { + const deployment = await sdk.forProject.sites.getDeployment( + site.$id, + site.deploymentId + ); + deployments.push(deployment); + } catch (err) { + // Active deployment no longer available (deleted?) + console.warn(err); + } + }) + ); + return { offset, limit, search, siteList, + deployments, view }; }; diff --git a/src/routes/(console)/project-[project]/sites/create-site/deploying/+page.svelte b/src/routes/(console)/project-[project]/sites/create-site/deploying/+page.svelte index 28c87470f..da280cdb8 100644 --- a/src/routes/(console)/project-[project]/sites/create-site/deploying/+page.svelte +++ b/src/routes/(console)/project-[project]/sites/create-site/deploying/+page.svelte @@ -39,10 +39,10 @@ diff --git a/src/routes/(console)/project-[project]/sites/createSiteModal.svelte b/src/routes/(console)/project-[project]/sites/createSiteModal.svelte index a21f16b3a..56d81324c 100644 --- a/src/routes/(console)/project-[project]/sites/createSiteModal.svelte +++ b/src/routes/(console)/project-[project]/sites/createSiteModal.svelte @@ -24,6 +24,7 @@ Clone a template @@ -42,6 +43,7 @@ diff --git a/src/routes/(console)/project-[project]/sites/grid.svelte b/src/routes/(console)/project-[project]/sites/grid.svelte index ce3dbfc75..394c3e877 100644 --- a/src/routes/(console)/project-[project]/sites/grid.svelte +++ b/src/routes/(console)/project-[project]/sites/grid.svelte @@ -15,14 +15,40 @@ import { getFrameworkIcon } from './store'; import { SvgIcon } from '$lib/components'; import { app } from '$lib/stores/app'; + import { getApiEndpoint } from '$lib/stores/sdk'; export let siteList: Models.SiteList; + export let deployments: Models.Deployment[]; let showRedeploy = false; let selectedSite: Models.Site = null; + + function getScreenshot(theme: string, site: Models.Site) { + const deployment = + deployments.find((d) => site.deploymentId && d.$id === site.deploymentId) ?? null; + + if (theme === 'dark') { + return deployment?.screenshotDark + ? getFilePreview(deployment.screenshotDark) + : `${base}/images/sites/screenshot-placeholder-dark.svg`; + } + + return deployment?.screenshotLight + ? getFilePreview(deployment.screenshotLight) + : `${base}/images/sites/screenshot-placeholder-light.svg`; + } + + function getFilePreview(fileId: string) { + // TODO: @Meldiron use sdk.forConsole.storage.getFilePreview + const endpoint = getApiEndpoint(); + return ( + endpoint + + `/storage/buckets/screenshots/files/${fileId}/view?project=console&mode=admin` + ); + } - + {#each siteList.sites as site} diff --git a/src/routes/(console)/project-[project]/sites/redeployModal.svelte b/src/routes/(console)/project-[project]/sites/redeployModal.svelte index 3edeb31e6..ab470db07 100644 --- a/src/routes/(console)/project-[project]/sites/redeployModal.svelte +++ b/src/routes/(console)/project-[project]/sites/redeployModal.svelte @@ -1,6 +1,6 @@ - +

- Are you sure you want to redeploy {site.name}? Redeploying may affect your production - code. + Are you sure you want to redeploy {site.name}? It may affect your production code.

-
+ diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/+page.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/+page.svelte index 89e40a717..15b8d609e 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/+page.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/+page.svelte @@ -7,37 +7,48 @@ import { Button } from '$lib/elements/forms'; import { protocol } from '$routes/(console)/store'; import InstantRollbackDomain from './instantRollbackDomain.svelte'; - import { base } from '$app/paths'; - import { page } from '$app/stores'; - import { invalidate } from '$app/navigation'; - import { Dependencies } from '$lib/constants'; import { app } from '$lib/stores/app'; import EmptyDeploymentDark from './empty-deployment-dark.svg'; import EmptyDeploymentLight from './empty-deployment-light.svg'; + import { sdk } from '$lib/stores/sdk'; + import { invalidate } from '$app/navigation'; + import { Dependencies } from '$lib/constants'; + import { onMount } from 'svelte'; + import { page } from '$app/stores'; export let data; let showRollback = false; - $: console.log(data.site); - $: console.log(data.deployment); - $: console.log(data.deploymentList); - $: console.log(data.proxyRuleList); + let unsubscribe: { (): void }; - // TODO: dark mode empty state + onMount(() => { + unsubscribe = sdk.forConsole.client.subscribe('console', (response) => { + if (response.events.includes(`sites.${$page.params.site}.deployments.*`)) { + console.log('test'); + invalidate(Dependencies.SITE); + } + }); + }); + + // $: console.log(data.site); + $: console.log(data.deployment); + // $: console.log(data.deploymentList); + // $: console.log(data.proxyRuleList); - + {#if data?.deployment && data.deployment.status === 'ready'} - + - {:else if data.deployment && data.deployment.status === 'building'} + {:else if data.deployment?.status === 'building'} - - - - + + + {:else} + + + + Deploy your site to get started. Once deployed, you'll see your latest build + details here. + {/if} diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/+page.ts b/src/routes/(console)/project-[project]/sites/site-[site]/+page.ts index b332c7dc6..cc5279589 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/+page.ts +++ b/src/routes/(console)/project-[project]/sites/site-[site]/+page.ts @@ -8,7 +8,7 @@ export const load = async ({ params, depends, parent }) => { const { site, proxyRuleList } = await parent(); const [deploymentList, prodReadyDeployments] = await Promise.all([ - sdk.forProject.sites.listDeployments(params.site, [Query.limit(5), Query.orderDesc('')]), + sdk.forProject.sites.listDeployments(params.site, [Query.limit(4), Query.orderDesc('')]), sdk.forProject.sites.listDeployments(params.site, [ Query.limit(1) // Query.equal('status', 'ready') diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/+page.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/+page.svelte index a61eaa197..e780be57f 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/+page.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/+page.svelte @@ -16,11 +16,12 @@ import { columns } from './store'; import CreateManualDeploymentModal from './createManualDeploymentModal.svelte'; import DeploymentMetrics from './deploymentMetrics.svelte'; - import { IconPlus } from '@appwrite.io/pink-icons-svelte'; + import { IconFilterLine, IconPlus } from '@appwrite.io/pink-icons-svelte'; import { onMount } from 'svelte'; import { sdk } from '$lib/stores/sdk'; import { invalidate } from '$app/navigation'; import { Dependencies } from '$lib/constants'; + import CreateCliModal from './createCliModal.svelte'; export let data; @@ -49,13 +50,13 @@ - + {#if data.deploymentList.total} {/if} - + {#if data.deploymentList.total} {#if $tags?.length} @@ -94,11 +95,12 @@ Create deployment - - + + { + on:click={(e) => { + toggle(e); if (!hasInstallation) { showConnectRepo = true; } else { @@ -108,13 +110,15 @@ Git { + on:click={(e) => { + toggle(e); showConnectCLI = true; }}> CLI { + on:click={(e) => { + toggle(e); showConnectManual = true; }}> Manual @@ -205,3 +209,6 @@ {#if showConnectManual} {/if} +{#if showConnectCLI} + +{/if} diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/createCliModal.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/createCliModal.svelte new file mode 100644 index 000000000..87f082007 --- /dev/null +++ b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/createCliModal.svelte @@ -0,0 +1,103 @@ + + + + + Deploy your site using the Appwrite CLI by running the following command inside your + function's folder. + + + + + + {#each ['Unix', 'CMD', 'PowerShell'] as cat} + (category = cat)} + active={category === cat}> + {cat} + + {/each} + + + {#each ['Unix', 'CMD', 'PowerShell'] as cat} + {#if category === cat} + + {/if} + {/each} + + + + If you did not create your site using the CLI, initialize your function by following our documentation. + + + + + + diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/createGitDeploymentModal.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/createGitDeploymentModal.svelte index 7122848cd..223784b0b 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/createGitDeploymentModal.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/createGitDeploymentModal.svelte @@ -4,80 +4,81 @@ import { Repositories } from '$lib/components/git'; import { Dependencies } from '$lib/constants'; import { Link } from '$lib/elements'; - import { Button } from '$lib/elements/forms'; - import InputSelectSearch from '$lib/elements/forms/inputSelectSearch.svelte'; + import { Button, InputCheckbox, InputSelect } from '$lib/elements/forms'; + import { timeFromNow } from '$lib/helpers/date'; import { addNotification } from '$lib/stores/notifications'; import { sdk } from '$lib/stores/sdk'; import { installation, repository, sortBranches } from '$lib/stores/vcs'; - import type { BuildRuntime, Framework, Models } from '@appwrite.io/console'; + import { Type, type Models } from '@appwrite.io/console'; import { IconGithub } from '@appwrite.io/pink-icons-svelte'; - import { Icon, InlineCode, Layout, Spinner, Typography } from '@appwrite.io/pink-svelte'; - import { onMount } from 'svelte'; + import { Icon, Layout, Skeleton, Typography } from '@appwrite.io/pink-svelte'; export let show = false; export let site: Models.Site; let installations = { installations: [], total: 0 }; let hasRepository = !!site?.providerRepositoryId; - let selectedRepository: string = null; + let selectedRepository: string = site.providerRepositoryId; let branch: string = null; + let activate = true; let error = ''; - onMount(async () => { - installations = await sdk.forProject.vcs.listInstallations(); - if (!site?.installationId && installations.total > 0) { - installation.set(installations.installations[0]); - } - if (!$repository?.id && hasRepository) { - $repository = await sdk.forProject.vcs.getRepository( - $installation.$id, - site.providerRepositoryId + async function loadInstallations() { + try { + installations = await sdk.forProject.vcs.listInstallations(); + if (!site?.installationId && installations.total > 0) { + installation.set(installations.installations[0]); + } + $installation = installations.installations.find( + (installation) => installation.$id === site.installationId ); + if (!$installation?.$id) { + $installation = installations.installations[0]; + } + } catch (error) { + console.log(error); } - console.log(installations); - }); + } - async function loadBranches() { - const { branches } = await sdk.forProject.vcs.listRepositoryBranches( - $installation.$id, - selectedRepository - ); - const sorted = sortBranches(branches); - branch = sorted[0]?.name ?? null; + async function load() { + try { + await loadInstallations(); + if (!$repository?.id && hasRepository) { + $repository = await sdk.forProject.vcs.getRepository( + $installation.$id, + site.providerRepositoryId + ); + } + const branchList = await sdk.forProject.vcs.listRepositoryBranches( + $installation.$id, + selectedRepository + ); - if (!branch) { - branch = 'main'; + console.log(branchList); + + const sorted = sortBranches(branchList.branches); + branch = sorted[0]?.name ?? null; + + if (!branch) { + branch = 'main'; + } + + return sorted; + } catch (error) { + console.log(installations); + console.log(error); } - - return sorted; } async function createDeployment() { try { - if (!site.installationId || !site.providerRepositoryId || !branch) { - await sdk.forProject.sites.update( - site.$id, - site.name, - site?.framework as Framework, - site.enabled || undefined, - site.timeout || undefined, - site.installCommand || undefined, - site.buildCommand || undefined, - site.outputDirectory || undefined, - (site?.buildRuntime as BuildRuntime) || undefined, - site.adapter || undefined, - site.fallbackFile || undefined, - site.installationId || $installation.$id || undefined, - site.providerRepositoryId || $repository.id || undefined, - branch, - site.providerSilentMode || undefined, - undefined //TODO: add dir? - ); - } + await sdk.forProject.sites.createVcsDeployment(site.$id, Type.Branch, branch, activate); show = false; invalidate(Dependencies.DEPLOYMENTS); addNotification({ - message: 'Deployment has been created successfully', + message: activate + ? 'Deployment is in progress. It will be automatically activated after build step completes.' + : 'Deployment is in progress. You can activate it after build step completes.', type: 'success' }); } catch (e) { @@ -88,26 +89,26 @@ - Enter a valid commit reference to create a new deployment from or - use the CLI to deploy. Learn more + Enter a valid commit reference to create a new deployment. Learn more - {#if installations && hasRepository} - - - - - - {$repository?.organization}/{$repository?.name} - + {#if hasRepository} + {#await load()} + + + + + + + + + + - - {#await loadBranches()} - {:then branches} {@const options = branches @@ -120,24 +121,48 @@ ?.sort((a, b) => { return a.label > b.label ? 1 : -1; }) ?? []} - - + + + + + + {$repository?.organization}/{$repository?.name} + + + + + Last updated {timeFromNow($repository?.pushedAt)} + + + + { branch = event.detail.value; }} - interactiveOutput - name="branch" {options} /> + {#if branch} + + {/if} {/await} - {/if} - {#if !hasRepository} + {:else} - + diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/deploymentMetrics.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/deploymentMetrics.svelte index 12a17f960..099dcee3d 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/deploymentMetrics.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/deploymentMetrics.svelte @@ -35,17 +35,17 @@ { id: 'avgTime', value: null, - description: 'Average builds time' + description: 'Avg. builds time' }, { id: 'success', value: null, - description: 'Successful deployments' + description: 'Successful' }, { id: 'failed', value: null, - description: 'Failed deployments' + description: 'Failed ' } ]; onMount(async () => { @@ -55,28 +55,32 @@ }); async function fetchUsage() { - metrics.forEach((metric) => { - metric.value = null; - }); - metrics = metrics; - try { - const usage = await sdk.forProject.sites.getUsage($page.params.site, range); - metrics = metrics.map((metric) => { - metric.value = usage[metric.id] ?? 'n/a'; - return metric; + // Add timeout to make it look nicer + setTimeout(async () => { + metrics.forEach((metric) => { + metric.value = null; }); metrics = metrics; - console.log(usage); - } catch (error) { - console.log(error); - } + + try { + const usage = await sdk.forProject.sites.getUsage($page.params.site, range); + metrics = metrics.map((metric) => { + metric.value = usage[metric.id] ?? '-'; + return metric; + }); + metrics = metrics; + console.log(usage); + } catch (error) { + console.log(error); + } + }, 800); } $: console.log(metrics); - + Metrics for {range !== SiteUsageRange.TwentyFourHours ? `${toLocaleDate( @@ -95,7 +99,7 @@ on:change={fetchUsage} /> - + {#each metrics as metric} {/each} diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/quickFilters.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/quickFilters.svelte index efbbe4f06..0252024c3 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/quickFilters.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/quickFilters.svelte @@ -1,7 +1,6 @@ {#each [typeFilter] as filter} - - (filter.show = !filter.show)} - event="apply_quick_filter" - eventData={{ source: 'function_deployments', column: filter.title }}> + + + {#key filter.tag} {filter?.tag ?? filter.title} {/key} - - - - - {#each filter.options as option (option.value + option.checked)} - { - option.checked = !option.checked; - addFilterAndApply( - filter.id, - filter.title, - filter.operator, - filter?.array ? null : option.checked ? option.value : null, - filter?.array - ? (filter.options - .filter((opt) => opt.checked) - .map((opt) => opt.value) ?? []) - : [] - ); - }}> - {option.label} - - {/each} - {#if filter.options.some((option) => option.checked)} - { - filter.show = false; - filter.tag = null; - addFilterAndApply(filter.id, filter.title, filter.operator, null, []); - }}> - Clear selection - - {/if} + + + + + {#each filter.options as option (option.value + option.checked)} + { + option.checked = !option.checked; + addFilterAndApply( + filter.id, + filter.title, + filter.operator, + filter?.array ? null : option.checked ? option.value : null, + filter?.array + ? (filter.options + .filter((opt) => opt.checked) + .map((opt) => opt.value) ?? []) + : [] + ); + }}> + {option.label} + + {/each} + {#if filter.options.some((option) => option.checked)} + { + filter.tag = null; + addFilterAndApply(filter.id, filter.title, filter.operator, null, []); + toggle(e); + }}> + Clear selection + + {/if} + - + {/each} {#each [sizeFilter] as filter} - - (filter.show = !filter.show)} - event="apply_quick_filter" - eventData={{ source: 'function_deployments', column: filter.title }}> + + + + {#key filter.tag} {filter?.tag ?? filter.title} {/key} - - - - - {#each filter.options as option (option.value + option.checked)} - { - filter.show = false; - addFilterAndApply( - filter.id, - filter.title, - filter.operator, - filter?.array ? null : option.value, - [] - ); - }}> - {option.label} - - {/each} - {#if filter?.tag} - { - filter.show = false; - filter.tag = null; - addFilterAndApply(filter.id, filter.title, filter.operator, null, []); - }}> - Clear selection - - {/if} + + + + + {#each filter.options as option (option.value + option.checked)} + { + addFilterAndApply( + filter.id, + filter.title, + filter.operator, + filter?.array ? null : option.value, + [] + ); + toggle(e); + }}> + {option.label} + + {/each} + {#if filter?.tag} + { + filter.show = false; + filter.tag = null; + addFilterAndApply(filter.id, filter.title, filter.operator, null, []); + }}> + Clear selection + + {/if} + - + {/each} diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/store.ts b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/store.ts index 01ce17465..a7915b8c5 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/store.ts +++ b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/store.ts @@ -21,7 +21,7 @@ export const columns = writable([ title: 'Domains', type: 'string', show: true, - width: 15, + width: 150, array: true, format: 'string', filter: false diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/table.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/table.svelte index 8dc45f6df..4fc263b15 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/deployments/table.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/deployments/table.svelte @@ -2,7 +2,7 @@ import { Id, Trim } from '$lib/components'; import type { PageData } from './$types'; import { type Models } from '@appwrite.io/console'; - import { calculateTime } from '$lib/helpers/timeConversion'; + import { formatTimeDetailed } from '$lib/helpers/timeConversion'; import DeploymentSource from '../../(components)/deploymentSource.svelte'; import DeploymentCreatedBy from '../../(components)/deploymentCreatedBy.svelte'; import { timer } from '$lib/actions/timer'; @@ -12,8 +12,9 @@ import RedeployModal from '../../redeployModal.svelte'; import Cancel from './cancelDeploymentModal.svelte'; import { base } from '$app/paths'; - import { ActionMenu, Popover, Status, Table } from '@appwrite.io/pink-svelte'; + import { ActionMenu, Icon, Layout, Popover, Status, Table } from '@appwrite.io/pink-svelte'; import { + IconDotsHorizontal, IconLightningBolt, IconRefresh, IconTerminal, @@ -24,6 +25,7 @@ import ActivateDeploymentModal from '../../activateDeploymentModal.svelte'; import { deploymentStatusConverter } from '../store'; import { capitalize } from '$lib/helpers/string'; + import { Button } from '$lib/elements/forms'; export let data: PageData; @@ -61,7 +63,7 @@ {@const status = deployment.status} {#if data?.activeDeployment?.$id === deployment?.$id} - + {:else} {:else if column.id === 'domains'} -
+
{deployment.domain} @@ -89,7 +91,7 @@ {#if ['processing', 'building'].includes(deployment.status)} {:else} - {calculateTime(deployment.buildTime)} + {formatTimeDetailed(deployment.buildTime)} {/if} {:else if column.id === 'size'} @@ -104,76 +106,82 @@ {/if} {/each} - - - - - { - e.preventDefault(); - selectedDeployment = deployment; - showRedeploy = true; - toggle(e); - }}> - Redeploy - - { - e.preventDefault(); - toggle(e); - }}> - View details - - {#if deployment?.status === 'ready' && deployment?.$id !== data.site.deploymentId} + + + + + { e.preventDefault(); selectedDeployment = deployment; - showActivate = true; + showRedeploy = true; toggle(e); }}> - Activate + Redeploy - {/if} + { + e.preventDefault(); + toggle(e); + }}> + View details + + {#if deployment?.status === 'ready' && deployment?.$id !== data.site.deploymentId} + { + e.preventDefault(); + selectedDeployment = deployment; + showActivate = true; + toggle(e); + }}> + Activate + + {/if} - {#if deployment?.status === 'processing' || deployment?.status === 'building' || deployment.status === 'waiting'} - { - e.preventDefault(); - selectedDeployment = deployment; - showCancel = true; - toggle(e); - }}> - Cancel - - {/if} - {#if deployment.status !== 'building' && deployment.status !== 'processing' && deployment?.status !== 'waiting'} - { - e.preventDefault(); - selectedDeployment = deployment; - showDelete = true; - toggle(e); - }}> - Delete - - {/if} - - - + {#if deployment?.status === 'processing' || deployment?.status === 'building' || deployment.status === 'waiting'} + { + e.preventDefault(); + selectedDeployment = deployment; + showCancel = true; + toggle(e); + }}> + Cancel + + {/if} + {#if deployment.status !== 'building' && deployment.status !== 'processing' && deployment?.status !== 'waiting'} + { + e.preventDefault(); + selectedDeployment = deployment; + showDelete = true; + toggle(e); + }}> + Delete + + {/if} + + + + {/each} diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/deploymentsOverview.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/deploymentsOverview.svelte index cb323a647..fdba19de6 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/deploymentsOverview.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/deploymentsOverview.svelte @@ -2,6 +2,7 @@ import { ActionMenu, Badge, + Empty, Icon, Layout, Popover, @@ -26,6 +27,8 @@ import { Card } from '$lib/components'; import ActivateDeploymentModal from '../activateDeploymentModal.svelte'; import CancelDeploymentModal from './deployments/cancelDeploymentModal.svelte'; + import { capitalize } from '$lib/helpers/string'; + import { deploymentStatusConverter } from './store'; export let site: Models.Site; export let activeDeployment: Models.Deployment; @@ -37,58 +40,56 @@ let selectedDeployment: Models.Deployment = null; -{#if deploymentList.total} - - - - Deployments - - + + + + + Deployments + - {#if deploymentList?.total} - - - Deployment ID - Status - Source - Updated - - - {#each deploymentList?.deployments as deployment} - - - {deployment.$id} - - - {@const status = deployment.status} - {#if activeDeployment?.$id === deployment?.$id} - - {:else} - - {/if} - + + + {#if deploymentList?.total} + + + Deployment ID + Status + Source + Updated + + + {#each deploymentList?.deployments as deployment} + + + {deployment.$id} + + + {@const status = deployment.status} + {#if activeDeployment?.$id === deployment?.$id} + + {:else} + + {/if} + - - - - - - - + + + + + + + + + + - - - {/each} - - {/if} - -{:else} - - No deployments exist - -{/if} + + + + {/each} + + {:else} + + + + Deployments are created when you deploy your site. You can deploy your site + using the CLI, Git, or manually. + + + + {/if} + {#if selectedDeployment && showRedeploy} diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/domains/deleteDomainModal.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/domains/deleteDomainModal.svelte index 37d8c9b19..f3bcf72d9 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/domains/deleteDomainModal.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/domains/deleteDomainModal.svelte @@ -34,7 +34,7 @@ {#if selectedDomain}

Are you sure you want to delete {selectedDomain.domain}? You will no longer be - able to execute your function by visiting this domain. + able to view your site by visiting this domain.

{/if} - Domains + + Domains + + +
- - - {#if i < 2 && i < proxyRuleList.rules.length - 1} - + {#if proxyRuleList?.rules?.length} + + {/if} {/if} - {/each} + {#each proxyRuleList?.rules?.slice(0, 3) as rule, i} + + + + + + {rule.domain} + + + + + + Added {timeFromNow(rule.$createdAt)} + + + + + {#if i < 2 && i < proxyRuleList.rules.length - 1} + + {/if} + {/each} + diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/empty-deployment-dark.svg b/src/routes/(console)/project-[project]/sites/site-[site]/empty-deployment-dark.svg index 997bad861..414175d0a 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/empty-deployment-dark.svg +++ b/src/routes/(console)/project-[project]/sites/site-[site]/empty-deployment-dark.svg @@ -1,93 +1,93 @@ - - - - - + + + + + - - + + - - + + - - + + -
- - +
+ + - - - + + + - - - + + + - - - - - - - + + + + + + + - + - + - + - + - + - + - + - + - - + + - - + + - - + + - + - + - + - + - + - + - - + +
diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/empty-deployment-light.svg b/src/routes/(console)/project-[project]/sites/site-[site]/empty-deployment-light.svg index 997bad861..60330bcaf 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/empty-deployment-light.svg +++ b/src/routes/(console)/project-[project]/sites/site-[site]/empty-deployment-light.svg @@ -1,93 +1,93 @@ - - - - - + + + + + - - + + - - + + - - + + -
- - +
+ + - - - + + + - - - + + + - - - - - - - + + + + + + + - + - + - + - + - + - + - + - + - - + + - - + + - + - + - + - + - + - - + +
diff --git a/src/routes/(console)/project-[project]/sites/site-[site]/header.svelte b/src/routes/(console)/project-[project]/sites/site-[site]/header.svelte index 9d7bcf309..664ad1314 100644 --- a/src/routes/(console)/project-[project]/sites/site-[site]/header.svelte +++ b/src/routes/(console)/project-[project]/sites/site-[site]/header.svelte @@ -1,7 +1,7 @@
Editor - - - +
-
- - - - + + + + + { + selectedVar = variable; + showVariablesDropdown[i] = false; + showVariablesModal = true; + toggle(e); + }}> + Edit + + {#if !isGlobal} { + trailingIcon={IconGlobeAlt} + on:click={async (e) => { selectedVar = variable; showVariablesDropdown[i] = false; - showVariablesModal = true; + showPromoteModal = true; toggle(e); }}> - Edit + Promote - - {#if !isGlobal} - { - selectedVar = variable; - showVariablesDropdown[i] = false; - showPromoteModal = true; - toggle(e); - }}> - Promote - - {/if} - { - handleVariableDeleted(variable); - showVariablesDropdown[i] = false; - toggle(e); - }}> - Delete - - - - -
+ {/if} + { + handleVariableDeleted(variable); + showVariablesDropdown[i] = false; + toggle(e); + }}> + Delete + +
+
+ {/each} - -

Total variables: {sum}

- -
+ {#if sum > limit} + +

Total variables: {sum}

+ +
+ {/if}
{:else} (showVariablesModal = true)}> Create a {isGlobal ? 'global variable' : 'variable'} to get started {/if} + + + +
diff --git a/src/routes/(console)/project-[project]/uploadVariablesModal.svelte b/src/routes/(console)/project-[project]/uploadVariablesModal.svelte index 10a324399..faf99c413 100644 --- a/src/routes/(console)/project-[project]/uploadVariablesModal.svelte +++ b/src/routes/(console)/project-[project]/uploadVariablesModal.svelte @@ -4,6 +4,8 @@ import { Button, InputFile } from '$lib/elements/forms'; import { addNotification } from '$lib/stores/notifications'; import type { Models } from '@appwrite.io/console'; + import { IconInfo } from '@appwrite.io/pink-icons-svelte'; + import { Icon, Layout, Tooltip, Typography, Upload } from '@appwrite.io/pink-svelte'; import { parse } from 'envfile'; export let isGlobal: boolean; @@ -85,7 +87,13 @@ {/if} - + + + + Upload a file + + + diff --git a/src/themes/dark-cloud.json b/src/themes/dark-cloud.json index 248178d8a..3cf55bc71 100644 --- a/src/themes/dark-cloud.json +++ b/src/themes/dark-cloud.json @@ -184,6 +184,7 @@ "gap-l": "var(--base-16)", "gap-xl": "var(--base-20)", "gap-xxl": "var(--base-32)", + "gap-xxxl": "var(--base-40)", "border-width-m": "1.2000000476837158px", "border-width-l": "2px", "border-width-xl": "3px", diff --git a/src/themes/dark.json b/src/themes/dark.json index e9c21f808..589c49c29 100644 --- a/src/themes/dark.json +++ b/src/themes/dark.json @@ -185,6 +185,7 @@ "gap-l": "var(--base-16)", "gap-xl": "var(--base-20)", "gap-xxl": "var(--base-32)", + "gap-xxxl": "var(--base-40)", "border-width-m": "1.2000000476837158px", "border-width-l": "2px", "border-width-xl": "3px", diff --git a/src/themes/light-cloud.json b/src/themes/light-cloud.json index e7219a7bd..00f48ae17 100644 --- a/src/themes/light-cloud.json +++ b/src/themes/light-cloud.json @@ -92,7 +92,7 @@ "color-border-neutral-stronger": "var(--neutral-500)", "color-fgcolor-on-warning-weak": "var(--web-orange-700)", "color-border-neutral-strongest": "var(--neutral-900)", - "color-border-focus": "var(--neutral-500)", + "color-border-focus": "var(--neutral-300)", "color-border-accent": "var(--brand-pink-500)", "color-border-accent-secondary": "var(--brand-pink-600)", "color-border-success": "var(--web-green-500)", @@ -184,6 +184,7 @@ "gap-l": "var(--base-16)", "gap-xl": "var(--base-20)", "gap-xxl": "var(--base-32)", + "gap-xxxl": "var(--base-40)", "border-width-m": "1.2000000476837158px", "border-width-l": "2px", "border-width-xl": "3px", diff --git a/src/themes/light.json b/src/themes/light.json index 65d4883dc..9a68a639a 100644 --- a/src/themes/light.json +++ b/src/themes/light.json @@ -92,7 +92,7 @@ "color-border-neutral-stronger": "var(--neutral-500)", "color-fgcolor-on-warning-weak": "var(--web-orange-700)", "color-border-neutral-strongest": "var(--neutral-900)", - "color-border-focus": "var(--neutral-500)", + "color-border-focus": "var(--neutral-300)", "color-border-accent": "var(--brand-pink-500)", "color-border-accent-secondary": "var(--brand-pink-600)", "color-border-success": "var(--web-green-500)", @@ -185,6 +185,7 @@ "gap-l": "var(--base-16)", "gap-xl": "var(--base-20)", "gap-xxl": "var(--base-32)", + "gap-xxxl": "var(--base-40)", "border-width-m": "1.2000000476837158px", "border-width-l": "2px", "border-width-xl": "3px", diff --git a/static/images/sites/templates/starter-for-nuxt.png b/static/images/sites/templates/starter-for-nuxt.png new file mode 100644 index 000000000..c2718d2d8 Binary files /dev/null and b/static/images/sites/templates/starter-for-nuxt.png differ diff --git a/static/images/sites/templates/starter-for-react-native.png b/static/images/sites/templates/starter-for-react-native.png new file mode 100644 index 000000000..3c880e30b Binary files /dev/null and b/static/images/sites/templates/starter-for-react-native.png differ diff --git a/static/images/sites/templates/starter-for-react.png b/static/images/sites/templates/starter-for-react.png new file mode 100644 index 000000000..871bba220 Binary files /dev/null and b/static/images/sites/templates/starter-for-react.png differ diff --git a/static/images/sites/templates/starter-for-vue.png b/static/images/sites/templates/starter-for-vue.png new file mode 100644 index 000000000..bdf3e67ee Binary files /dev/null and b/static/images/sites/templates/starter-for-vue.png differ diff --git a/static/images/sites/templates/template-for-onelink.png b/static/images/sites/templates/template-for-onelink.png new file mode 100644 index 000000000..d42b5faa5 Binary files /dev/null and b/static/images/sites/templates/template-for-onelink.png differ