diff --git a/apps/studio/.env b/apps/studio/.env index addb3f02120a2..aa475c4b29833 100644 --- a/apps/studio/.env +++ b/apps/studio/.env @@ -21,7 +21,7 @@ NEXT_PUBLIC_GOTRUE_URL=$SUPABASE_PUBLIC_URL/auth/v1 NEXT_PUBLIC_HCAPTCHA_SITE_KEY=10000000-ffff-ffff-ffff-000000000001 # CmdK / AI -NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InhndWloeHV6cWlid3hqbmlteGV2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NzUwOTQ4MzUsImV4cCI6MTk5MDY3MDgzNX0.0PMlOxtKL4O9GGZuAP_Xl4f-Tut1qOnW4bNEmAtoB8w +NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InhndWloeHV6cWlid3hqbmlteGV2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTgzNzc1MTgsImV4cCI6MjAzMzk1MzUxOH0.aIqjQ9V7djMxYit-DT1fYNV_VWMHSqldh_18XfX2_BE NEXT_PUBLIC_SUPABASE_URL=https://xguihxuzqibwxjnimxev.supabase.co DOCKER_SOCKET_LOCATION=/var/run/docker.sock diff --git a/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx b/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx index b69109218a9d1..9ffa0387be786 100644 --- a/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx +++ b/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx @@ -63,6 +63,9 @@ export const CreateBranchModal = () => { const gitlessBranching = useIsBranching2Enabled() const allowDataBranching = useFlag('allowDataBranching') + // [Joshen] This is meant to be short lived while we're figuring out how to control + // requests to this endpoint. Kill switch in case we need to stop the requests + const disableBackupsCheck = useFlag('disableBackupsCheckInCreatebranchmodal') const isProPlanAndUp = selectedOrg?.plan?.id !== 'free' const promptProPlanUpgrade = IS_PLATFORM && !isProPlanAndUp @@ -89,7 +92,13 @@ export const CreateBranchModal = () => { useCheckGithubBranchValidity({ onError: () => {}, }) - const { data: cloneBackups, error: cloneBackupsError } = useCloneBackupsQuery({ projectRef }) + const { data: cloneBackups, error: cloneBackupsError } = useCloneBackupsQuery( + { projectRef }, + { + // [Joshen] Only trigger this request when the modal is opened + enabled: showCreateBranchModal && !disableBackupsCheck, + } + ) const targetVolumeSizeGb = cloneBackups?.target_volume_size_gb ?? 0 const noPhysicalBackups = cloneBackupsError?.message.startsWith( 'Physical backups need to be enabled' @@ -358,13 +367,13 @@ export const CreateBranchModal = () => { - {noPhysicalBackups && ( + {!disableBackupsCheck && noPhysicalBackups && ( PITR is required for the project to clone data into the branch diff --git a/apps/studio/components/interfaces/Reports/Reports.constants.ts b/apps/studio/components/interfaces/Reports/Reports.constants.ts index b6cf92f089428..96b3b326d3b2d 100644 --- a/apps/studio/components/interfaces/Reports/Reports.constants.ts +++ b/apps/studio/components/interfaces/Reports/Reports.constants.ts @@ -566,10 +566,6 @@ export const EDGE_FUNCTION_REGIONS = [ key: 'us-west-1', label: 'N. California', }, - { - key: 'ap-northeast-2', - label: 'Seoul', - }, { key: 'us-west-2', label: 'Oregon', @@ -594,4 +590,4 @@ export const EDGE_FUNCTION_REGIONS = [ key: 'sa-east-1', label: 'São Paulo', }, -] +] as const diff --git a/apps/studio/components/interfaces/Reports/v2/ReportChartV2.tsx b/apps/studio/components/interfaces/Reports/v2/ReportChartV2.tsx index 52c2033dcbaf5..c021a855ac6a3 100644 --- a/apps/studio/components/interfaces/Reports/v2/ReportChartV2.tsx +++ b/apps/studio/components/interfaces/Reports/v2/ReportChartV2.tsx @@ -40,7 +40,7 @@ export const ReportChartV2 = ({ const isAvailable = report.availableIn === undefined || (orgPlanId && report.availableIn.includes(orgPlanId)) - const canFetch = orgPlanId !== undefined + const canFetch = orgPlanId !== undefined && isAvailable const { data: queryResult, @@ -83,7 +83,7 @@ export const ReportChartV2 = ({ const [chartStyle, setChartStyle] = useState(report.defaultChartStyle) - if (!isAvailable && !isLoadingChart) { + if (!isAvailable) { return } diff --git a/apps/studio/components/interfaces/Reports/v2/ReportsNumericFilter.tsx b/apps/studio/components/interfaces/Reports/v2/ReportsNumericFilter.tsx index 55173bfe52115..cb3765e1c94fc 100644 --- a/apps/studio/components/interfaces/Reports/v2/ReportsNumericFilter.tsx +++ b/apps/studio/components/interfaces/Reports/v2/ReportsNumericFilter.tsx @@ -12,8 +12,7 @@ import { } from '@ui/components/shadcn/ui/select' import { Button, cn } from 'ui' import { Input } from 'ui-patterns/DataInputs/Input' - -export type ComparisonOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' +import { z } from 'zod' const OPERATOR_LABELS = { '=': 'Equals', @@ -24,15 +23,19 @@ const OPERATOR_LABELS = { '!=': 'Not equal to', } satisfies Record -export interface NumericFilter { - operator: ComparisonOperator - value: number -} +const comparisonOperatorSchema = z.enum(['=', '>=', '<=', '>', '<', '!=']) +export type ComparisonOperator = z.infer + +export const numericFilterSchema = z.object({ + operator: comparisonOperatorSchema, + value: z.number(), +}) +export type NumericFilter = z.infer interface ReportsNumericFilterProps { label: string - value?: NumericFilter - onChange: (value: NumericFilter | undefined) => void + value: NumericFilter | null + onChange: (value: NumericFilter | null) => void operators?: ComparisonOperator[] defaultOperator?: ComparisonOperator placeholder?: string @@ -57,9 +60,9 @@ export const ReportsNumericFilter = ({ className, }: ReportsNumericFilterProps) => { const [open, setOpen] = useState(false) - const [tempValue, setTempValue] = useState(value) + const [tempValue, setTempValue] = useState(value) - const isActive = value !== undefined + const isActive = value !== null useEffect(() => { if (!open) { @@ -67,11 +70,6 @@ export const ReportsNumericFilter = ({ } }, [open, value]) - const handleClear = (e: React.MouseEvent) => { - e.stopPropagation() - onChange(undefined) - } - const handleApply = () => { onChange(tempValue) setOpen(false) @@ -87,27 +85,26 @@ export const ReportsNumericFilter = ({ const handleOperatorChange = (operator: ComparisonOperator) => { setTempValue({ operator, - value: tempValue?.value || 0, + value: tempValue?.value ?? 0, }) } const handleValueChange = (inputValue: string) => { - const numericValue = parseFloat(inputValue) || 0 - setTempValue({ - operator: tempValue?.operator || defaultOperator, - value: numericValue, - }) - } - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter') { - e.preventDefault() - handleApply() + if (inputValue === '') { + setTempValue(null) + } else { + const numericValue = parseFloat(inputValue) + if (!isNaN(numericValue)) { + setTempValue({ + operator: tempValue?.operator ?? defaultOperator, + value: numericValue, + }) + } } } const handleClearAll = () => { - setTempValue(undefined) + setTempValue(null) } return ( @@ -133,13 +130,6 @@ export const ReportsNumericFilter = ({ -
- {label} - -
-
{ e.preventDefault() @@ -175,7 +165,6 @@ export const ReportsNumericFilter = ({ placeholder={placeholder} value={tempValue?.value || ''} onChange={(e) => handleValueChange(e.target.value)} - onKeyDown={handleKeyDown} min={min} max={max} step={step} @@ -193,8 +182,8 @@ export const ReportsNumericFilter = ({
- -
-
- {label} - -
-
- -
- {options.length === 0 ? ( -
- {isLoading ? 'Loading options...' : 'No options available'} -
- ) : ( - options.map((option) => ( - - )) - )} -
+ + {showSearch && } + + No options found. + + {options.map((option) => ( + + + + ))} + + +
-
} > -
+
{selectedDateRange && reportConfig .filter((report) => !report.hide)