diff --git a/apps/studio/components/grid/components/header/Header.tsx b/apps/studio/components/grid/components/header/Header.tsx index 2b2429cd33332..fde164a247cc5 100644 --- a/apps/studio/components/grid/components/header/Header.tsx +++ b/apps/studio/components/grid/components/header/Header.tsx @@ -2,7 +2,6 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import saveAs from 'file-saver' import { ArrowUp, ChevronDown, FileText, Trash } from 'lucide-react' import Link from 'next/link' -import Papa from 'papaparse' import { ReactNode, useState } from 'react' import { toast } from 'sonner' @@ -28,6 +27,7 @@ import { useTableEditorTableStateSnapshot } from 'state/table-editor-table' import { Button, cn, + copyToClipboard, DropdownMenu, DropdownMenuContent, DropdownMenuItem, @@ -37,6 +37,7 @@ import { } from 'ui' import { ExportDialog } from './ExportDialog' import { FilterPopover } from './filter/FilterPopover' +import { formatRowsForCSV } from './Header.utils' import { SortPopover } from './sort/SortPopover' // [Joshen] CSV exports require this guard as a fail-safe if the table is // just too large for a browser to keep all the rows in memory before @@ -281,6 +282,25 @@ const RowHeader = () => { }) } + const onCopyRows = (type: 'csv' | 'json' | 'sql') => { + const rows = allRows.filter((x) => snap.selectedRows.has(x.idx)) + + if (type === 'csv') { + const csv = formatRowsForCSV({ + rows, + columns: snap.table!.columns.map((column) => column.name), + }) + copyToClipboard(csv) + } else if (type === 'sql') { + const sqlStatements = formatTableRowsToSQL(snap.table, rows) + copyToClipboard(sqlStatements) + } else if (type === 'json') { + copyToClipboard(JSON.stringify(rows)) + } + + toast.success('Copied rows to clipboard') + } + const onRowsExportCSV = async () => { setIsExporting(true) @@ -340,16 +360,8 @@ const RowHeader = () => { return } - const formattedRows = rows.map((row) => { - const formattedRow = row - Object.keys(row).map((column) => { - if (typeof row[column] === 'object' && row[column] !== null) - formattedRow[column] = JSON.stringify(formattedRow[column]) - }) - return formattedRow - }) - - const csv = Papa.unparse(formattedRows, { + const csv = formatRowsForCSV({ + rows, columns: snap.table!.columns.map((column) => column.name), }) const csvData = new Blob([csv], { type: 'text/csv;charset=utf-8;' }) @@ -494,6 +506,42 @@ const RowHeader = () => { : `Delete ${snap.selectedRows.size} row`} )} + + {!snap.allRowsSelected ? ( + + + + + + onCopyRows('csv')}>Copy as CSV + onCopyRows('sql')}>Copy as SQL + onCopyRows('json')}>Copy as JSON + + + ) : ( + + Copy + + )} + - -
+ <> + + + + + Add new secrets + + + {fields.map((fieldItem, index) => ( +
+ ( + + Key + + handlePaste(e.nativeEvent)} + /> + + + + )} + /> + ( + + Value + + +
+ } + /> + + + + )} + /> + +
+ ))} + + + + - - - - - + + + + { isCreating={isCreating} secretName={duplicateSecretName} /> - + ) } diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecret.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecret.tsx index 4821b1a3093d7..7bdc4c9ef7ead 100644 --- a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecret.tsx +++ b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecret.tsx @@ -6,6 +6,7 @@ import { ButtonTooltip } from 'components/ui/ButtonTooltip' import type { ProjectSecret } from 'data/secrets/secrets-query' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' import { TimestampInfo } from 'ui-patterns' +import { TableCell, TableRow } from 'ui' interface EdgeFunctionSecretProps { secret: ProjectSecret @@ -19,28 +20,31 @@ const EdgeFunctionSecret = ({ secret, onSelectDelete }: EdgeFunctionSecretProps) const isReservedSecret = !!secret.name.match(/^(SUPABASE_).*/) return ( - - + +

{secret.name}

-
- -

+ + +

{secret.value}

