add screenshotsGenerated metric across console

This commit is contained in:
Harsh Mahajan
2025-11-03 20:12:25 +00:00
parent c5fd02a363
commit b7e99baeef
10 changed files with 132 additions and 9 deletions
+1 -1
View File
@@ -22,7 +22,7 @@
},
"dependencies": {
"@ai-sdk/svelte": "^1.1.24",
"@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e",
"@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@0aa6399",
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@46f65c7",
"@appwrite.io/pink-legacy": "^1.0.3",
+5 -5
View File
@@ -12,8 +12,8 @@ importers:
specifier: ^1.1.24
version: 1.1.24(svelte@5.25.3)(zod@3.24.3)
'@appwrite.io/console':
specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e
version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e
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
@@ -260,8 +260,8 @@ packages:
'@analytics/type-utils@0.6.2':
resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==}
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e':
resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e}
'@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':
@@ -3703,7 +3703,7 @@ snapshots:
'@analytics/type-utils@0.6.2': {}
'@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e': {}
'@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.25.3)':
dependencies:
+5
View File
@@ -292,12 +292,14 @@ export type OrganizationUsage = {
databasesReads: Array<Models.Metric>;
databasesWrites: Array<Models.Metric>;
imageTransformations: Array<Models.Metric>;
screenshotsGenerated: Array<Models.Metric>;
executionsTotal: number;
filesStorageTotal: number;
buildsStorageTotal: number;
databasesReadsTotal: number;
databasesWritesTotal: number;
imageTransformationsTotal: number;
screenshotsGeneratedTotal: number;
deploymentsStorageTotal: number;
executionsMBSecondsTotal: number;
buildsMBSecondsTotal: number;
@@ -316,6 +318,7 @@ export type OrganizationUsage = {
authPhoneTotal: number;
authPhoneEstimate: number;
imageTransformations: number;
screenshotsGenerated: number;
}>;
authPhoneTotal: number;
authPhoneEstimate: number;
@@ -384,6 +387,7 @@ export type Plan = {
bandwidth: number;
storage: number;
imageTransformations: number;
screenshotsGenerated: number;
webhooks: number;
users: number;
teams: number;
@@ -411,6 +415,7 @@ export type Plan = {
databasesWrites: AdditionalResource;
GBHours: AdditionalResource;
imageTransformations: AdditionalResource;
screenshotsGenerated: AdditionalResource;
};
addons: {
seats: PlanAddon;
+10
View File
@@ -332,4 +332,14 @@ export type UsageProject = {
* Aggregated statistics of total number of image transformations.
*/
imageTransformationsTotal: number;
/**
* Array of screenshots generated per period.
*/
screenshotsGenerated: Metric[];
/**
* Aggregated statistics of total number of screenshots generated.
*/
screenshotsGeneratedTotal: number;
};
+2 -1
View File
@@ -150,7 +150,8 @@ export type PlanServices =
| 'webhooks'
| 'sites'
| 'authPhone'
| 'imageTransformations';
| 'imageTransformations'
| 'screenshotsGenerated';
export function getServiceLimit(serviceId: PlanServices, tier: Tier = null, plan?: Plan): number {
if (!isCloud) return 0;
@@ -127,6 +127,9 @@
imageTransformations: projectData?.resources?.find(
(resource) => resource.resourceId === 'imageTransformations'
),
screenshotsGenerated: projectData?.resources?.find(
(resource) => resource.resourceId === 'screenshotsGenerated'
),
bandwidth: projectData?.resources?.find(
(resource) => resource.resourceId === 'bandwidth'
),
@@ -280,6 +283,19 @@
),
maxValue: currentPlan?.imageTransformations
},
{
id: `screenshots-generated`,
cells: {
item: 'Screenshots generated',
usage: `${formatNum(project.screenshotsGenerated.value || 0)} / ${currentPlan?.screenshotsGenerated ? formatNum(currentPlan.screenshotsGenerated) : 'Unlimited'}`,
price: formatCurrency(project.screenshotsGenerated.amount || 0)
},
progressData: createProgressData(
project.screenshotsGenerated.value || 0,
currentPlan?.screenshotsGenerated
),
maxValue: currentPlan?.screenshotsGenerated
},
{
id: `gb-hours`,
cells: {
@@ -322,6 +322,53 @@
</svelte:fragment>
</CardGrid>
<CardGrid gap="none">
<svelte:fragment slot="title">Screenshots generated</svelte:fragment>
The total number of screenshots generated across all projects in your organization.
<svelte:fragment slot="aside">
{#if data.organizationUsage.screenshotsGeneratedTotal}
{@const current = data.organizationUsage.screenshotsGeneratedTotal}
{@const max = getServiceLimit('screenshotsGenerated', tier, plan)}
<ProgressBarBig
currentUnit="Screenshots"
currentValue={formatNum(current)}
maxValue={max ? `/ ${formatNum(max)}` : undefined}
progressValue={current}
progressMax={max}
showBar={false} />
<BarChart
options={{
yAxis: {
axisLabel: {
formatter: formatNum
}
}
}}
series={[
{
name: 'Screenshots generated',
data: [
...(data.organizationUsage.screenshotsGenerated ?? []).map((e) => [
e.date,
e.value
])
]
}
]} />
{#if projects?.length > 0}
<ProjectBreakdown {projects} metric="screenshotsGenerated" {usageProjects} />
{/if}
{:else}
<Card isDashed>
<Layout.Stack gap="xs" alignItems="center" justifyContent="center">
<Icon icon={IconChartSquareBar} size="l" />
<Typography.Text variant="m-600">No data to show</Typography.Text>
</Layout.Stack>
</Card>
{/if}
</svelte:fragment>
</CardGrid>
<CardGrid gap="none">
<svelte:fragment slot="title">Executions</svelte:fragment>
Calculated for all functions that are executed in all projects in your organization.
@@ -34,7 +34,9 @@ export const load: PageLoad = async ({ params, parent }) => {
databasesReadsTotal: null,
databasesWritesTotal: null,
imageTransformations: null,
imageTransformationsTotal: null
imageTransformationsTotal: null,
screenshotsGenerated: null,
screenshotsGeneratedTotal: null
}
};
}
@@ -16,7 +16,8 @@
| 'authPhoneTotal'
| 'databasesReads'
| 'databasesWrites'
| 'imageTransformations';
| 'imageTransformations'
| 'screenshotsGenerated';
type Estimate = 'authPhoneEstimate';
@@ -89,6 +90,7 @@
switch (metric) {
case 'imageTransformations':
case 'screenshotsGenerated':
case 'authPhoneTotal':
return formatNumberWithCommas(value);
case 'executions':
@@ -30,6 +30,8 @@
data.usage.buildsStorageTotal;
$: imageTransformations = data.usage.imageTransformations;
$: imageTransformationsTotal = data.usage.imageTransformationsTotal;
$: screenshotsGenerated = (data.usage as any).screenshotsGenerated ?? null;
$: screenshotsGeneratedTotal = (data.usage as any).screenshotsGeneratedTotal ?? 0;
$: dbReads = data.usage.databasesReads;
$: dbWrites = data.usage.databasesWrites;
@@ -241,6 +243,44 @@
{/if}
</svelte:fragment>
</CardGrid>
<CardGrid>
<svelte:fragment slot="title">Screenshots generated</svelte:fragment>
Total number of screenshots generated in your project.
<svelte:fragment slot="aside">
{#if screenshotsGenerated}
{@const current = formatNum(screenshotsGeneratedTotal)}
<div class="u-flex u-flex-vertical">
<div class="u-flex u-main-space-between">
<p>
<span class="heading-level-4">{current}</span>
<span class="body-text-1 u-bold">Screenshots</span>
</p>
</div>
</div>
<BarChart
options={{
yAxis: {
axisLabel: {
formatter: formatNum
}
}
}}
series={[
{
name: 'Screenshots generated',
data: [...screenshotsGenerated.map((e) => [e.date, e.value])]
}
]} />
{:else}
<Card isDashed>
<Layout.Stack gap="xs" alignItems="center" justifyContent="center">
<Icon icon={IconChartSquareBar} size="l" />
<Typography.Text variant="m-600">No data to show</Typography.Text>
</Layout.Stack>
</Card>
{/if}
</svelte:fragment>
</CardGrid>
<CardGrid>
<svelte:fragment slot="title">Executions</svelte:fragment>
Calculated for all functions that are executed in this project.