From ed52d94e9bb4c9602398b2b6c1f4e5c23b739951 Mon Sep 17 00:00:00 2001 From: Drew Lyton Date: Thu, 26 Sep 2024 10:28:09 -0400 Subject: [PATCH] feat: add permission dialog to banner --- .../RequestPermissionDialog.tsx | 10 ++-- .../sanity/src/structure/i18n/resources.ts | 2 + .../banners/PermissionCheckBanner.tsx | 52 +++++++++++++------ 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/packages/sanity/src/structure/components/requestPermissionDialog/RequestPermissionDialog.tsx b/packages/sanity/src/structure/components/requestPermissionDialog/RequestPermissionDialog.tsx index b69b78409c3..ef252500466 100644 --- a/packages/sanity/src/structure/components/requestPermissionDialog/RequestPermissionDialog.tsx +++ b/packages/sanity/src/structure/components/requestPermissionDialog/RequestPermissionDialog.tsx @@ -38,7 +38,7 @@ export const LoadingContainer = styled(Flex).attrs({ /** @internal */ export interface RequestPermissionDialogProps { - onCancel?: () => void + onClose?: () => void onRequstSubmitted?: () => void } @@ -50,7 +50,7 @@ export interface RequestPermissionDialogProps { * @internal */ export function RequestPermissionDialog({ - onCancel, + onClose, onRequstSubmitted, }: RequestPermissionDialogProps) { const {t} = useTranslation(structureLocaleNamespace) @@ -132,7 +132,7 @@ export function RequestPermissionDialog({ header={t('request-permission-dialog.header.text')} footer={{ cancelButton: { - onClick: onCancel, + onClick: onClose, text: t('confirm-dialog.cancel-button.fallback-text'), }, confirmButton: { @@ -143,8 +143,8 @@ export function RequestPermissionDialog({ onClick: onConfirm, }, }} - onClose={onCancel} - onClickOutside={onCancel} + onClose={onClose} + onClickOutside={onClose} > diff --git a/packages/sanity/src/structure/i18n/resources.ts b/packages/sanity/src/structure/i18n/resources.ts index 10c4e672164..32616fde154 100644 --- a/packages/sanity/src/structure/i18n/resources.ts +++ b/packages/sanity/src/structure/i18n/resources.ts @@ -114,6 +114,8 @@ const structureLocaleStrings = defineLocalesResources('structure', { /** The text for the permission check banner if the user only has multiple roles, but they do not allow updating this document */ 'banners.permission-check-banner.missing-permission_update_other': 'Your roles do not have permissions to update this document.', + /** The text for the request permission button that appears for viewer roles */ + 'banners.permission-check-banner.request-permission-button.text': 'Ask to edit', /** The text for the reload button */ 'banners.reference-changed-banner.reason-changed.reload-button.text': 'Reload reference', /** The text for the reference change banner if the reason is that the reference has been changed */ diff --git a/packages/sanity/src/structure/panes/document/documentPanel/banners/PermissionCheckBanner.tsx b/packages/sanity/src/structure/panes/document/documentPanel/banners/PermissionCheckBanner.tsx index 6514d1c384f..6fdc302b8bc 100644 --- a/packages/sanity/src/structure/panes/document/documentPanel/banners/PermissionCheckBanner.tsx +++ b/packages/sanity/src/structure/panes/document/documentPanel/banners/PermissionCheckBanner.tsx @@ -1,7 +1,9 @@ import {ReadOnlyIcon} from '@sanity/icons' import {Text} from '@sanity/ui' +import {useState} from 'react' import {Translate, useCurrentUser, useListFormat, useTranslation} from 'sanity' +import {RequestPermissionDialog} from '../../../../components/requestPermissionDialog/RequestPermissionDialog' import {structureLocaleNamespace} from '../../../../i18n' import {Banner} from './Banner' @@ -12,12 +14,17 @@ interface PermissionCheckBannerProps { export function PermissionCheckBanner({granted, requiredPermission}: PermissionCheckBannerProps) { const currentUser = useCurrentUser() + + const currentUserRoles = currentUser?.roles || [] + const isOnlyViewer = currentUserRoles.length === 1 && currentUserRoles[0].name === 'viewer' + const [showRequestPermissionDialog, setShowDialog] = useState(false) + const listFormat = useListFormat({style: 'short'}) const {t} = useTranslation(structureLocaleNamespace) if (granted) return null - const roleTitles = (currentUser?.roles || []).map((role) => role.title) + const roleTitles = currentUserRoles.map((role) => role.title) const roles = listFormat .formatToParts(roleTitles) .map((part) => @@ -25,20 +32,33 @@ export function PermissionCheckBanner({granted, requiredPermission}: PermissionC ) return ( - - <>{roles}}} - values={{count: roles.length, roles: roleTitles}} - context={requiredPermission} - /> - - } - data-testid="permission-check-banner" - icon={ReadOnlyIcon} - /> + <> + + <>{roles}}} + values={{count: roles.length, roles: roleTitles}} + context={requiredPermission} + /> + + } + action={ + isOnlyViewer + ? { + onClick: () => setShowDialog(true), + text: t('banners.permission-check-banner.request-permission-button.text'), + } + : undefined + } + data-testid="permission-check-banner" + icon={ReadOnlyIcon} + /> + {showRequestPermissionDialog && ( + setShowDialog(false)} /> + )} + ) }