-
- + + {!!secret.updated_at ? ( ) : ( '-' )} - - + +
-
-
+ + ) } diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx index 4aba64bac4e89..5312e2611d62f 100644 --- a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx +++ b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx @@ -4,14 +4,23 @@ import { useState } from 'react' import { toast } from 'sonner' import { useParams } from 'common' -import Table from 'components/to-be-cleaned/Table' import AlertError from 'components/ui/AlertError' import NoPermission from 'components/ui/NoPermission' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useSecretsDeleteMutation } from 'data/secrets/secrets-delete-mutation' import { ProjectSecret, useSecretsQuery } from 'data/secrets/secrets-query' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' -import { Badge, Separator } from 'ui' +import { + Badge, + Separator, + Table, + TableHead, + TableHeader, + TableRow, + TableCell, + TableBody, + Card, +} from 'ui' import { Input } from 'ui-patterns/DataInputs/Input' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import AddNewSecretForm from './AddNewSecretForm' @@ -43,15 +52,15 @@ const EdgeFunctionSecrets = () => { : data ?? [] const headers = [ - Name, - + Name, + Digest{' '} SHA256 - , - Updated at, - , + , + Updated at, + , ] return ( @@ -60,14 +69,13 @@ const EdgeFunctionSecrets = () => { {isError && } {isSuccess && ( <> - {!canUpdateSecrets ? ( - - ) : ( -
+
+ {!canUpdateSecrets ? ( + + ) : ( - -
- )} + )} +
{canUpdateSecrets && !canReadSecrets ? ( ) : canReadSecrets ? ( @@ -83,11 +91,13 @@ const EdgeFunctionSecrets = () => { /> -
- 0 ? ( + +
+ + {headers} + + + {secrets.length > 0 ? ( secrets.map((secret) => ( { /> )) ) : secrets.length === 0 && searchString.length > 0 ? ( - - + +

No results found

Your search for "{searchString}" did not return any results

-
-
+ + ) : ( - - + +

No secrets created

There are no secrets associated with your project yet

-
-
- ) - } - /> - + + + )} +
+
+
) : null} diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionsListItem.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionsListItem.tsx index 55fae1e47a542..186616f953ee6 100644 --- a/apps/studio/components/interfaces/Functions/EdgeFunctionsListItem.tsx +++ b/apps/studio/components/interfaces/Functions/EdgeFunctionsListItem.tsx @@ -8,7 +8,7 @@ import Table from 'components/to-be-cleaned/Table' import { useCustomDomainsQuery } from 'data/custom-domains/custom-domains-query' import type { EdgeFunctionsResponse } from 'data/edge-functions/edge-functions-query' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' -import { copyToClipboard, Tooltip, TooltipContent, TooltipTrigger } from 'ui' +import { copyToClipboard, TableCell, TableRow, Tooltip, TooltipContent, TooltipTrigger } from 'ui' interface EdgeFunctionsListItemProps { function: EdgeFunctionsResponse @@ -33,18 +33,19 @@ export const EdgeFunctionsListItem = ({ function: item }: EdgeFunctionsListItemP : functionUrl return ( - { router.push(`/project/${ref}/functions/${item.slug}`) }} + className="cursor-pointer" > - +

{item.name}

-
- + +

{endpoint} @@ -75,13 +76,13 @@ export const EdgeFunctionsListItem = ({ function: item }: EdgeFunctionsListItemP )}

-
- + +

{dayjs(item.created_at).format('DD MMM, YYYY HH:mm')}

-
- + +
@@ -92,10 +93,10 @@ export const EdgeFunctionsListItem = ({ function: item }: EdgeFunctionsListItemP Last updated on {dayjs(item.updated_at).format('DD MMM, YYYY HH:mm')} - - + +

{item.version}

-
- + + ) } diff --git a/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePolicies.tsx b/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePolicies.tsx index 0294019aa77c5..6f234884903ba 100644 --- a/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePolicies.tsx +++ b/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePolicies.tsx @@ -4,18 +4,23 @@ import { useState } from 'react' import { toast } from 'sonner' import PolicyEditorModal from 'components/interfaces/Auth/Policies/PolicyEditorModal' +import { + ScaffoldSection, + ScaffoldSectionDescription, + ScaffoldSectionTitle, +} from 'components/layouts/Scaffold' import { useDatabasePoliciesQuery } from 'data/database-policies/database-policies-query' import { useDatabasePolicyCreateMutation } from 'data/database-policies/database-policy-create-mutation' import { useDatabasePolicyDeleteMutation } from 'data/database-policies/database-policy-delete-mutation' import { useDatabasePolicyUpdateMutation } from 'data/database-policies/database-policy-update-mutation' import { useBucketsQuery } from 'data/storage/buckets-query' +import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { Loader } from 'lucide-react' import ConfirmModal from 'ui-patterns/Dialogs/ConfirmDialog' import { formatPoliciesForStorage } from '../Storage.utils' import StoragePoliciesBucketRow from './StoragePoliciesBucketRow' import StoragePoliciesEditPolicyModal from './StoragePoliciesEditPolicyModal' import StoragePoliciesPlaceholder from './StoragePoliciesPlaceholder' -import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' const StoragePolicies = () => { const { data: project } = useSelectedProjectQuery() @@ -176,67 +181,72 @@ const StoragePolicies = () => { return (
-

