Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative: restrict Navigation permissions and show UI warning if cannot create #37454

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8849edf
Test for publish abtility and display warning
getdave Dec 10, 2021
602f812
Update creation of Nav posts to require admin perms
getdave Dec 13, 2021
86016bc
Only show menu creation option if user has permission to create
getdave Dec 13, 2021
dab6f77
Move permission selectors to hook
getdave Dec 17, 2021
316b107
Show warning if unable to create Navigation Menus
getdave Dec 16, 2021
2632271
Copy changes from Core patch
getdave Dec 16, 2021
6b440f6
Only show error if create is not allowed
getdave Dec 16, 2021
26ed2b2
Revert "Copy changes from Core patch"
getdave Dec 16, 2021
8efde3d
Use streamlined permissions
getdave Dec 17, 2021
4fd4fc2
Remove inline warning and reenable ability to select existing
getdave Dec 17, 2021
7ff2e75
Refactor Notices to reusable hook
getdave Dec 17, 2021
5745d79
Add notices for creating Menus
getdave Dec 17, 2021
3bbcffd
Rename dep for clarity
getdave Dec 17, 2021
2a56786
Hide other creation options
getdave Dec 17, 2021
07ccae4
Add e2e test
getdave Dec 17, 2021
b4a7621
Hide classic Menus from dropdown
getdave Dec 17, 2021
8676d2a
Fix up e2e tests following changes from rebase
getdave Dec 17, 2021
230b9d9
Update to make component props more agnostic
getdave Dec 17, 2021
a90dc3d
Make component props less tighly coupled to permissions
getdave Dec 17, 2021
2d4c890
Remove unneeded undefined fallback
getdave Dec 17, 2021
4b630e5
Refactor hooks
getdave Dec 17, 2021
50ccac1
Try switch user to admin
getdave Dec 17, 2021
5c2597e
Try switching back to admin after each permissions test
getdave Dec 17, 2021
4430a51
Try targetting test that relies on avoiding a 404 from URL details en…
getdave Dec 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/navigation.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ function gutenberg_register_navigation_post_type() {
'editor',
'revisions',
),
'capabilities' => array(
getdave marked this conversation as resolved.
Show resolved Hide resolved
'edit_others_posts' => 'edit_theme_options',
'delete_posts' => 'edit_theme_options',
'publish_posts' => 'edit_theme_options',
'create_posts' => 'edit_theme_options',
'read_private_posts' => 'edit_theme_options',
'delete_private_posts' => 'edit_theme_options',
'delete_published_posts' => 'edit_theme_options',
'delete_others_posts' => 'edit_theme_options',
'edit_private_posts' => 'edit_theme_options',
'edit_published_posts' => 'edit_theme_options',
),
);

