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

Bug/5354 dashboard sharing blocked no owner #9015

Merged
merged 8 commits into from
Jul 26, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ import {
PERMISSION_DELEGATE_MODULE_SHARING_MANAGEMENT,
PERMISSION_MANAGE_MODULE_SHARING_OPTIONS,
} from '../../../googlesitekit/datastore/user/constants';
import WarningNotice from '../../WarningNotice';
import Link from '../../Link';

const viewAccessOptions = [
{
Expand All @@ -65,14 +67,25 @@ const viewAccessOptions = [
},
];

export default function Module( { moduleSlug, moduleName, ownerUsername } ) {
export default function Module( {
moduleSlug,
moduleName,
ownerUsername,
recoverable,
} ) {
const viewContext = useViewContext();
const moduleRef = useRef();

const [ manageViewAccess, setManageViewAccess ] = useState( undefined );

const hasRecoverableModules = useSelect( ( select ) =>
select( CORE_MODULES ).hasRecoverableModules()
);
const hasMultipleAdmins = useSelect( ( select ) =>
select( CORE_SITE ).hasMultipleAdmins()
);
const showManageColumn = hasRecoverableModules || hasMultipleAdmins;

const management = useSelect(
( select ) =>
select( CORE_MODULES ).getSharingManagement( moduleSlug ) ?? 'owner'
Expand All @@ -99,6 +112,12 @@ export default function Module( { moduleSlug, moduleName, ownerUsername } ) {
select( CORE_MODULES ).isDoingSubmitSharingChanges()
);

const recoverableModuleSupportLink = useSelect( ( select ) =>
select( CORE_SITE ).getDocumentationLinkURL(
'dashboard-sharing-module-recovery'
)
);

const { setSharingManagement } = useDispatch( CORE_MODULES );

const sharedOwnershipModule =
Expand Down Expand Up @@ -180,7 +199,27 @@ export default function Module( { moduleSlug, moduleName, ownerUsername } ) {
/>
) }

{ ! hasSharingCapability && (
{ recoverable && (
<WarningNotice>
{ createInterpolateElement(
__(
'Managing user required to manage view access. <Link>Learn more</Link>',
'google-site-kit'
),
{
Link: (
<Link
href={ recoverableModuleSupportLink }
external
hideExternalIndicator
/>
),
}
) }
</WarningNotice>
) }

{ ! hasSharingCapability && ! recoverable && (
<p className="googlesitekit-dashboard-sharing-settings__note">
{ __(
'Contact managing user to manage view access',
Expand All @@ -190,7 +229,7 @@ export default function Module( { moduleSlug, moduleName, ownerUsername } ) {
) }
</div>

{ hasMultipleAdmins && (
{ showManageColumn && (
<div className="googlesitekit-dashboard-sharing-settings__column--manage">
{ sharedOwnershipModule && (
<p className="googlesitekit-dashboard-sharing-settings__note">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,16 @@ import {
} from '../../../googlesitekit/datastore/user/constants';

export default function DashboardSharingSettings() {
const hasRecoverableModules = useSelect( ( select ) =>
select( CORE_MODULES ).hasRecoverableModules()
);

const hasMultipleAdmins = useSelect( ( select ) =>
select( CORE_SITE ).hasMultipleAdmins()
);

const showManageColumn = hasRecoverableModules || hasMultipleAdmins;

const sortedShareableModules = useSelect( ( select ) => {
const userID = select( CORE_USER ).getID();
const shareableModules = select( CORE_MODULES ).getShareableModules();
Expand Down Expand Up @@ -79,7 +85,7 @@ export default function DashboardSharingSettings() {
'googlesitekit-dashboard-sharing-settings',
{
'googlesitekit-dashboard-sharing-settings--has-multiple-admins':
hasMultipleAdmins,
showManageColumn,
}
) }
>
Expand All @@ -91,7 +97,7 @@ export default function DashboardSharingSettings() {
{ __( 'Who can view', 'google-site-kit' ) }
</div>

{ hasMultipleAdmins && (
{ showManageColumn && (
<div className="googlesitekit-dashboard-sharing-settings__column--manage">
{ __(
'Who can manage view access',
Expand All @@ -102,14 +108,17 @@ export default function DashboardSharingSettings() {
</header>

<div className="googlesitekit-dashboard-sharing-settings__main">
{ sortedShareableModules.map( ( { slug, name, owner } ) => (
<Module
key={ slug }
moduleSlug={ slug }
moduleName={ name }
ownerUsername={ owner?.login }
/>
) ) }
{ sortedShareableModules.map(
( { slug, name, owner, recoverable } ) => (
<Module
key={ slug }
moduleSlug={ slug }
moduleName={ name }
ownerUsername={ owner?.login }
recoverable={ recoverable }
/>
)
) }
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe( 'DashboardSharingSettings', () => {
expect( container ).toHaveTextContent( 'Search Console' );
} );

it( 'should render the modules with user role select when the admin owns the modules', () => {
it( 'should render the modules with user role select when the admin owns the modules', async () => {
act( () => {
provideModules( registry, modules );
provideModuleRegistrations( registry );
Expand All @@ -107,9 +107,15 @@ describe( 'DashboardSharingSettings', () => {
.dispatch( MODULES_SEARCH_CONSOLE )
.receiveGetSettings( { ownerID: 1 } );
} );
const { container } = render( <DashboardSharingSettings />, {
registry,
} );

const { container, waitForRegistry } = render(
<DashboardSharingSettings />,
{
registry,
}
);

await waitForRegistry();

expect(
container.querySelector(
Expand All @@ -118,7 +124,7 @@ describe( 'DashboardSharingSettings', () => {
).toBeInTheDocument();
} );

it( 'should not render sharing management for a single admin environment', () => {
it( 'should not render sharing management for a single admin environment', async () => {
act( () => {
provideModules( registry, modules );
provideModuleRegistrations( registry );
Expand All @@ -144,9 +150,14 @@ describe( 'DashboardSharingSettings', () => {
.dispatch( MODULES_SEARCH_CONSOLE )
.receiveGetSettings( { ownerID: 1 } );
} );
const { container } = render( <DashboardSharingSettings />, {
registry,
} );
const { container, waitForRegistry } = render(
<DashboardSharingSettings />,
{
registry,
}
);

await waitForRegistry();

expect( container ).not.toHaveTextContent(
'Who can manage view access'
Expand Down
19 changes: 19 additions & 0 deletions assets/js/googlesitekit/modules/datastore/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,25 @@ const baseSelectors = {
return calculateRecoverableModules( modules, state.recoverableModules );
} ),

/**
* Checks if there are any recoverable modules for dashboard sharing.
*
* @since n.e.x.t
*
* @param {Object} state Data store's state.
* @return {(boolean|undefined)} `true` if there are recoverable modules.
* `false` if there are none.
* `undefined` if not loaded.
*/
hasRecoverableModules: ( state ) => {
// Return `undefined` if recoverableModules haven't been loaded yet.
if ( state.recoverableModules === undefined ) {
return undefined;
}

return Object.keys( state.recoverableModules ).length > 0;
},

/**
* Gets the list of shared ownership modules for dashboard sharing.
*
Expand Down
10 changes: 10 additions & 0 deletions assets/sass/components/global/_googlesitekit-sharing-settings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@
display: flex;
flex: 1 1 45%;
}

.googlesitekit-warning-notice {
margin-right: $grid-gap-desktop;
padding: $grid-gap-phone / 2 $grid-gap-phone;

.googlesitekit-cta-link {
font-weight: $fw-normal;
text-decoration: underline;
}
}
}

.googlesitekit-dashboard-sharing-settings__row {
Expand Down
Loading