Storage policies

-

- Safeguard your files with policies that define the operations allowed for your users at the - bucket level. -

- {isLoading ? (
) : ( -
- {buckets.length === 0 && } - - {/* Sections for policies grouped by buckets */} - {buckets.map((bucket) => { - const bucketPolicies = get( - find(formattedStorageObjectPolicies, { name: bucket.name }), - ['policies'], - [] - ).sort((a: any, b: any) => a.name.localeCompare(b.name)) - - return ( +
+ + Buckets + + Write policies for each bucket to control access to the bucket and its contents + + {buckets.length === 0 && } + + {/* Sections for policies grouped by buckets */} +
+ {buckets.map((bucket) => { + const bucketPolicies = get( + find(formattedStorageObjectPolicies, { name: bucket.name }), + ['policies'], + [] + ).sort((a: any, b: any) => a.name.localeCompare(b.name)) + + return ( + + ) + })} +
+
+ + + Schema + + Write policies for the tables under the storage schema directly for greater control + + +
+ {/* Section for policies under storage.objects that are not tied to any buckets */} + + {/* Section for policies under storage.buckets */} + - ) - })} - -
-

- You may also write policies for the tables under the storage schema directly for greater - control -

- - {/* Section for policies under storage.objects that are not tied to any buckets */} - - - {/* Section for policies under storage.buckets */} - +
+
)} diff --git a/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePoliciesBucketRow.tsx b/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePoliciesBucketRow.tsx index 178141b7c3485..26eb07822ced7 100644 --- a/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePoliciesBucketRow.tsx +++ b/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePoliciesBucketRow.tsx @@ -4,6 +4,10 @@ import { Archive, Edit, MoreVertical, Trash } from 'lucide-react' import { Badge, Button, + Card, + CardContent, + CardHeader, + CardTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, @@ -28,35 +32,33 @@ const PolicyRow = ({ }: PolicyRowProps) => { const { name, command } = policy return ( -
- -
-
{command}
-
- {name} -
+ +
+
{command}
+
+ {name}
- - -
+
+ + + -
, - ]} - > + + +
+ + {label} + {bucket.public && Public} +
+ +
{policies.length === 0 ? ( -
+

No policies created yet

-
+ ) : ( -
+
{policies.map((policy: any) => ( ))} - {policies.length !== 0 ? ( -
-

{getFooterLabel()}

-
- ) : null}
)} - + ) } diff --git a/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePoliciesPlaceholder.tsx b/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePoliciesPlaceholder.tsx index 4dd36cabfa931..50bee986b545d 100644 --- a/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePoliciesPlaceholder.tsx +++ b/apps/studio/components/interfaces/Storage/StoragePolicies/StoragePoliciesPlaceholder.tsx @@ -1,23 +1,13 @@ -import Panel from 'components/ui/Panel' -import { Archive } from 'lucide-react' +import { CardContent, Card } from 'ui' const StoragePoliciesPlaceholder = () => ( - -
- -

Bucket policies

-
-
, - ]} - > -
+ +

Create a bucket first to start writing policies!