register_post_type( 'wp_navigation', $args );
Expand Down
93 changes: 47 additions & 46 deletions packages/block-library/src/navigation/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import {
Button,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { store as noticeStore } from '@wordpress/notices';

/**
* Internal dependencies
Expand All @@ -54,6 +53,7 @@ import NavigationMenuSelector from './navigation-menu-selector';
import NavigationMenuNameControl from './navigation-menu-name-control';
import UnsavedInnerBlocks from './unsaved-inner-blocks';
import NavigationMenuDeleteControl from './navigation-menu-delete-control';
import useNavigationNotice from './use-navigation-notice';

const EMPTY_ARRAY = [];

Expand Down Expand Up @@ -107,8 +107,6 @@ function Navigation( {
customPlaceholder: CustomPlaceholder = null,
customAppender: CustomAppender = null,
} ) {
const noticeRef = useRef();

const {
openSubmenusOnClick,
overlayMenu,
Expand Down Expand Up @@ -192,8 +190,6 @@ function Navigation( {
__unstableMarkNextChangeAsNotPersistent,
} = useDispatch( blockEditorStore );

const { createWarningNotice, removeNotice } = useDispatch( noticeStore );

const [
hasSavedUnsavedInnerBlocks,
setHasSavedUnsavedInnerBlocks,
Expand All @@ -220,6 +216,8 @@ function Navigation( {
hasResolvedCanUserUpdateNavigationEntity,
canUserDeleteNavigationEntity,
hasResolvedCanUserDeleteNavigationEntity,
canUserCreateNavigation,
hasResolvedCanUserCreateNavigation,
} = useNavigationMenu( ref );

const navRef = useRef();
Expand Down Expand Up @@ -307,7 +305,7 @@ function Navigation( {
setDetectedColor,
setDetectedBackgroundColor
);
const subMenuElement = navRef.current.querySelector(
const subMenuElement = navRef.current?.querySelector(
'[data-type="core/navigation-link"] [data-type="core/navigation-link"]'
);
if ( subMenuElement ) {
Expand Down Expand Up @@ -336,52 +334,52 @@ function Navigation( {
}
}, [ clientId, ref, hasUncontrolledInnerBlocks, controlledInnerBlocks ] );

useEffect( () => {
const setPermissionsNotice = () => {
if ( noticeRef.current ) {
return;
}

noticeRef.current =
'block-library/core/navigation/permissions/update';

createWarningNotice(
__(
'You do not have permission to edit this Menu. Any changes made will not be saved.'
),
{
id: noticeRef.current,
type: 'snackbar',
}
);
};
const [ showCantEditNotice, hideCantEditNotice ] = useNavigationNotice( {
name: 'block-library/core/navigation/permissions/update',
message: __(
'You do not have permission to edit this Menu. Any changes made will not be saved.'
),
} );

const removePermissionsNotice = () => {
if ( ! noticeRef.current ) {
return;
}
removeNotice( noticeRef.current );
noticeRef.current = null;
};
const [ showCantCreateNotice, hideCantCreateNotice ] = useNavigationNotice(
{
name: 'block-library/core/navigation/permissions/create',
message: __(
'You do not have permission to create Navigation Menus.'
),
}
);

useEffect( () => {
if ( ! isSelected && ! isInnerBlockSelected ) {
removePermissionsNotice();
hideCantEditNotice();
hideCantCreateNotice();
}

if (
( isSelected || isInnerBlockSelected ) &&
hasResolvedCanUserUpdateNavigationEntity &&
! canUserUpdateNavigationEntity
) {
setPermissionsNotice();
if ( isSelected || isInnerBlockSelected ) {
if (
hasResolvedCanUserUpdateNavigationEntity &&
! canUserUpdateNavigationEntity
) {
showCantEditNotice();
}

if (
! ref &&
hasResolvedCanUserCreateNavigation &&
! canUserCreateNavigation
) {
showCantCreateNotice();
}
}
}, [
ref,
isEntityAvailable,
hasResolvedCanUserUpdateNavigationEntity,
canUserUpdateNavigationEntity,
isSelected,
isInnerBlockSelected,
canUserUpdateNavigationEntity,
hasResolvedCanUserUpdateNavigationEntity,
canUserCreateNavigation,
hasResolvedCanUserCreateNavigation,
ref,
] );

const startWithEmptyMenu = useCallback( () => {
Expand Down Expand Up @@ -488,6 +486,7 @@ function Navigation( {
onClose();
} }
onCreateNew={ startWithEmptyMenu }
showCreate={ canUserCreateNavigation }
/>
) }
</ToolbarDropdownMenu>
Expand Down Expand Up @@ -642,11 +641,13 @@ function Navigation( {
hasResolvedNavigationMenus
}
clientId={ clientId }
canUserCreateNavigation={ canUserCreateNavigation }
/>
) }
{ ! isEntityAvailable && ! isPlaceholderShown && (
<PlaceholderPreview isLoading />
) }
{ ! hasResolvedCanUserCreateNavigation ||
( ! isEntityAvailable && ! isPlaceholderShown && (
getdave marked this conversation as resolved.
Show resolved Hide resolved
<PlaceholderPreview isLoading />
) ) }
{ ! isPlaceholderShown && (
<ResponsiveWrapper
id={ clientId }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import { addQueryArgs } from '@wordpress/url';
*/
import useNavigationMenu from '../use-navigation-menu';

export default function NavigationMenuSelector( { onSelect, onCreateNew } ) {
export default function NavigationMenuSelector( {
onSelect,
onCreateNew,
showCreate = false,
} ) {
const { navigationMenus } = useNavigationMenu();
const ref = useEntityId( 'postType', 'wp_navigation' );

Expand Down Expand Up @@ -42,18 +46,20 @@ export default function NavigationMenuSelector( { onSelect, onCreateNew } ) {
} ) }
/>
</MenuGroup>
<MenuGroup>
<MenuItem onClick={ onCreateNew }>
{ __( 'Create new menu' ) }
</MenuItem>
<MenuItem
href={ addQueryArgs( 'edit.php', {
post_type: 'wp_navigation',
} ) }
>
{ __( 'Manage menus' ) }
</MenuItem>
</MenuGroup>
{ showCreate && (
<MenuGroup>
<MenuItem onClick={ onCreateNew }>
{ __( 'Create new menu' ) }
</MenuItem>
<MenuItem
href={ addQueryArgs( 'edit.php', {
post_type: 'wp_navigation',
} ) }
>
{ __( 'Manage menus' ) }
</MenuItem>
</MenuGroup>
) }
</>
);
}
64 changes: 40 additions & 24 deletions packages/block-library/src/navigation/edit/placeholder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const ExistingMenusDropdown = ( {
onFinish,
menus,
onCreateFromMenu,
showClassicMenus = false,
} ) => {
const toggleProps = {
variant: 'tertiary',
Expand Down Expand Up @@ -65,22 +66,24 @@ const ExistingMenusDropdown = ( {
);
} ) }
</MenuGroup>
<MenuGroup label={ __( 'Classic Menus' ) }>
{ menus?.map( ( menu ) => {
return (
<MenuItem
onClick={ () => {
setSelectedMenu( menu.id );
onCreateFromMenu( menu.name );
} }
onClose={ onClose }
key={ menu.id }
>
{ decodeEntities( menu.name ) }
</MenuItem>
);
} ) }
</MenuGroup>
{ showClassicMenus && (
<MenuGroup label={ __( 'Classic Menus' ) }>
{ menus?.map( ( menu ) => {
return (
<MenuItem
onClick={ () => {
setSelectedMenu( menu.id );
onCreateFromMenu( menu.name );
} }
onClose={ onClose }
key={ menu.id }
>
{ decodeEntities( menu.name ) }
</MenuItem>
);
} ) }
</MenuGroup>
) }
</>
) }
</DropdownMenu>
Expand All @@ -92,6 +95,7 @@ export default function NavigationPlaceholder( {
onFinish,
canSwitchNavigationMenu,
hasResolvedNavigationMenus,
canUserCreateNavigation = false,
} ) {
const [ selectedMenu, setSelectedMenu ] = useState();
const [ isCreatingFromMenu, setIsCreatingFromMenu ] = useState( false );
Expand All @@ -102,6 +106,10 @@ export default function NavigationPlaceholder( {
blocks,
navigationMenuTitle = null
) => {
if ( ! canUserCreateNavigation ) {
getdave marked this conversation as resolved.
Show resolved Hide resolved
return;
}

const navigationMenu = await createNavigationMenu(
navigationMenuTitle,
blocks
Expand Down Expand Up @@ -176,8 +184,10 @@ export default function NavigationPlaceholder( {
<Icon icon={ navigation } />{ ' ' }
{ __( 'Navigation' ) }
</div>

<hr />
{ hasMenus || navigationMenus.length ? (

{ hasMenus || navigationMenus?.length ? (
<>
<ExistingMenusDropdown
canSwitchNavigationMenu={
Expand All @@ -188,11 +198,14 @@ export default function NavigationPlaceholder( {
onFinish={ onFinish }
menus={ menus }
onCreateFromMenu={ onCreateFromMenu }
showClassicMenus={
canUserCreateNavigation
}
/>
<hr />
</>
) : undefined }
{ hasPages ? (
{ canUserCreateNavigation && hasPages ? (
<>
<Button
variant="tertiary"
Expand All @@ -203,12 +216,15 @@ export default function NavigationPlaceholder( {
<hr />
</>
) : undefined }
<Button
variant="tertiary"
onClick={ onCreateEmptyMenu }
>
{ __( 'Start empty' ) }
</Button>

{ canUserCreateNavigation && (
<Button
variant="tertiary"
onClick={ onCreateEmptyMenu }
>
{ __( 'Start empty' ) }
</Button>
) }
</div>
</div>
</Placeholder>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* WordPress dependencies
*/
import { useRef } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { store as noticeStore } from '@wordpress/notices';

function useNavigationNotice( { name, message } = {} ) {
const noticeRef = useRef();

const { createWarningNotice, removeNotice } = useDispatch( noticeStore );

const showNotice = () => {
if ( noticeRef.current ) {
return;
}

noticeRef.current = name;

createWarningNotice( message, {
id: noticeRef.current,
type: 'snackbar',
} );
};

const hideNotice = () => {
if ( ! noticeRef.current ) {
return;
}
removeNotice( noticeRef.current );
noticeRef.current = null;
};

return [ showNotice, hideNotice ];
}

export default useNavigationNotice;
1 change: 1 addition & 0 deletions packages/block-library/src/navigation/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ $color-control-label-height: 20px;
font-size: $default-font-size;
font-family: $default-font;
gap: $grid-unit-15 * 0.5;
align-items: center;

// Margins.
.components-dropdown,
Expand Down
Loading