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

[FIX] Showing Workspace Section For User Having LiveChat Manager Permission #27188

Merged
merged 9 commits into from Jan 3, 2023
Expand Up @@ -10,7 +10,7 @@ import AuditModelList from './AuditModelList';

type AdministrationListProps = {
accountBoxItems: (IAppAccountBoxItem | AccountBoxItem)[];
closeList: () => void;
onDismiss: () => void;
hasAdminPermission: boolean;
hasAuditLicense: boolean;
hasAuditPermission: boolean;
Expand All @@ -24,18 +24,19 @@ const AdministrationList: FC<AdministrationListProps> = ({
hasAuditLogPermission,
hasManageApps,
hasAdminPermission,
closeList,
onDismiss,
}) => {
const appBoxItems = accountBoxItems.filter((item): item is IAppAccountBoxItem => isAppAccountBoxItem(item));
const adminBoxItems = accountBoxItems.filter((item): item is AccountBoxItem => !isAppAccountBoxItem(item));
const showAudit = hasAuditPermission || hasAuditLogPermission;
const showManageApps = hasManageApps || !!appBoxItems.length;
const showAdmin = hasAdminPermission || !!adminBoxItems.length;
const showWorkspace = hasAdminPermission;

const list = [
showAdmin && <AdministrationModelList showAdmin={showAdmin} accountBoxItems={adminBoxItems} closeList={closeList} />,
showManageApps && <AppsModelList appBoxItems={appBoxItems} closeList={closeList} showManageApps={showManageApps} />,
showAudit && <AuditModelList showAudit={hasAuditPermission} showAuditLog={hasAuditLogPermission} closeList={closeList} />,
showAdmin && <AdministrationModelList showWorkspace={showWorkspace} accountBoxItems={adminBoxItems} onDismiss={onDismiss} />,
showManageApps && <AppsModelList appBoxItems={appBoxItems} appsManagementAllowed={hasManageApps} onDismiss={onDismiss} />,
showAudit && <AuditModelList showAudit={hasAuditPermission} showAuditLog={hasAuditLogPermission} onDismiss={onDismiss} />,
];

return (
Expand Down
Expand Up @@ -13,13 +13,13 @@ import ListItem from '../Sidebar/ListItem';

type AdministrationModelListProps = {
accountBoxItems: AccountBoxItem[];
showAdmin: boolean;
closeList: () => void;
showWorkspace: boolean;
onDismiss: () => void;
};

const INFO_PERMISSIONS = ['view-statistics'];

const AdministrationModelList: FC<AdministrationModelListProps> = ({ accountBoxItems, showAdmin, closeList }) => {
const AdministrationModelList: FC<AdministrationModelListProps> = ({ accountBoxItems, showWorkspace, onDismiss }) => {
const t = useTranslation();
const { tabType, trialEndDate, isLoading } = useUpgradeTabParams();
const shouldShowEmoji = isFullyFeature(tabType);
Expand All @@ -35,37 +35,35 @@ const AdministrationModelList: FC<AdministrationModelListProps> = ({ accountBoxI
<>
<OptionTitle>{t('Administration')}</OptionTitle>
<ul>
{showAdmin && (
<>
{showUpgradeItem && (
<ListItem
icon='arrow-stack-up'
text={
<>
{t(label)} {shouldShowEmoji && <Emoji emojiHandle=':zap:' />}
</>
}
action={(): void => {
upgradeRoute.push({ type: tabType }, trialEndDate ? { trialEndDate } : undefined);
closeList();
}}
/>
)}
<ListItem
icon='cog'
text={t('Workspace')}
action={(): void => {
if (hasInfoPermission) {
infoRoute.push();
closeList();
return;
}
{showUpgradeItem && (
<ListItem
icon='arrow-stack-up'
text={
<>
{t(label)} {shouldShowEmoji && <Emoji emojiHandle=':zap:' />}
</>
}
action={(): void => {
upgradeRoute.push({ type: tabType }, trialEndDate ? { trialEndDate } : undefined);
onDismiss();
}}
/>
)}
{showWorkspace && (
<ListItem
icon='cog'
text={t('Workspace')}
action={(): void => {
if (hasInfoPermission) {
infoRoute.push();
onDismiss();
return;
}

adminRoute.push({ context: '/' });
closeList();
}}
/>
</>
adminRoute.push({ context: '/' });
onDismiss();
}}
/>
)}
{accountBoxItems.length > 0 && (
<>
Expand All @@ -74,7 +72,7 @@ const AdministrationModelList: FC<AdministrationModelListProps> = ({ accountBoxI
if (item.href) {
FlowRouter.go(item.href);
}
closeList();
onDismiss();
};

return <ListItem text={t(item.name)} icon={item.icon} action={action} key={item.name + key} />;
Expand Down
Expand Up @@ -9,11 +9,11 @@ import ListItem from '../Sidebar/ListItem';

type AppsModelListProps = {
appBoxItems: IAppAccountBoxItem[];
showManageApps: boolean;
closeList: () => void;
appsManagementAllowed: boolean;
onDismiss: () => void;
};

const AppsModelList = ({ appBoxItems, showManageApps, closeList }: AppsModelListProps): ReactElement => {
const AppsModelList = ({ appBoxItems, appsManagementAllowed, onDismiss }: AppsModelListProps): ReactElement => {
const t = useTranslation();
const marketplaceRoute = useRoute('admin-marketplace');
const page = 'list';
Expand All @@ -22,22 +22,22 @@ const AppsModelList = ({ appBoxItems, showManageApps, closeList }: AppsModelList
<>
<OptionTitle>{t('Apps')}</OptionTitle>
<ul>
{showManageApps && (
{appsManagementAllowed && (
<>
<ListItem
icon='store'
text={t('Marketplace')}
action={(): void => {
marketplaceRoute.push({ context: 'all', page });
closeList();
onDismiss();
}}
/>
<ListItem
icon='cube'
text={t('Installed')}
action={(): void => {
marketplaceRoute.push({ context: 'installed', page });
closeList();
onDismiss();
}}
/>
</>
Expand All @@ -53,7 +53,7 @@ const AppsModelList = ({ appBoxItems, showManageApps, closeList }: AppsModelList
appId: item.appId,
payload: { context: item.context },
});
closeList();
onDismiss();
};
return <ListItem text={(t.has(item.name) && t(item.name)) || item.name} action={action} key={item.actionId + key} />;
})}
Expand Down
Expand Up @@ -6,12 +6,12 @@ import React from 'react';
import ListItem from '../Sidebar/ListItem';

type AuditModelListProps = {
closeList: () => void;
onDismiss: () => void;
showAudit: boolean;
showAuditLog: boolean;
};

const AuditModelList: FC<AuditModelListProps> = ({ showAudit, showAuditLog, closeList }) => {
const AuditModelList: FC<AuditModelListProps> = ({ showAudit, showAuditLog, onDismiss }) => {
const t = useTranslation();

const auditHomeRoute = useRoute('audit-home');
Expand All @@ -27,7 +27,7 @@ const AuditModelList: FC<AuditModelListProps> = ({ showAudit, showAuditLog, clos
text={t('Messages')}
action={(): void => {
auditHomeRoute.push();
closeList();
onDismiss();
}}
/>
)}
Expand All @@ -37,7 +37,7 @@ const AuditModelList: FC<AuditModelListProps> = ({ showAudit, showAuditLog, clos
text={t('Logs')}
action={(): void => {
auditSettingsRoute.push();
closeList();
onDismiss();
}}
/>
)}
Expand Down
Expand Up @@ -58,7 +58,7 @@ const Administration: VFC<Omit<HTMLAttributes<HTMLElement>, 'is'>> = (props) =>
<Dropdown reference={reference} ref={target}>
<AdministrationList
accountBoxItems={accountBoxItems}
closeList={(): void => toggle(false)}
onDismiss={(): void => toggle(false)}
hasAdminPermission={hasAdminPermission}
hasAuditLicense={hasAuditLicense}
hasAuditPermission={hasAuditPermission}
Expand Down
Expand Up @@ -3,34 +3,38 @@ import { expect } from 'chai';
import proxyquire from 'proxyquire';
import React from 'react';

const COMPONENT_PATH = '../../../../../client/components/AdministrationList/AdministrationList';
const defaultConfig = {
'@rocket.chat/ui-contexts': {
useAtLeastOnePermission: () => true,
},
'../../../app/ui-utils/client/lib/AccountBox': {
AccountBoxItem: {},
isAppAccountBoxItem: () => false,
},
'../../../ee/client/hooks/useHasLicenseModule': {
useHasLicenseModule: () => true,
},
'./AdministrationModelList': () => <p>Administration Model List</p>,
'./AppsModelList': () => <p>Apps Model List</p>,
'./AuditModelList': () => <p>Audit Model List</p>,
const mockAdministrationListModule = (stubs = {}) => {
return proxyquire.noCallThru().load('../../../../../client/components/AdministrationList/AdministrationList', {
'@rocket.chat/ui-contexts': {
useAtLeastOnePermission: () => true,
},
'../../../app/ui-utils/client/lib/AccountBox': {
AccountBoxItem: {},
isAppAccountBoxItem: () => false,
},
'../../../ee/client/hooks/useHasLicenseModule': {
useHasLicenseModule: () => true,
},
'./AdministrationModelList': () => <p>Administration Model List</p>,
'./AppsModelList': () => <p>Apps Model List</p>,
'./AuditModelList': () => <p>Audit Model List</p>,
...stubs,
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
}) as typeof import('../../../../../client/components/AdministrationList/AdministrationList');
};

describe('components/AdministrationList/AdministrationList', () => {
it('should render all model list', async () => {
const AdministrationList = proxyquire.noCallThru().load(COMPONENT_PATH, defaultConfig).default;
const AdministrationList = mockAdministrationListModule().default;
render(
<AdministrationList
closeList={() => null}
accountBoxItems={[{}]}
accountBoxItems={[{} as any]}
hasAuditPermission={true}
hasAuditLogPermission={true}
hasManageApps={true}
hasAdminPermission={true}
hasAuditLicense={false}
onDismiss={() => null}
/>,
);

Expand All @@ -40,36 +44,53 @@ describe('components/AdministrationList/AdministrationList', () => {
});

it('should render nothing when no permission', async () => {
const AdministrationList = proxyquire.noCallThru().load(COMPONENT_PATH, {
...defaultConfig,
const AdministrationList = mockAdministrationListModule({
'@rocket.chat/ui-contexts': {
useAtLeastOnePermission: () => false,
},
}).default;
render(<AdministrationList closeList={() => null} accountBoxItems={[]} />);
render(
<AdministrationList
hasAdminPermission={false}
hasAuditLicense={false}
hasAuditLogPermission={false}
hasAuditPermission={false}
hasManageApps={false}
accountBoxItems={[]}
onDismiss={() => null}
/>,
);

expect(screen.queryByText('Administration Model List')).to.not.exist;
expect(screen.queryByText('Apps Model List')).to.not.exist;
expect(screen.queryByText('Audit Model List')).to.not.exist;
});

it('should render administration model list when has account box item', async () => {
const AdministrationList = proxyquire.noCallThru().load(COMPONENT_PATH, {
...defaultConfig,
const AdministrationList = mockAdministrationListModule({
'@rocket.chat/ui-contexts': {
useAtLeastOnePermission: () => false,
},
}).default;
render(<AdministrationList closeList={() => null} accountBoxItems={[{}]} />);
render(
<AdministrationList
hasAdminPermission={false}
hasAuditLicense={false}
hasAuditLogPermission={false}
hasAuditPermission={false}
hasManageApps={false}
accountBoxItems={[{} as any]}
onDismiss={() => null}
/>,
);

expect(screen.getByText('Administration Model List')).to.exist;
expect(screen.queryByText('Apps Model List')).to.not.exist;
expect(screen.queryByText('Audit Model List')).to.not.exist;
});

it('should render apps model list when has app account box item', async () => {
const AdministrationList = proxyquire.noCallThru().load(COMPONENT_PATH, {
...defaultConfig,
const AdministrationList = mockAdministrationListModule({
'../../../app/ui-utils/client/lib/AccountBox': {
'AccountBoxItem': {},
'isAppAccountBoxItem': () => true,
Expand All @@ -79,7 +100,17 @@ describe('components/AdministrationList/AdministrationList', () => {
useAtLeastOnePermission: () => false,
},
}).default;
render(<AdministrationList closeList={() => null} accountBoxItems={[{}]} />);
render(
<AdministrationList
hasAdminPermission={false}
hasAuditLicense={false}
hasAuditLogPermission={false}
hasAuditPermission={false}
hasManageApps={false}
accountBoxItems={[{} as any]}
onDismiss={() => null}
/>,
);

expect(screen.getByText('Apps Model List')).to.exist;
expect(screen.queryByText('Administration Model List')).to.not.exist;
Expand Down