-
- + +
) export default StoragePoliciesPlaceholder diff --git a/apps/studio/components/interfaces/Storage/StorageSettings/S3Connection.tsx b/apps/studio/components/interfaces/Storage/StorageSettings/S3Connection.tsx index e8fbe4a986a93..eb16fee9daa49 100644 --- a/apps/studio/components/interfaces/Storage/StorageSettings/S3Connection.tsx +++ b/apps/studio/components/interfaces/Storage/StorageSettings/S3Connection.tsx @@ -9,11 +9,15 @@ import * as z from 'zod' import { useParams } from 'common' import { useIsProjectActive } from 'components/layouts/ProjectLayout/ProjectContext' +import { + ScaffoldSection, + ScaffoldSectionDescription, + ScaffoldSectionTitle, +} from 'components/layouts/Scaffold' import Table from 'components/to-be-cleaned/Table' import AlertError from 'components/ui/AlertError' -import { FormHeader } from 'components/ui/Forms/FormHeader' +import { DocsButton } from 'components/ui/DocsButton' import NoPermission from 'components/ui/NoPermission' -import Panel from 'components/ui/Panel' import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query' import { useProjectStorageConfigQuery } from 'data/config/project-storage-config-query' import { useProjectStorageConfigUpdateUpdateMutation } from 'data/config/project-storage-config-update-mutation' @@ -24,10 +28,12 @@ import { AlertDescription_Shadcn_, Alert_Shadcn_, Button, + Card, + CardContent, + CardFooter, FormControl_Shadcn_, FormField_Shadcn_, Form_Shadcn_, - Separator, Switch, WarningIcon, } from 'ui' @@ -102,90 +108,87 @@ export const S3Connection = () => { return ( <> - -
- - {projectIsLoading ? ( - - ) : isProjectActive ? ( - - ( - - - - - - )} - /> - - {isErrorStorageConfig && ( -
- +
+
+ S3 Connection + + Connect to your bucket using any S3-compatible service via the S3 protocol + +
+ +
+ + + {projectIsLoading ? ( + + ) : isProjectActive ? ( + + + ( + + + + + + )} /> -
- )} - - -
- - - - {!projectIsLoading && ( - - - - )} -
+ {isErrorStorageConfig && ( +
+ +
+ )} + - + +
+ + + + {!projectIsLoading && ( + + + + )} +
+
-
- {!canUpdateStorageSettings ? ( -

- You need additional permissions to update storage settings -

- ) : ( -
+ {!canUpdateStorageSettings && ( + +

+ You need additional permissions to update storage settings +

+
)} -
- + + + {form.formState.isDirty && ( + + )} + + + ) : ( + + + Project is paused + + To connect to your S3 bucket, you need to restore your project. + +
+
-
- - ) : ( - - - Project is paused - - To connect to your S3 bucket, you need to restore your project. - -
- -
-
- )} - - - -
- - } - /> + + )} + + + + +
+
+ S3 Access Keys + + Manage your access keys for this project. + +
+ +
{!canReadS3Credentials ? ( @@ -286,7 +290,7 @@ export const S3Connection = () => { )} )} -
+ { } }, [organization]) - const formattedMaxSizeBytes = `${new Intl.NumberFormat('en-US').format(maxBytes)} bytes` - const FormSchema = z .object({ fileSizeLimit: z.coerce.number(), @@ -156,55 +156,50 @@ const StorageSettings = () => { } return ( - - {isLoading && } - {isError && ( - - )} - {isSuccess && ( -
-
-
-
-
-

Upload file size limit

-
- -
-
-
- ( - - - size - - - - - - - )} - /> -
-
- ( - - Unit - + + + {isLoading && } + {isError && ( + + )} + {isSuccess && ( + + + + ( + + {storageUnit !== StorageSizeUnits.BYTES && ( + <> + Equivalent to {convertToBytes(limit, storageUnit).toLocaleString()}{' '} + bytes.{' '} + + )} + Maximum upload file size is {formatBytes(maxBytes)}. + + } + > + +
+ + ( @@ -224,84 +219,80 @@ const StorageSettings = () => { ))} - - - - )} - /> -
-
-

- {storageUnit !== StorageSizeUnits.BYTES && - `Equivalent to ${convertToBytes( - limit, - storageUnit - ).toLocaleString()} bytes. `} - Maximum upload file size is {formatBytes(maxBytes)}. -

-
-
+ )} + /> +
+ + + )} + /> + -
-
-

Enable Image Transformation

-
-
-
- ( + + ( + + Optimize and resize images on the fly.{' '} + + Learn more + + . + + } + > + - )} - /> -
-

- Optimize and resize images on the fly.{' '} - - Learn more - - . -

