diff --git a/apps/studio/components/ui/Charts/ComposedChart.tsx b/apps/studio/components/ui/Charts/ComposedChart.tsx
index 8a57a190b78b4..0c36f49f72e14 100644
--- a/apps/studio/components/ui/Charts/ComposedChart.tsx
+++ b/apps/studio/components/ui/Charts/ComposedChart.tsx
@@ -28,8 +28,12 @@ import {
} from './Charts.constants'
import { CommonChartProps, Datum } from './Charts.types'
import { numberFormatter, useChartSize } from './Charts.utils'
-import { calculateTotalChartAggregate, CustomLabel, CustomTooltip } from './ComposedChart.utils'
-import { MultiAttribute } from './ComposedChartHandler'
+import {
+ calculateTotalChartAggregate,
+ CustomLabel,
+ CustomTooltip,
+ type MultiAttribute,
+} from './ComposedChart.utils'
import NoDataPlaceholder from './NoDataPlaceholder'
import { ChartHighlight } from './useChartHighlight'
import { formatBytes } from 'lib/helpers'
@@ -202,11 +206,10 @@ export default function ComposedChart({
const isDiskSpaceChart = chartData?.some((att: any) =>
att.name.toLowerCase().includes('disk_space_')
)
- const isDBSizeChart = chartData?.some((att: any) =>
- att.name.toLowerCase().includes('pg_database_size')
- )
+ const isDiskSizeChart = chartData?.some((att: any) => att.name.toLowerCase().includes('disk_fs_'))
const isNetworkChart = chartData?.some((att: any) => att.name.toLowerCase().includes('network_'))
- const shouldFormatBytes = isRamChart || isDiskSpaceChart || isDBSizeChart || isNetworkChart
+ const shouldFormatBytes = isRamChart || isDiskSpaceChart || isDiskSizeChart || isNetworkChart
+
//*
// Set the y-axis domain
// to the highest value in the chart data for percentage charts
diff --git a/apps/studio/components/ui/Charts/ComposedChart.utils.tsx b/apps/studio/components/ui/Charts/ComposedChart.utils.tsx
index 16578ee99da55..95444d5223059 100644
--- a/apps/studio/components/ui/Charts/ComposedChart.utils.tsx
+++ b/apps/studio/components/ui/Charts/ComposedChart.utils.tsx
@@ -5,9 +5,68 @@ import { useState } from 'react'
import { cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
import { CHART_COLORS, DateTimeFormats } from './Charts.constants'
import { numberFormatter } from './Charts.utils'
-import { MultiAttribute } from './ComposedChartHandler'
import { formatBytes } from 'lib/helpers'
+export interface ReportAttributes {
+ id?: string
+ label: string
+ attributes?: (MultiAttribute | false)[]
+ defaultChartStyle?: 'bar' | 'line' | 'stackedAreaLine'
+ hide?: boolean
+ hideChartType?: boolean
+ format?: string
+ className?: string
+ showTooltip?: boolean
+ showLegend?: boolean
+ showTotal?: boolean
+ showMaxValue?: boolean
+ valuePrecision?: number
+ docsUrl?: string
+ syncId?: string
+ showGrid?: boolean
+ YAxisProps?: {
+ width?: number
+ tickFormatter?: (value: any) => string
+ }
+ hideHighlightedValue?: boolean
+}
+
+type Provider = 'infra-monitoring' | 'daily-stats' | 'reference-line' | 'combine'
+
+export type MultiAttribute = {
+ attribute: string
+ provider: Provider
+ label?: string
+ color?: string
+ stackId?: string
+ format?: string
+ description?: string
+ docsLink?: string
+ isMaxValue?: boolean
+ type?: 'line' | 'area-bar'
+ omitFromTotal?: boolean
+ tooltip?: string
+ customValue?: number
+ /**
+ * Manipulate the value of the attribute before it is displayed on the chart.
+ * @param value - The value of the attribute.
+ * @returns The manipulated value.
+ */
+ manipulateValue?: (value: number) => number
+ /**
+ * Create a virtual attribute by combining values from other attributes.
+ * Expression should use attribute names and basic math operators (+, -, *, /).
+ * Example: 'disk_fs_used - pg_database_size - disk_fs_used_wal'
+ */
+ combine?: string
+ id?: string
+ value?: number
+ isReferenceLine?: boolean
+ strokeDasharray?: string
+ className?: string
+ hide?: boolean
+}
+
interface CustomIconProps {
color: string
}
@@ -78,9 +137,7 @@ const CustomTooltip = ({
const isDiskSpaceChart = payload?.some((p: any) =>
p.dataKey.toLowerCase().includes('disk_space_')
)
- const isDBSizeChart = payload?.some((p: any) =>
- p.dataKey.toLowerCase().includes('pg_database_size')
- )
+ const isDBSizeChart = payload?.some((p: any) => p.dataKey.toLowerCase().includes('disk_fs_'))
const isNetworkChart = payload?.some((p: any) => p.dataKey.toLowerCase().includes('network_'))
const shouldFormatBytes = isRamChart || isDiskSpaceChart || isDBSizeChart || isNetworkChart
@@ -120,7 +177,7 @@ const CustomTooltip = ({
{isPercentage ? '%' : ''}
{/* Show percentage if max value is set */}
- {!!maxValueData && !isMax && (
+ {!!maxValueData && !isMax && !isPercentage && (
({percentage}%)
)}
@@ -154,6 +211,7 @@ const CustomTooltip = ({
{isPercentage ? '%' : ''}
{maxValueAttribute &&
+ !isPercentage &&
!isNaN((total as number) / maxValueData?.value) &&
isFinite((total as number) / maxValueData?.value) && (
diff --git a/apps/studio/components/ui/Charts/ComposedChartHandler.tsx b/apps/studio/components/ui/Charts/ComposedChartHandler.tsx
index 25bee033ebf87..1c90a17dd37a4 100644
--- a/apps/studio/components/ui/Charts/ComposedChartHandler.tsx
+++ b/apps/studio/components/ui/Charts/ComposedChartHandler.tsx
@@ -16,31 +16,9 @@ import { useChartHighlight } from './useChartHighlight'
import type { ChartData } from './Charts.types'
import type { UpdateDateRange } from 'pages/project/[ref]/reports/database'
+import { MultiAttribute } from './ComposedChart.utils'
-type Provider = 'infra-monitoring' | 'daily-stats' | 'reference-line'
-
-export type MultiAttribute = {
- attribute: string
- provider: Provider
- label?: string
- color?: string
- stackId?: string
- format?: 'percent' | 'number'
- description?: string
- docsLink?: string
- isMaxValue?: boolean
- type?: 'line' | 'area-bar'
- omitFromTotal?: boolean
- tooltip?: string
- customValue?: number
- id?: string
- value?: number
- isReferenceLine?: boolean
- strokeDasharray?: string
- className?: string
-}
-
-interface ComposedChartHandlerProps {
+export interface ComposedChartHandlerProps {
id?: string
label: string
attributes: MultiAttribute[]
@@ -189,6 +167,7 @@ const ComposedChartHandler = ({
// Add regular attributes
attributes.forEach((attr, index) => {
if (!attr) return
+
// Handle custom value attributes (like disk size)
if (attr.customValue !== undefined) {
point[attr.attribute] = attr.customValue
@@ -200,7 +179,16 @@ const ComposedChartHandler = ({
const queryData = attributeQueries[index]?.data?.data
const matchingPoint = queryData?.find((p: any) => p.period_start === timestamp)
- point[attr.attribute] = matchingPoint?.[attr.attribute] ?? 0
+ let value = matchingPoint?.[attr.attribute] ?? 0
+
+ // Apply value manipulation if provided
+ if (attr.manipulateValue && typeof attr.manipulateValue === 'function') {
+ // Ensure value is a number before manipulation
+ const numericValue = typeof value === 'number' ? value : Number(value) || 0
+ value = attr.manipulateValue(numericValue)
+ }
+
+ point[attr.attribute] = value
})
// Add reference line values for each timestamp
diff --git a/apps/studio/data/fetchers.ts b/apps/studio/data/fetchers.ts
index a4c4ad6f4cd38..d3849c3e83e96 100644
--- a/apps/studio/data/fetchers.ts
+++ b/apps/studio/data/fetchers.ts
@@ -160,3 +160,55 @@ export const handleError = (error: unknown): never => {
// up in the UI.
throw new ResponseError(undefined)
}
+
+// [Joshen] The methods below are brought over from lib/common/fetchers because we still need them
+// primarily for our own endpoints in the dashboard repo. So consolidating all the fetch methods into here.
+
+async function handleFetchResponse(response: Response): Promise {
+ const contentType = response.headers.get('Content-Type')
+ if (contentType === 'application/octet-stream') return response as any
+ try {
+ const resTxt = await response.text()
+ try {
+ // try to parse response text as json
+ return JSON.parse(resTxt)
+ } catch (err) {
+ // return as text plain
+ return resTxt as any
+ }
+ } catch (e) {
+ return handleError(response) as T | ResponseError
+ }
+}
+
+/**
+ * To be used only for dashboard API endpoints. Use `fetch` directly if calling a non dashboard API endpoint
+ *
+ * Exception for `bucket-object-download-mutation` as openapi-fetch doesn't support octet-stream responses
+ */
+export async function fetchPost(
+ url: string,
+ data: { [prop: string]: any },
+ options?: { [prop: string]: any }
+): Promise {
+ try {
+ const { headers: otherHeaders, abortSignal, ...otherOptions } = options ?? {}
+ const headers = await constructHeaders({
+ 'Content-Type': 'application/json',
+ ...DEFAULT_HEADERS,
+ ...otherHeaders,
+ })
+ const response = await fetch(url, {
+ method: 'POST',
+ body: JSON.stringify(data),
+ referrerPolicy: 'no-referrer-when-downgrade',
+ headers,
+ ...otherOptions,
+ signal: abortSignal,
+ })
+ if (!response.ok) return handleError(response)
+ return handleFetchResponse(response)
+ } catch (error) {
+ return handleError(error)
+ }
+}
diff --git a/apps/studio/data/profile/profile-create-mutation.ts b/apps/studio/data/profile/profile-create-mutation.ts
index f4c674300d23f..0b373597a9f9c 100644
--- a/apps/studio/data/profile/profile-create-mutation.ts
+++ b/apps/studio/data/profile/profile-create-mutation.ts
@@ -1,23 +1,20 @@
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
+import { components } from 'api-types'
+import { handleError, post } from 'data/fetchers'
import { organizationKeys } from 'data/organizations/keys'
import { permissionKeys } from 'data/permissions/keys'
-import { post } from 'lib/common/fetch'
-import { API_URL } from 'lib/constants'
import type { ResponseError } from 'types'
import { profileKeys } from './keys'
-import type { Profile } from './types'
-export type ProfileResponse = Profile
+export type ProfileResponse = components['schemas']['ProfileResponse']
export async function createProfile() {
- const response = await post(`${API_URL}/profile`, {})
- if (response.error) {
- throw response.error
- }
+ const { data, error } = await post('/platform/profile')
- return response as ProfileResponse
+ if (error) handleError(error)
+ return data
}
type ProfileCreateData = Awaited>
diff --git a/apps/studio/data/reports/database-charts.ts b/apps/studio/data/reports/database-charts.ts
index 82eb6551eee8f..718534e7ecab6 100644
--- a/apps/studio/data/reports/database-charts.ts
+++ b/apps/studio/data/reports/database-charts.ts
@@ -1,7 +1,8 @@
import { numberFormatter } from 'components/ui/Charts/Charts.utils'
import { formatBytes } from 'lib/helpers'
-import { Organization } from '../../types'
+import { Organization } from 'types'
import { Project } from '../projects/project-detail-query'
+import { ReportAttributes } from 'components/ui/Charts/ComposedChart.utils'
export const getReportAttributes = (isFreePlan: boolean) => [
{ id: 'ram_usage', label: 'Memory usage', hide: false },
@@ -26,7 +27,10 @@ export const getReportAttributes = (isFreePlan: boolean) => [
},
]
-export const getReportAttributesV2 = (org: Organization, project: Project) => {
+export const getReportAttributesV2: (org: Organization, project: Project) => ReportAttributes[] = (
+ org,
+ project
+) => {
const isFreePlan = org?.plan?.id === 'free'
const computeSize = project?.infra_compute_size || 'medium'
const isSpendCapEnabled =
@@ -46,7 +50,7 @@ export const getReportAttributesV2 = (org: Organization, project: Project) => {
syncId: 'database-reports',
valuePrecision: 2,
YAxisProps: {
- width: 60,
+ width: 75,
tickFormatter: (value: any) => formatBytes(value, 2),
},
attributes: [
@@ -226,8 +230,8 @@ export const getReportAttributesV2 = (org: Organization, project: Project) => {
],
},
{
- id: 'db-size',
- label: 'Database Size',
+ id: 'disk-size',
+ label: 'Disk Size',
syncId: 'database-reports',
valuePrecision: 2,
hide: false,
@@ -243,19 +247,36 @@ export const getReportAttributesV2 = (org: Organization, project: Project) => {
defaultChartStyle: 'line',
docsUrl: 'https://supabase.com/docs/guides/platform/database-size',
attributes: [
+ {
+ attribute: 'disk_fs_used_system',
+ provider: 'infra-monitoring',
+ format: 'bytes',
+ label: 'System',
+ tooltip: 'Reserved space for the system to ensure your database runs smoothly.',
+ },
+ {
+ attribute: 'disk_fs_used_wal',
+ provider: 'infra-monitoring',
+ format: 'bytes',
+ label: 'WAL',
+ tooltip:
+ 'Disk usage by the write-ahead log. The usage depends on your WAL settings and the amount of data being written to the database.',
+ },
+
{
attribute: 'pg_database_size',
provider: 'infra-monitoring',
+ format: 'bytes',
label: 'Database',
- tooltip: 'Total space on disk used by your database (tables, indexes, data, ...).',
+ tooltip: 'Disk usage by your database (tables, indexes, data, ...).',
},
{
- attribute: 'max_pg_database_size',
- provider: 'reference-line',
- label: 'Disk size',
- value: (project?.volumeSizeGb || getRecommendedDbSize(computeSize)) * 1024 * 1024 * 1024,
- tooltip: 'Disk Size refers to the total space your project occupies on disk',
+ attribute: 'disk_fs_size',
+ provider: 'infra-monitoring',
isMaxValue: true,
+ format: 'bytes',
+ label: 'Disk Size',
+ tooltip: 'Disk Size refers to the total space your project occupies on disk',
},
!isFreePlan &&
(isSpendCapEnabled
@@ -304,20 +325,21 @@ export const getReportAttributesV2 = (org: Organization, project: Project) => {
showTotal: false,
attributes: [
{
- attribute: 'network_transmit_bytes',
+ attribute: 'network_receive_bytes',
provider: 'infra-monitoring',
- label: 'Transmit',
+ label: 'Ingress',
+ manipulateValue: (value: number) => value * -1,
tooltip:
- 'Data sent from your database to clients. High values may indicate large query results or numerous outgoing connections.',
- stackId: '2',
+ 'Data received by your database from clients. High values may indicate frequent queries, large data inserts, or many incoming connections.',
+ stackId: '1',
},
{
- attribute: 'network_receive_bytes',
+ attribute: 'network_transmit_bytes',
provider: 'infra-monitoring',
- label: 'Receive',
+ label: 'Egress',
tooltip:
- 'Data received by your database from clients. High values may indicate frequent queries, large data inserts, or many incoming connections.',
- stackId: '1',
+ 'Data sent from your database to clients. High values may indicate large query results or numerous outgoing connections.',
+ stackId: '2',
},
],
},
@@ -335,44 +357,49 @@ export const getReportAttributesV2 = (org: Organization, project: Project) => {
{
attribute: 'client_connections_postgres',
provider: 'infra-monitoring',
- label: 'postgres',
- tooltip: 'Active connections',
+ label: 'Postgres',
+ tooltip:
+ 'Direct connections to the Postgres database from your application and external clients.',
},
{
attribute: 'client_connections_authenticator',
provider: 'infra-monitoring',
- label: 'postgrest',
- tooltip: 'Active connections',
+ label: 'PostgREST',
+ tooltip: 'Connections magaged by PostgREST to auto-generate RESTful API.',
},
{
- attribute: 'client_connections_supabase_auth_admin',
+ attribute: 'client_connections_supabase_admin',
provider: 'infra-monitoring',
- label: 'auth',
- tooltip: 'Active connections',
+ label: 'Admin',
+ tooltip:
+ 'Administrative connections used by various Supabase services for internal operations and maintenance tasks.',
},
{
- attribute: 'client_connections_supabase_storage_admin',
+ attribute: 'client_connections_supabase_auth_admin',
provider: 'infra-monitoring',
- label: 'storage',
- tooltip: 'Active connections',
+ label: 'Auth',
+ tooltip:
+ 'Administrative connections used by Supabase Auth service for user management and authentication operations.',
},
{
- attribute: 'client_connections_supabase_admin',
+ attribute: 'client_connections_supabase_storage_admin',
provider: 'infra-monitoring',
- label: 'supabase-admin',
- tooltip: 'Active connections',
+ label: 'Storage',
+ tooltip:
+ 'Administrative connections used by Supabase Storage service for file operations and bucket management.',
},
{
attribute: 'client_connections_other',
provider: 'infra-monitoring',
- label: 'other',
- tooltip: 'Active connections',
+ label: 'Other',
+ tooltip: "Miscellaneous database connections that don't fall into other categories.",
},
{
attribute: 'max_db_connections',
- provider: 'infra-monitoring',
- label: 'Maximum connections allowed',
- tooltip: 'Maximum connections for instance size',
+ provider: 'reference-line',
+ label: 'Max connections',
+ value: getConnectionLimits(computeSize).direct,
+ tooltip: 'Max available connections for your current compute size',
isMaxValue: true,
},
],
diff --git a/apps/studio/data/service-status/edge-functions-status-query.ts b/apps/studio/data/service-status/edge-functions-status-query.ts
index 9010e05806431..ea97a0b41411a 100644
--- a/apps/studio/data/service-status/edge-functions-status-query.ts
+++ b/apps/studio/data/service-status/edge-functions-status-query.ts
@@ -1,6 +1,5 @@
import { useQuery, UseQueryOptions } from '@tanstack/react-query'
-import { get } from 'lib/common/fetch'
import type { ResponseError } from 'types'
import { serviceStatusKeys } from './keys'
@@ -9,10 +8,16 @@ export type EdgeFunctionServiceStatusVariables = {
}
export async function getEdgeFunctionServiceStatus(signal?: AbortSignal) {
- const res = await get(`https://obuldanrptloktxcffvn.supabase.co/functions/v1/health-check`, {
- signal,
- })
- return res as { healthy: boolean }
+ try {
+ const res = await fetch('https://obuldanrptloktxcffvn.supabase.co/functions/v1/health-check', {
+ method: 'GET',
+ signal,
+ })
+ const response = await res.json()
+ return response as { healthy: boolean }
+ } catch (err) {
+ return { healthy: false }
+ }
}
export type EdgeFunctionServiceStatusData = Awaited>
diff --git a/apps/studio/data/storage/bucket-object-download-mutation.ts b/apps/studio/data/storage/bucket-object-download-mutation.ts
index dca56be8d93f2..02073d937ffa3 100644
--- a/apps/studio/data/storage/bucket-object-download-mutation.ts
+++ b/apps/studio/data/storage/bucket-object-download-mutation.ts
@@ -2,7 +2,7 @@ import { UseMutationOptions, useMutation } from '@tanstack/react-query'
import { toast } from 'sonner'
import { components } from 'data/api'
-import { post } from 'lib/common/fetch'
+import { fetchPost } from 'data/fetchers'
import { API_URL, IS_PLATFORM } from 'lib/constants'
import { ResponseError } from 'types'
@@ -18,15 +18,9 @@ export const downloadBucketObject = async (
) => {
if (!bucketId) throw new Error('bucketId is required')
- // [Joshen] JFYI we have to use lib/common/fetch post as post from openapi-fetch doesn't support receiving octet-streams
- // Opting to hard code /platform for non platform just for this particular mutation, so that it's clear what's happening
- const response = await post(
+ const response = await fetchPost(
`${API_URL}${IS_PLATFORM ? '' : '/platform'}/storage/${projectRef}/buckets/${bucketId}/objects/download`,
- {
- path,
- options,
- abortSignal: signal,
- }
+ { path, options, abortSignal: signal }
)
if (response.error) throw response.error
diff --git a/apps/studio/lib/common/fetch/base.ts b/apps/studio/lib/common/fetch/base.ts
index f9bf3c87aa736..3f000da9971fe 100644
--- a/apps/studio/lib/common/fetch/base.ts
+++ b/apps/studio/lib/common/fetch/base.ts
@@ -15,7 +15,6 @@ export async function handleResponse(
): Promise> {
const contentType = response.headers.get('Content-Type')
if (contentType === 'application/octet-stream') return response as any
-
try {
const resTxt = await response.text()
try {
diff --git a/apps/studio/lib/common/fetch/get.ts b/apps/studio/lib/common/fetch/get.ts
index 0d9382c952990..b1f912934c975 100644
--- a/apps/studio/lib/common/fetch/get.ts
+++ b/apps/studio/lib/common/fetch/get.ts
@@ -25,30 +25,3 @@ export async function get(
return handleError(error, requestId)
}
}
-
-export async function getWithTimeout(
- url: string,
- options?: { [prop: string]: any }
-): Promise> {
- const requestId = uuidv4()
- try {
- const timeout = options?.timeout ?? 60000
- const controller = new AbortController()
- const id = setTimeout(() => controller.abort(), timeout)
- const { headers: optionHeaders, ...otherOptions } = options ?? {}
- const headers = await constructHeaders(requestId, optionHeaders)
- const response = await fetch(url, {
- method: 'GET',
- referrerPolicy: 'no-referrer-when-downgrade',
- headers,
- ...otherOptions,
- signal: controller.signal,
- })
- clearTimeout(id)
-
- if (!response.ok) return handleResponseError(response, requestId)
- return handleResponse(response, requestId)
- } catch (error) {
- return handleError(error, requestId)
- }
-}
diff --git a/apps/studio/lib/common/fetch/index.ts b/apps/studio/lib/common/fetch/index.ts
index e374cad9dc178..f476c3c02f49f 100644
--- a/apps/studio/lib/common/fetch/index.ts
+++ b/apps/studio/lib/common/fetch/index.ts
@@ -9,7 +9,7 @@ export {
isResponseOk,
} from './base'
export { delete_ } from './delete'
-export { get, getWithTimeout } from './get'
+export { get } from './get'
export { head, headWithTimeout } from './head'
export { patch } from './patch'
export { post } from './post'
diff --git a/apps/studio/pages/project/[ref]/reports/database.tsx b/apps/studio/pages/project/[ref]/reports/database.tsx
index 1c280a783c214..8ada04517a0ad 100644
--- a/apps/studio/pages/project/[ref]/reports/database.tsx
+++ b/apps/studio/pages/project/[ref]/reports/database.tsx
@@ -21,7 +21,7 @@ import ChartHandler from 'components/ui/Charts/ChartHandler'
import Panel from 'components/ui/Panel'
import ShimmerLine from 'components/ui/ShimmerLine'
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
-import ComposedChartHandler, { MultiAttribute } from 'components/ui/Charts/ComposedChartHandler'
+import ComposedChartHandler from 'components/ui/Charts/ComposedChartHandler'
import { DateRangePicker } from 'components/ui/DateRangePicker'
import GrafanaPromoBanner from 'components/ui/GrafanaPromoBanner'
@@ -33,12 +33,12 @@ import { useProjectDiskResizeMutation } from 'data/config/project-disk-resize-mu
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useCurrentOrgPlan } from 'hooks/misc/useCurrentOrgPlan'
import { useFlag } from 'hooks/ui/useFlag'
+import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { TIME_PERIODS_INFRA } from 'lib/constants/metrics'
import { formatBytes } from 'lib/helpers'
import type { NextPageWithLayout } from 'types'
-import { useOrganizationQuery } from '../../../../data/organizations/organization-query'
-import { useSelectedOrganization } from '../../../../hooks/misc/useSelectedOrganization'
+import type { MultiAttribute } from 'components/ui/Charts/ComposedChart.utils'
const DatabaseReport: NextPageWithLayout = () => {
return (
@@ -60,7 +60,7 @@ export default DatabaseReport
const DatabaseUsage = () => {
const { db, chart, ref } = useParams()
const { project } = useProjectContext()
- const isReportsV2 = useFlag('reportsDatabaseV2')
+ const showChartsV2 = useFlag('reportsDatabaseV2')
const org = useSelectedOrganization()
const { plan: orgPlan, isLoading: isOrgPlanLoading } = useCurrentOrgPlan()
const isFreePlan = !isOrgPlanLoading && orgPlan?.id === 'free'
@@ -126,7 +126,7 @@ const DatabaseUsage = () => {
})
)
})
- if (isReportsV2) {
+ if (showChartsV2) {
REPORT_ATTRIBUTES_V2.forEach((chart: any) => {
chart.attributes.forEach((attr: any) => {
queryClient.invalidateQueries(
@@ -252,7 +252,7 @@ const DatabaseUsage = () => {
- {isReportsV2 ? (
+ {showChartsV2 ? (
{dateRange &&
REPORT_ATTRIBUTES_V2.filter((chart) => !chart.hide).map((chart) => (
diff --git a/apps/www/data/career.json b/apps/www/data/career.json
index fd8e38e80aaaa..2b9d14fb06832 100644
--- a/apps/www/data/career.json
+++ b/apps/www/data/career.json
@@ -2,7 +2,7 @@
"company": [
{
"number": "120+",
- "text": "team members\n\nin 25+ countries"
+ "text": "team members\n\nin 35+ countries"
},
{
"number": "15+",
@@ -17,7 +17,7 @@
"text": "community members"
},
{
- "number": "10,000+",
+ "number": "20,000+",
"text": "memes posted\n\n(and counting)"
}
],
@@ -77,8 +77,8 @@
},
{
"icon": "tech_allowance",
- "title": "Hardware Budget",
- "text": "Use this budget for anything you need to set up your work environment from tech to office setup."
+ "title": "Tech Allowance",
+ "text": "Use this budget for any technology you need for your work setup."
},
{
"icon": "healthcare",
diff --git a/apps/www/pages/careers.tsx b/apps/www/pages/careers.tsx
index a9fa84e33d94a..6feac83d2bfa8 100644
--- a/apps/www/pages/careers.tsx
+++ b/apps/www/pages/careers.tsx
@@ -166,7 +166,7 @@ const CareerPage = ({ jobs, placeholderJob, contributors }: CareersPageProps) =>
We work together,
wherever we are
-
+
Working in a globally distributed team is rewarding but has its challenges. We are
across many different timezones, so we use tools like Notion, Slack, and Discord
to stay connected to our team, and our community.
@@ -187,19 +187,20 @@ const CareerPage = ({ jobs, placeholderJob, contributors }: CareersPageProps) =>
What is Supabase
-
+
Supabase is the Postgres development platform, built by developers for
developers. Supabase adds auth, realtime, storage, restful APIs, and edge
- functions to Postgres without a single line of code. Supabase was born-remote.
- Having a globally distributed, open source company is our secret weapon to
- hiring top-tier talent.
+
+
+ Supabase was born-remote. Having a globally distributed, open source company
+ is our secret weapon to hiring top-tier talent.