From 9be160a51faad089eb8bcd35baa14971d4be8505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Gr=C3=BCneberg?= Date: Tue, 2 Apr 2024 22:12:28 +0800 Subject: [PATCH] feat: add supavisor egress breakdown (#22375) --- .../content/guides/platform/billing-faq.mdx | 2 +- .../Organization/Usage/Usage.constants.tsx | 3 ++- .../Charts/ChartHandler.types.ts | 1 - .../to-be-cleaned/Charts/ChartRenderer.tsx | 20 +++++++++---------- apps/studio/data/analytics/constants.ts | 1 - .../data/analytics/org-daily-stats-query.ts | 1 + .../api/projects/[ref]/infra-monitoring.ts | 1 - packages/shared-data/pricing.ts | 2 +- 8 files changed, 14 insertions(+), 17 deletions(-) diff --git a/apps/docs/content/guides/platform/billing-faq.mdx b/apps/docs/content/guides/platform/billing-faq.mdx index 6616ce86ccc..4c29c53557b 100644 --- a/apps/docs/content/guides/platform/billing-faq.mdx +++ b/apps/docs/content/guides/platform/billing-faq.mdx @@ -64,7 +64,7 @@ Read more on [how billing for compute works](https://supabase.com/docs/guides/pl #### What is unified egress and how is it billed? -Unified egress refers to the total egress quota available to each organization. This quota can be utilized for various purposes such as Storage, Runtime, Auth, Functions, and Database. Each plan includes a specific egress quota, and any additional usage beyond that quota is billed accordingly. +Unified egress refers to the total egress quota available to each organization. This quota can be utilized for various purposes such as Storage, Realtime, Auth, Functions, Supavisor and Database. Each plan includes a specific egress quota, and any additional usage beyond that quota is billed accordingly. To learn more about unified egress and its details, please refer to the information provided [here](https://supabase.com/docs/guides/platform/org-based-billing#:~:text=running%20any%20projects.-,Unified%20egress,-%23). diff --git a/apps/studio/components/interfaces/Organization/Usage/Usage.constants.tsx b/apps/studio/components/interfaces/Organization/Usage/Usage.constants.tsx index 2e40f2ea751..ef3afbb64ac 100644 --- a/apps/studio/components/interfaces/Organization/Usage/Usage.constants.tsx +++ b/apps/studio/components/interfaces/Organization/Usage/Usage.constants.tsx @@ -83,11 +83,12 @@ export const USAGE_CATEGORIES: CategoryMeta[] = [ { key: EgressType.STORAGE, name: 'Storage Egress', color: 'blue' }, { key: EgressType.REALTIME, name: 'Realtime Egress', color: 'orange' }, { key: EgressType.FUNCTIONS, name: 'Functions Egress', color: 'purple' }, + { key: EgressType.SUPAVISOR, name: 'Supavisor Egress', color: 'red' }, ], name: 'Total Egress', unit: 'bytes', description: - 'Contains any outgoing traffic (egress) from your database.\nBilling is based on the total sum of egress in GB throughout your billing period.', + 'Contains any outgoing traffic (includes Database, Storage, Realtime, Auth, API, Edge Functions, Supavisor) from your database.\nBilling is based on the total sum of egress in GB throughout your billing period.', chartDescription: 'The data refreshes every 24 hours.', }, ], diff --git a/apps/studio/components/to-be-cleaned/Charts/ChartHandler.types.ts b/apps/studio/components/to-be-cleaned/Charts/ChartHandler.types.ts index 9cfdbbf1429..e6b0f65b178 100644 --- a/apps/studio/components/to-be-cleaned/Charts/ChartHandler.types.ts +++ b/apps/studio/components/to-be-cleaned/Charts/ChartHandler.types.ts @@ -3,7 +3,6 @@ export interface ChartData { yAxisLimit?: number maximum?: number total: number - totalAverage: number totalGrouped: Attribute data: DataPoint[] } diff --git a/apps/studio/components/to-be-cleaned/Charts/ChartRenderer.tsx b/apps/studio/components/to-be-cleaned/Charts/ChartRenderer.tsx index ff6e0ee43da..cfd484c30d3 100644 --- a/apps/studio/components/to-be-cleaned/Charts/ChartRenderer.tsx +++ b/apps/studio/components/to-be-cleaned/Charts/ChartRenderer.tsx @@ -46,17 +46,19 @@ const Header = ({ let title = '' + const isByteAttribute = + format === 'bytes' || + attribute.includes('ingress') || + attribute.includes('egress') || + attribute.includes('bytes') + if (focus) { if (!data) { title = '' } else if (format === '%') { title = Number(data[focus]?.[attribute]).toFixed(2) } else { - if ( - attribute.includes('ingress') || - attribute.includes('egress') || - attribute.includes('bytes') - ) { + if (isByteAttribute) { title = formatBytes(data[focus]?.[attribute]) } else { title = data[focus]?.[attribute]?.toLocaleString() @@ -66,11 +68,7 @@ const Header = ({ if (format === '%' && highlightedValue) { title = highlightedValue.toFixed(2) } else { - if ( - attribute.includes('ingress') || - attribute.includes('egress') || - attribute.includes('bytes') - ) { + if (isByteAttribute) { title = formatBytes(highlightedValue) } else { title = highlightedValue?.toLocaleString() @@ -91,7 +89,7 @@ const Header = ({ } > {title} - {format} + {!isByteAttribute && {format}} ) const date = ( diff --git a/apps/studio/data/analytics/constants.ts b/apps/studio/data/analytics/constants.ts index 2ae4371e2fe..556dc996957 100644 --- a/apps/studio/data/analytics/constants.ts +++ b/apps/studio/data/analytics/constants.ts @@ -12,7 +12,6 @@ export interface AnalyticsData { data: DataPoint[] format: string total: number - totalAverage: number yAxisLimit: number hasNoData?: boolean } diff --git a/apps/studio/data/analytics/org-daily-stats-query.ts b/apps/studio/data/analytics/org-daily-stats-query.ts index 1262a94bc3d..ba7bb6917d7 100644 --- a/apps/studio/data/analytics/org-daily-stats-query.ts +++ b/apps/studio/data/analytics/org-daily-stats-query.ts @@ -11,6 +11,7 @@ export enum EgressType { STORAGE = 'egress_storage', REALTIME = 'egress_realtime', FUNCTIONS = 'egress_functions', + SUPAVISOR = 'egress_supavisor', UNIFIED = 'egress', } diff --git a/apps/studio/pages/api/projects/[ref]/infra-monitoring.ts b/apps/studio/pages/api/projects/[ref]/infra-monitoring.ts index 35523e117a2..4a954d96839 100644 --- a/apps/studio/pages/api/projects/[ref]/infra-monitoring.ts +++ b/apps/studio/pages/api/projects/[ref]/infra-monitoring.ts @@ -21,7 +21,6 @@ const handleGetAll = async (req: NextApiRequest, res: NextApiResponse) => { data: [], yAxisLimit: 0, format: '%', - totalAverage: 0, total: 0, } return res.status(200).json(response) diff --git a/packages/shared-data/pricing.ts b/packages/shared-data/pricing.ts index df20e5a6875..d78eb0bcd0e 100644 --- a/packages/shared-data/pricing.ts +++ b/packages/shared-data/pricing.ts @@ -112,7 +112,7 @@ export const pricing: Pricing = { { title: 'Bandwidth', tooltips: { - main: 'Billing is based on the total sum of all outgoing traffic (includes Database, Storage, Realtime, Auth, API, Edge Functions) in GB throughout your billing period.', + main: 'Billing is based on the total sum of all outgoing traffic (includes Database, Storage, Realtime, Auth, API, Edge Functions, Supavisor) in GB throughout your billing period.', }, plans: { free: '5 GB included',