-
-
-
- - {isFreeTier && ( -
- -
- )} - {isSpendCapOn && ( -
- + + )} /> -
- )} -
-
-
- {!canUpdateStorageSettings ? ( + + + {isFreeTier && ( + + + + )} + {isSpendCapOn && ( + + + + )} + + {!canUpdateStorageSettings && ( +

You need additional permissions to update storage settings

- ) : ( -
- )} -
+ + )} + + + {form.formState.isDirty && ( - -
-
-
-
- - )} - + )} + + + + + )} + + ) } diff --git a/apps/studio/components/layouts/ProjectLayout/LoadingState.tsx b/apps/studio/components/layouts/ProjectLayout/LoadingState.tsx index 122ff258752b6..25f46fb6bdb37 100644 --- a/apps/studio/components/layouts/ProjectLayout/LoadingState.tsx +++ b/apps/studio/components/layouts/ProjectLayout/LoadingState.tsx @@ -13,23 +13,25 @@ const LoadingState = () => { return (
-
- {isLoading ? ( - - ) : ( -

{projectName}

- )} +
+
+ {isLoading ? ( + + ) : ( +

{projectName}

+ )} +
- -
- -
- +
+
+ +
- -
- - +
+
+ + +
) diff --git a/apps/studio/components/to-be-cleaned/Table.tsx b/apps/studio/components/to-be-cleaned/Table.tsx index c8d9077505aad..17c0aa1db6f04 100644 --- a/apps/studio/components/to-be-cleaned/Table.tsx +++ b/apps/studio/components/to-be-cleaned/Table.tsx @@ -11,6 +11,9 @@ interface TableProps { style?: React.StyleHTMLAttributes } +/** + * @deprecated Use `Table` from `ui` instead + */ function Table({ body, head, @@ -45,6 +48,9 @@ interface ThProps { style?: React.CSSProperties } +/** + * @deprecated Use `TableHeader` from `ui` instead + */ const Th = ({ children, className, style }: PropsWithChildren) => { const classes = ['p-3 px-4 text-left'] if (className) classes.push(className) @@ -62,6 +68,9 @@ interface TrProps { onClick?: () => void } +/** + * @deprecated Use `TableRow` from `ui` instead + */ const Tr = ({ children, className, onClick, style, hoverable }: PropsWithChildren) => { let classes = [className] if (onClick || hoverable) classes.push('tr--link') @@ -79,6 +88,9 @@ interface TdProps extends React.HTMLProps { align?: 'left' | 'center' | 'right' | 'justify' | 'char' | undefined } +/** + * @deprecated Use `TableCell` from `ui` instead + */ const Td = ({ children, colSpan, className, style, ...rest }: PropsWithChildren) => { return ( diff --git a/apps/studio/pages/project/[ref]/functions/index.tsx b/apps/studio/pages/project/[ref]/functions/index.tsx index c7e4b532550ff..7a76544467c92 100644 --- a/apps/studio/pages/project/[ref]/functions/index.tsx +++ b/apps/studio/pages/project/[ref]/functions/index.tsx @@ -11,14 +11,13 @@ import DefaultLayout from 'components/layouts/DefaultLayout' import EdgeFunctionsLayout from 'components/layouts/EdgeFunctionsLayout/EdgeFunctionsLayout' import { PageLayout } from 'components/layouts/PageLayout/PageLayout' import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' -import Table from 'components/to-be-cleaned/Table' import AlertError from 'components/ui/AlertError' import { DocsButton } from 'components/ui/DocsButton' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useEdgeFunctionsQuery } from 'data/edge-functions/edge-functions-query' import { IS_PLATFORM } from 'lib/constants' import type { NextPageWithLayout } from 'types' -import { Button } from 'ui' +import { Button, Table, TableHead, TableRow, TableHeader, TableBody, Card } from 'ui' const EdgeFunctionsPage: NextPageWithLayout = () => { const { ref } = useParams() @@ -62,25 +61,28 @@ const EdgeFunctionsPage: NextPageWithLayout = () => { {isSuccess && ( <> {hasFunctions ? ( - - Name - URL - Created - Last updated - Deployments - - } - body={ - <> - {functions.length > 0 && - functions.map((item) => ( - - ))} - - } - /> + +
+ + + Name + URL + Created + Last updated + Deployments + + + + + <> + {functions.length > 0 && + functions.map((item) => ( + + ))} + + +
+ ) : ( )} diff --git a/apps/studio/pages/project/[ref]/functions/secrets.tsx b/apps/studio/pages/project/[ref]/functions/secrets.tsx index ebc487a755174..d9df3ec1e5202 100644 --- a/apps/studio/pages/project/[ref]/functions/secrets.tsx +++ b/apps/studio/pages/project/[ref]/functions/secrets.tsx @@ -3,14 +3,16 @@ import { FunctionsSecretsEmptyStateLocal } from 'components/interfaces/Functions import DefaultLayout from 'components/layouts/DefaultLayout' import EdgeFunctionsLayout from 'components/layouts/EdgeFunctionsLayout/EdgeFunctionsLayout' import { PageLayout } from 'components/layouts/PageLayout/PageLayout' -import { ScaffoldContainer } from 'components/layouts/Scaffold' +import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' import { IS_PLATFORM } from 'lib/constants' import type { NextPageWithLayout } from 'types' const SecretsPage: NextPageWithLayout = () => { return ( - - {IS_PLATFORM ? : } + + + {IS_PLATFORM ? : } + ) } diff --git a/apps/studio/pages/project/[ref]/index.tsx b/apps/studio/pages/project/[ref]/index.tsx index 5c0b6881ba1a5..1ca640ba44b64 100644 --- a/apps/studio/pages/project/[ref]/index.tsx +++ b/apps/studio/pages/project/[ref]/index.tsx @@ -94,7 +94,7 @@ const Home: NextPageWithLayout = () => { return (
-
+
@@ -205,7 +205,7 @@ const Home: NextPageWithLayout = () => { {!isPaused && ( <> -
+
{IS_PLATFORM && project?.status !== PROJECT_STATUS.INACTIVE && ( <>{isNewProject ? : } diff --git a/apps/studio/pages/project/[ref]/storage/policies.tsx b/apps/studio/pages/project/[ref]/storage/policies.tsx index fe93cf7bc3547..5c96607f23cb6 100644 --- a/apps/studio/pages/project/[ref]/storage/policies.tsx +++ b/apps/studio/pages/project/[ref]/storage/policies.tsx @@ -2,18 +2,24 @@ import StorageLayout from 'components/layouts/StorageLayout/StorageLayout' import DefaultLayout from 'components/layouts/DefaultLayout' import { StoragePolicies } from 'components/interfaces/Storage' import type { NextPageWithLayout } from 'types' +import { PageLayout } from 'components/layouts/PageLayout/PageLayout' +import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' const StoragePoliciesPage: NextPageWithLayout = () => { - return ( -
- -
- ) + return } StoragePoliciesPage.getLayout = (page) => ( - {page} + + + {page} + + ) diff --git a/apps/studio/pages/project/[ref]/storage/settings.tsx b/apps/studio/pages/project/[ref]/storage/settings.tsx index c8a6d2ea3e1db..b204a9239c5bb 100644 --- a/apps/studio/pages/project/[ref]/storage/settings.tsx +++ b/apps/studio/pages/project/[ref]/storage/settings.tsx @@ -1,35 +1,27 @@ import DefaultLayout from 'components/layouts/DefaultLayout' import StorageLayout from 'components/layouts/StorageLayout/StorageLayout' -import { - ScaffoldContainer, - ScaffoldDescription, - ScaffoldHeader, - ScaffoldTitle, -} from 'components/layouts/Scaffold' +import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' import { StorageSettings } from 'components/interfaces/Storage' import { S3Connection } from 'components/interfaces/Storage/StorageSettings/S3Connection' import type { NextPageWithLayout } from 'types' +import { PageLayout } from 'components/layouts/PageLayout/PageLayout' -const PageLayout: NextPageWithLayout = () => { +const StorageSettingsPage: NextPageWithLayout = () => { return ( <> - - - Storage Settings - Configure your project's storage settings - - - - - - + + ) } -PageLayout.getLayout = (page) => ( +StorageSettingsPage.getLayout = (page) => ( - {page} + + + {page} + + ) -export default PageLayout +export default StorageSettingsPage diff --git a/apps/studio/styles/typography.scss b/apps/studio/styles/typography.scss index 8a050348bec5b..453f3df940405 100644 --- a/apps/studio/styles/typography.scss +++ b/apps/studio/styles/typography.scss @@ -55,7 +55,7 @@ } .heading-meta { - @apply text-xs font-mono uppercase tracking-wider font-medium text-foreground; + @apply text-xs font-mono uppercase tracking-wider font-medium text-foreground-light; } /* Text */ diff --git a/packages/ui/src/components/shadcn/ui/table.tsx b/packages/ui/src/components/shadcn/ui/table.tsx index a812d5fbfd6d6..186fadfe9e6ff 100644 --- a/packages/ui/src/components/shadcn/ui/table.tsx +++ b/packages/ui/src/components/shadcn/ui/table.tsx @@ -64,7 +64,7 @@ const TableHead = React.forwardRef<