diff --git a/src/lib/components/progressBarBig.svelte b/src/lib/components/progressBarBig.svelte index 68132f8938..4bd00e6258 100644 --- a/src/lib/components/progressBarBig.svelte +++ b/src/lib/components/progressBarBig.svelte @@ -1,34 +1,34 @@

- {used} - {unit} + {currentValue} + {currentUnit}

{progress}%

- {formatNumber ? abbreviateNumber(max) : max} - {unit} + {maxValue} + {maxUnit}

-
+ {#if showBar} +
= 75 && progress < 100} + class:is-danger={progress >= 100} + style:--graph-size={progress + '%'} /> + {/if}
diff --git a/src/lib/helpers/date.ts b/src/lib/helpers/date.ts index cc3e351777..c8aaf0fc86 100644 --- a/src/lib/helpers/date.ts +++ b/src/lib/helpers/date.ts @@ -69,3 +69,11 @@ export function hoursToDays(hours: number) { return `${hours} hour`; } } + +export function getTomorrow(date: Date) { + const tomorrow = new Date(date); + tomorrow.setDate(tomorrow.getDate() + 2); + tomorrow.setHours(0, 0, 0, 0); + + return tomorrow; +} diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index 09ec9294ee..1d785bf989 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -164,6 +164,13 @@ export type OrganizationUsage = { executions: number; storage: number; users: Array; + projects: Array<{ + projectId: string; + storage: number; + executions: number; + bandwidth: number; + users: number; + }>; }; export type AggregationList = { diff --git a/src/routes/console/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/console/organization-[organization]/usage/[[invoice]]/+page.svelte index 2ceac055e3..e0a29becf2 100644 --- a/src/routes/console/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/console/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -8,14 +8,18 @@ import { page } from '$app/stores'; import { goto } from '$app/navigation'; import { toLocaleDate } from '$lib/helpers/date.js'; + import { bytesToSize, humanFileSize } from '$lib/helpers/sizeConvertion'; + import { abbreviateNumber } from '$lib/helpers/numbers'; + import { BarChart } from '$lib/charts'; import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte'; + import ProjectBreakdown from './ProjectBreakdown.svelte'; export let data; const tier = data?.currentInvoice?.tier ?? $organization?.billingPlan; const plan = tierToPlan(tier).name; - let invoice = 'current'; + let invoice = null; async function handlePeriodChange() { const target = invoice @@ -56,7 +60,6 @@

Usage period:

- + ]} />
@@ -82,10 +85,28 @@

+ {@const current = data.organizationUsage.bandwidth[0]?.value ?? 0} + {@const currentHumanized = humanFileSize(current)} + {@const max = getServiceLimit('bandwidth', tier)} + currentUnit={currentHumanized.unit} + currentValue={currentHumanized.value} + maxUnit="GB" + maxValue={max.toString()} + progressValue={bytesToSize(current, 'GB')} + progressMax={max} + showBar={false} /> + [e.date, e.value])] + } + ]} /> + @@ -95,10 +116,24 @@

The total number of users across all projects in your organization.

+ {@const current = data.organizationUsage.users[0]?.value ?? 0} + {@const max = getServiceLimit('users', tier)} + currentUnit="Users" + currentValue={current.toString()} + maxUnit="Users" + maxValue={abbreviateNumber(max)} + progressValue={current} + progressMax={max} + showBar={false} /> + [e.date, e.value])] + } + ]} /> + @@ -110,10 +145,19 @@

+ {@const current = data.organizationUsage.executions} + {@const max = getServiceLimit('executions', tier)} + currentUnit="Executions" + currentValue={current.toString()} + maxUnit="Executions" + maxValue={abbreviateNumber(max)} + progressValue={current} + progressMax={max} /> + @@ -121,14 +165,22 @@ Storage

- Calculated for all storage operations across all projects in your organization. + Calculated for all your files, deployments, builds and databases. While in beta, only + file storage is counted against your plan limits.

+ {@const current = data.organizationUsage.storage} + {@const currentHumanized = humanFileSize(current)} + {@const max = getServiceLimit('storage', tier)} + currentUnit={currentHumanized.unit} + currentValue={currentHumanized.value} + maxUnit="GB" + maxValue={max.toString()} + progressValue={bytesToSize(current, 'GB')} + progressMax={max} /> + diff --git a/src/routes/console/organization-[organization]/usage/[[invoice]]/+page.ts b/src/routes/console/organization-[organization]/usage/[[invoice]]/+page.ts index c2f3584748..e5b8891759 100644 --- a/src/routes/console/organization-[organization]/usage/[[invoice]]/+page.ts +++ b/src/routes/console/organization-[organization]/usage/[[invoice]]/+page.ts @@ -2,12 +2,15 @@ import { sdk } from '$lib/stores/sdk'; import type { PageLoad } from './$types'; import type { Organization } from '$lib/stores/organization'; import type { Invoice } from '$lib/sdk/billing'; +import { getTomorrow } from '$lib/helpers/date'; +import { Query } from '@appwrite.io/console'; export const load: PageLoad = async ({ params, parent }) => { const { invoice } = params; const parentData = await parent(); const org = parentData.organization as Organization; - const today = new Date().toISOString(); + const tomorrow = getTomorrow(new Date()); + let startDate: string; let endDate: string; let currentInvoice: Invoice | null = null; @@ -18,7 +21,7 @@ export const load: PageLoad = async ({ params, parent }) => { endDate = currentInvoice.to; } else { startDate = org.billingCurrentInvoiceDate; - endDate = today; + endDate = tomorrow.toISOString(); } const [invoices, usage] = await Promise.all([ @@ -26,8 +29,16 @@ export const load: PageLoad = async ({ params, parent }) => { sdk.forConsole.billing.listUsage(params.organization, startDate, endDate) ]); + const projectNames = await sdk.forConsole.projects.list([ + Query.equal( + '$id', + usage.projects.map((p) => p.projectId) + ) + ]); + return { organizationUsage: usage, + projectNames: projectNames.projects, invoices, currentInvoice }; diff --git a/src/routes/console/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte b/src/routes/console/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte new file mode 100644 index 0000000000..d553efc80b --- /dev/null +++ b/src/routes/console/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte @@ -0,0 +1,82 @@ + + + + + Project breakdown +
+ + + Project + Usage + + + + {#each groupByProject(metric) as project} + + + {getProjectName(project.projectId)} + + {format(project.usage)} + View project usage + + {/each} + +
+
+
+