diff --git a/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx b/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx index bcb8b8b85f1..a3cec39614e 100644 --- a/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx +++ b/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx @@ -1,6 +1,5 @@ import { FC, useState } from 'react' import { observer } from 'mobx-react-lite' -import * as Tooltip from '@radix-ui/react-tooltip' import { Badge, IconLoader, Toggle } from '@supabase/ui' import { PermissionAction } from '@supabase/shared-types/out/constants' @@ -82,31 +81,12 @@ const ExtensionCard: FC = ({ extension }) => { {loading ? ( ) : ( - - - (isOn ? disableExtension() : enableExtension())} - /> - - {!canUpdateExtentions && ( - - -
- - You need additional permissions to update database extensions - -
-
- )} -
+ (isOn ? disableExtension() : enableExtension())} + /> )}
= ({}) => { (ext: any) => !isNull(ext.installed_version) ) + const canUpdateExtentions = checkPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'extensions' + ) + return (
-
+
= ({}) => { onChange={(e) => setFilterString(e.target.value)} icon={} /> + {!canUpdateExtentions && ( +
+ } + title="You need additional permissions to update database extensions" + /> +
+ )}
diff --git a/studio/components/interfaces/Database/Publications/PublicationsList.tsx b/studio/components/interfaces/Database/Publications/PublicationsList.tsx index e911d25ea05..39fc79645e7 100644 --- a/studio/components/interfaces/Database/Publications/PublicationsList.tsx +++ b/studio/components/interfaces/Database/Publications/PublicationsList.tsx @@ -1,11 +1,13 @@ import { FC, useState } from 'react' import { observer } from 'mobx-react-lite' -import { Button, Input, Toggle, IconSearch } from '@supabase/ui' +import { PermissionAction } from '@supabase/shared-types/out/constants' +import { Button, Input, Toggle, IconSearch, IconAlertCircle } from '@supabase/ui' -import { useStore } from 'hooks' +import { checkPermissions, useStore } from 'hooks' import { confirmAlert } from 'components/to-be-cleaned/ModalsDeprecated/ConfirmModal' import Table from 'components/to-be-cleaned/Table' import NoSearchResults from 'components/to-be-cleaned/NoSearchResults' +import InformationBox from 'components/ui/InformationBox' interface Props { onSelectPublication: (id: number) => void @@ -15,6 +17,17 @@ const PublicationsList: FC = ({ onSelectPublication = () => {} }) => { const { ui, meta } = useStore() const [filterString, setFilterString] = useState('') + const canUpdatePublications = checkPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'publications' + ) + + const publicationEvents = [ + { event: 'Insert', key: 'publish_insert' }, + { event: 'Update', key: 'publish_update' }, + { event: 'Delete', key: 'publish_delete' }, + { event: 'Truncate', key: 'publish_truncate' }, + ] const publications = filterString.length === 0 ? meta.publications.list() @@ -51,17 +64,22 @@ const PublicationsList: FC = ({ onSelectPublication = () => {} }) => {
-
- } - placeholder={'Filter'} - value={filterString} - onChange={(e) => setFilterString(e.target.value)} + } + placeholder={'Filter'} + value={filterString} + onChange={(e) => setFilterString(e.target.value)} + /> +
+ {!canUpdatePublications && ( +
+ } + title="You need additional permissions to update database replications" />
-
-
+ )}
{publications.length === 0 ? ( @@ -98,42 +116,18 @@ const PublicationsList: FC = ({ onSelectPublication = () => {} }) => { {x.id} - -
- toggleListenEvent(x, 'insert', x.publish_insert)} - /> -
-
- -
- toggleListenEvent(x, 'update', x.publish_update)} - /> -
-
- -
- toggleListenEvent(x, 'delete', x.publish_delete)} - /> -
-
- -
- toggleListenEvent(x, 'truncate', x.publish_truncate)} - /> -
-
+ {publicationEvents.map((event) => ( + +
+ toggleListenEvent(x, 'insert', x[event.key])} + /> +
+
+ ))}
-
+ {!canUpdatePublications && ( +
+ } + title="You need additional permissions to update database replications" + /> +
+ )}
{tables.length === 0 ? ( diff --git a/studio/components/layouts/ProjectLayout/ProjectLayout.tsx b/studio/components/layouts/ProjectLayout/ProjectLayout.tsx index 15b9292cd35..7830458c91c 100644 --- a/studio/components/layouts/ProjectLayout/ProjectLayout.tsx +++ b/studio/components/layouts/ProjectLayout/ProjectLayout.tsx @@ -31,12 +31,17 @@ const ProjectLayout = ({ hideHeader = false, hideIconBar = false, }: PropsWithChildren) => { + const { ui } = useStore() const ongoingIncident = useFlag('ongoingIncident') + const projectName = ui.selectedProject?.name + return ( <> - {title ? `${title} | Supabase` : 'Supabase'} + + {title ? `${title} | Supabase` : projectName ? `${projectName} | Supabase` : 'Supabase'} + diff --git a/studio/pages/project/[ref]/database/extensions.tsx b/studio/pages/project/[ref]/database/extensions.tsx index 3eecae6a8a1..24fcb9af95d 100644 --- a/studio/pages/project/[ref]/database/extensions.tsx +++ b/studio/pages/project/[ref]/database/extensions.tsx @@ -13,11 +13,7 @@ const DatabaseExtensions: NextPageWithLayout = () => { return } - return ( -
- -
- ) + return } DatabaseExtensions.getLayout = (page) => {page} diff --git a/studio/pages/project/[ref]/database/replication.tsx b/studio/pages/project/[ref]/database/replication.tsx index e86f8f83853..d088599b009 100644 --- a/studio/pages/project/[ref]/database/replication.tsx +++ b/studio/pages/project/[ref]/database/replication.tsx @@ -1,10 +1,12 @@ import { useState } from 'react' import { observer } from 'mobx-react-lite' +import { PermissionAction } from '@supabase/shared-types/out/constants' -import { useStore } from 'hooks' +import { checkPermissions, useStore } from 'hooks' import { NextPageWithLayout } from 'types' import { DatabaseLayout } from 'components/layouts' import { PublicationsList, PublicationsTables } from 'components/interfaces/Database' +import NoPermission from 'components/ui/NoPermission' // [Joshen] Technically, best that we have these as separate URLs // makes it easier to manage state, but foresee that this page might @@ -14,9 +16,18 @@ const DatabaseReplication: NextPageWithLayout = () => { const { meta } = useStore() const publications = meta.publications.list() + const canViewPublications = checkPermissions( + PermissionAction.TENANT_SQL_ADMIN_READ, + 'publications' + ) + const [selectedPublicationId, setSelectedPublicationId] = useState() const selectedPublication = publications.find((pub) => pub.id === selectedPublicationId) + if (!canViewPublications) { + return + } + return (
{selectedPublicationId === undefined ? (