Hide Apps tab for Admin (#2634) (#4221)

* Hide Apps tab for Admin

* Made users tab active is apps is not visible

* Add loading for groups, fix format issues

Co-authored-by: Dmytro Danylov <icdmytro.danylov@americanwell.com>
This commit is contained in:
Dmitriy Danilov 2022-10-12 19:27:12 +03:00 committed by GitHub
parent 4ac32b69d2
commit 0e7a4e6b38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 424 additions and 419 deletions

View file

@ -12,7 +12,7 @@ export const Container = function Container({
styles,
darkMode,
}) {
const { visibility, disabledState, borderRadius,borderColor } = styles;
const { visibility, disabledState, borderRadius, borderColor } = styles;
const backgroundColor =
['#fff', '#ffffffff'].includes(styles.backgroundColor) && darkMode ? '#232E3C' : styles.backgroundColor;
const computedStyles = {

View file

@ -7,6 +7,8 @@ import { toast } from 'react-hot-toast';
import { Link } from 'react-router-dom';
import { withTranslation } from 'react-i18next';
import { Loader } from '../ManageSSO/Loader';
class ManageGroupPermissionResourcesComponent extends React.Component {
constructor(props) {
super(props);
@ -50,6 +52,7 @@ class ManageGroupPermissionResourcesComponent extends React.Component {
groupPermissionService.getGroup(groupPermissionId).then((data) => {
this.setState({
groupPermission: data,
currentTab: data?.group === 'admin' ? 'users' : 'apps',
isLoadingGroup: false,
});
});
@ -163,11 +166,7 @@ class ManageGroupPermissionResourcesComponent extends React.Component {
};
findAppGroupPermission = (app, groupPermissionId) => {
const appGroupPermission = app.app_group_permissions.find(
(permission) => permission.group_permission_id === groupPermissionId
);
return appGroupPermission;
return app.app_group_permissions.find((permission) => permission.group_permission_id === groupPermissionId);
};
setSelectedUsers = (value) => {
@ -355,443 +354,449 @@ class ManageGroupPermissionResourcesComponent extends React.Component {
<div className="page-body">
<div className="container-xl">
<div className="card">
<nav className="nav nav-tabs">
<a
onClick={() => this.setState({ currentTab: 'apps' })}
className={cx('nav-item nav-link', { active: currentTab === 'apps' })}
data-cy="apps-link"
>
{this.props.t('header.organization.menus.manageGroups.permissionResources.apps', 'Apps')}
</a>
<a
onClick={() => this.setState({ currentTab: 'users' })}
className={cx('nav-item nav-link', { active: currentTab === 'users' })}
data-cy="users-link"
>
{this.props.t('header.organization.menus.manageGroups.permissionResources.users', 'Users')}
</a>
<a
onClick={() => this.setState({ currentTab: 'permissions' })}
className={cx('nav-item nav-link', { active: currentTab === 'permissions' })}
data-cy="permissions-link"
>
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.permissions',
'Permissions'
{isLoadingGroup ? (
<Loader />
) : (
<div className="card">
<nav className="nav nav-tabs">
{groupPermission?.group !== 'admin' && (
<a
onClick={() => this.setState({ currentTab: 'apps' })}
className={cx('nav-item nav-link', { active: currentTab === 'apps' })}
data-cy="apps-link"
>
{this.props.t('header.organization.menus.manageGroups.permissionResources.apps', 'Apps')}
</a>
)}
</a>
</nav>
<div className="card-body">
<div className="tab-content">
{/* Apps Tab */}
<div className={`tab-pane ${currentTab === 'apps' ? 'active show' : ''}`}>
{groupPermission?.group !== 'admin' && (
<div className="row">
<div className="col-5" data-cy="select-search">
<SelectSearch
className={`${this.props.darkMode ? 'select-search-dark' : 'select-search'}`}
options={appSelectOptions}
closeOnSelect={false}
multiple
search={true}
value={selectedAppIds}
filterOptions={fuzzySearch}
onChange={(value) => this.setSelectedApps(value)}
printOptions="on-focus"
placeholder={this.props.t(
'header.organization.menus.manageGroups.permissionResources.addAppsToGroup',
'Select apps to add to the group'
)}
/>
</div>
<div className="col-auto">
<div
className={`btn btn-primary w-100 ${isAddingApps ? 'btn-loading' : ''} ${
selectedAppIds.length === 0 ? 'disabled' : ''
}`}
onClick={() => this.addSelectedAppsToGroup(groupPermission.id, selectedAppIds)}
data-cy="add-button"
>
{this.props.t('globals.add', 'Add')}
<a
onClick={() => this.setState({ currentTab: 'users' })}
className={cx('nav-item nav-link', { active: currentTab === 'users' })}
data-cy="users-link"
>
{this.props.t('header.organization.menus.manageGroups.permissionResources.users', 'Users')}
</a>
<a
onClick={() => this.setState({ currentTab: 'permissions' })}
className={cx('nav-item nav-link', { active: currentTab === 'permissions' })}
data-cy="permissions-link"
>
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.permissions',
'Permissions'
)}
</a>
</nav>
<div className="card-body">
<div className="tab-content">
{/* Apps Tab */}
<div className={`tab-pane ${currentTab === 'apps' ? 'active show' : ''}`}>
{groupPermission?.group !== 'admin' && (
<div className="row">
<div className="col-5" data-cy="select-search">
<SelectSearch
className={`${this.props.darkMode ? 'select-search-dark' : 'select-search'}`}
options={appSelectOptions}
closeOnSelect={false}
multiple
search={true}
value={selectedAppIds}
filterOptions={fuzzySearch}
onChange={(value) => this.setSelectedApps(value)}
printOptions="on-focus"
placeholder={this.props.t(
'header.organization.menus.manageGroups.permissionResources.addAppsToGroup',
'Select apps to add to the group'
)}
/>
</div>
<div className="col-auto">
<div
className={`btn btn-primary w-100 ${isAddingApps ? 'btn-loading' : ''} ${
selectedAppIds.length === 0 ? 'disabled' : ''
}`}
onClick={() => this.addSelectedAppsToGroup(groupPermission.id, selectedAppIds)}
data-cy="add-button"
>
{this.props.t('globals.add', 'Add')}
</div>
</div>
</div>
</div>
)}
<br />
<div>
<div className="table-responsive">
<table className="table table-vcenter">
<thead>
<tr>
<th data-cy="name-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.name',
'Name'
)}
</th>
<th data-cy="permissions-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.permissions',
'Permissions'
)}
</th>
<th></th>
</tr>
</thead>
<tbody>
{isLoadingGroup || isLoadingApps ? (
)}
<br />
<div>
<div className="table-responsive">
<table className="table table-vcenter">
<thead>
<tr>
<td className="col-auto">
<div className="row">
<div className="skeleton-line w-10 col mx-3"></div>
</div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
<th data-cy="name-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.name',
'Name'
)}
</th>
<th data-cy="permissions-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.permissions',
'Permissions'
)}
</th>
<th></th>
</tr>
) : (
appsInGroup.map((app) => (
<tr key={app.id}>
<td>{app.name}</td>
<td className="text-secondary">
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="radio"
onChange={() => {
this.updateAppGroupPermission(app, groupPermission.id, 'view');
}}
disabled={groupPermission.group === 'admin'}
checked={this.canAppGroupPermission(app, groupPermission.id, 'view')}
/>
<span className="form-check-label">
{this.props.t('globals.view', 'view')}
</span>
</label>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="radio"
onChange={() => {
this.updateAppGroupPermission(app, groupPermission.id, 'edit');
}}
disabled={groupPermission.group === 'admin'}
checked={this.canAppGroupPermission(app, groupPermission.id, 'edit')}
/>
<span className="form-check-label">
{this.props.t('globals.edit', 'Edit')}
</span>
</label>
</thead>
<tbody>
{isLoadingGroup || isLoadingApps ? (
<tr>
<td className="col-auto">
<div className="row">
<div className="skeleton-line w-10 col mx-3"></div>
</div>
{this.canAppGroupPermission(app, groupPermission.id, 'view') && (
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
</tr>
) : (
appsInGroup.map((app) => (
<tr key={app.id}>
<td>{app.name}</td>
<td className="text-secondary">
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="radio"
onChange={() => {
this.updateAppGroupPermission(app, groupPermission.id, 'view');
}}
disabled={groupPermission.group === 'admin'}
checked={this.canAppGroupPermission(app, groupPermission.id, 'view')}
/>
<span className="form-check-label">
{this.props.t('globals.view', 'view')}
</span>
</label>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="radio"
onChange={() => {
this.updateAppGroupPermission(app, groupPermission.id, 'edit');
}}
disabled={groupPermission.group === 'admin'}
checked={this.canAppGroupPermission(app, groupPermission.id, 'edit')}
/>
<span className="form-check-label">
{this.props.t('globals.edit', 'Edit')}
</span>
</label>
</div>
{this.canAppGroupPermission(app, groupPermission.id, 'view') && (
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateAppGroupPermission(
app,
groupPermission.id,
'readOnDashboard'
);
}}
disabled={groupPermission.group === 'admin'}
checked={this.canAppGroupPermission(
app,
groupPermission.id,
'readOnDashboard'
)}
/>
<span className="form-check-label">Hide from dashboard</span>
</label>
</div>
)}
</td>
<td>
{groupPermission.group !== 'admin' && (
<Link
to="#"
onClick={() => {
this.removeAppFromGroup(groupPermission.id, app.id);
}}
data-cy="delete-link"
>
{this.props.t('globals.delete', 'Delete')}
</Link>
)}
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
</div>
{/* Users Tab */}
<div className={`tab-pane ${currentTab === 'users' ? 'active show' : ''}`}>
{groupPermission?.group === 'admin' && (
<div className="row">
<div className="col-5">
<SelectSearch
className={`${this.props.darkMode ? 'select-search-dark' : 'select-search'}`}
options={userSelectOptions}
closeOnSelect={false}
multiple
search={true}
filterOptions={fuzzySearch}
value={selectedUserIds}
onChange={(value) => this.setSelectedUsers(value)}
printOptions="on-focus"
placeholder={this.props.t(
'header.organization.menus.manageGroups.permissionResources.addUsersToGroup',
'Select users to add to the group'
)}
/>
</div>
<div className="col-auto">
<div
className={`btn btn-primary w-100 ${isAddingUsers ? 'btn-loading' : ''} ${
selectedUserIds.length === 0 ? 'disabled' : ''
}`}
onClick={() => this.addSelectedUsersToGroup(groupPermission.id, selectedUserIds)}
>
{this.props.t('globals.add', 'Add')}
</div>
</div>
</div>
)}
<br />
<div>
<div className="table-responsive">
<table className="table table-vcenter">
<thead>
<tr>
<th data-cy="name-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.name',
'name'
)}
</th>
<th data-cy="email-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.email',
'email'
)}
</th>
<th></th>
</tr>
</thead>
<tbody>
{isLoadingGroup || isLoadingUsers ? (
<tr>
<td className="col-auto">
<div className="row">
<div className="skeleton-line w-10 col mx-3"></div>
</div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
</tr>
) : (
usersInGroup.map((user) => (
<tr key={user.id}>
<td>{`${user.first_name} ${user.last_name}`}</td>
<td>{user.email}</td>
<td className="text-muted">
{groupPermission.group !== 'all_users' && (
<Link
to="#"
onClick={() => {
this.removeUserFromGroup(groupPermission.id, user.id);
}}
>
{this.props.t('globals.delete', 'Delete')}
</Link>
)}
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
</div>
{/* Permissions Tab */}
<div className={`tab-pane ${currentTab === 'permissions' ? 'active show' : ''}`}>
<div>
<div className="table-responsive">
<table className="table table-vcenter">
<thead>
<tr>
<th data-cy="resource-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.resource',
'Resource'
)}
</th>
<th data-cy="permissions-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.permissions',
'Permissions'
)}
</th>
<th></th>
</tr>
</thead>
<tbody>
{isLoadingGroup ? (
<tr>
<td className="col-auto">
<div className="row">
<div className="skeleton-line w-10 col mx-3"></div>
</div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
</tr>
) : (
<>
<tr>
<td data-cy="resource-apps">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.apps',
'Apps'
)}
</td>
<td className="text-muted">
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateAppGroupPermission(
app,
groupPermission.id,
'readOnDashboard'
);
this.updateGroupPermission(groupPermission.id, {
app_create: !groupPermission.app_create,
});
}}
checked={groupPermission.app_create}
disabled={groupPermission.group === 'admin'}
checked={this.canAppGroupPermission(
app,
groupPermission.id,
'readOnDashboard'
)}
data-cy="app-create-checkbox"
/>
<span className="form-check-label">Hide from dashboard</span>
<span className="form-check-label" data-cy="app-create-label">
{this.props.t('globals.create', 'Create')}
</span>
</label>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateGroupPermission(groupPermission.id, {
app_delete: !groupPermission.app_delete,
});
}}
checked={groupPermission.app_delete}
disabled={groupPermission.group === 'admin'}
data-cy="app-delete-checkbox"
/>
<span className="form-check-label" data-cy="app-delete-label">
{this.props.t('globals.delete', 'Delete')}
</span>
</label>
</div>
)}
</td>
<td>
{groupPermission.group !== 'admin' && (
<Link
to="#"
onClick={() => {
this.removeAppFromGroup(groupPermission.id, app.id);
}}
data-cy="delete-link"
>
{this.props.t('globals.delete', 'Delete')}
</Link>
)}
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
</div>
</td>
<td></td>
</tr>
{/* Users Tab */}
<div className={`tab-pane ${currentTab === 'users' ? 'active show' : ''}`}>
{groupPermission?.group === 'admin' && (
<div className="row">
<div className="col-5">
<SelectSearch
className={`${this.props.darkMode ? 'select-search-dark' : 'select-search'}`}
options={userSelectOptions}
closeOnSelect={false}
multiple
search={true}
filterOptions={fuzzySearch}
value={selectedUserIds}
onChange={(value) => this.setSelectedUsers(value)}
printOptions="on-focus"
placeholder={this.props.t(
'header.organization.menus.manageGroups.permissionResources.addUsersToGroup',
'Select users to add to the group'
)}
/>
<tr>
<td data-cy="resource-folders">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.folder',
'Folder'
)}
</td>
<td className="text-muted">
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateGroupPermission(groupPermission.id, {
folder_create: !folder_permission,
folder_delete: !folder_permission,
folder_update: !folder_permission,
});
}}
checked={folder_permission}
disabled={groupPermission.group === 'admin'}
data-cy="folder-create-checkbox"
/>
<span className="form-check-label" data-cy="folder-create-label">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.createUpdateDelete',
'Create/Update/Delete'
)}
</span>
</label>
</div>
</td>
<td></td>
</tr>
<tr>
<td>{this.props.t('globals.environmentVar', 'Environment variables')}</td>
<td className="text-muted">
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateGroupPermission(groupPermission.id, {
org_environment_variable_create: !orgEnvironmentPermission,
org_environment_variable_update: !orgEnvironmentPermission,
org_environment_variable_delete: !orgEnvironmentPermission,
});
}}
checked={orgEnvironmentPermission}
disabled={groupPermission.group === 'admin'}
/>
<span className="form-check-label">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.createUpdateDelete',
'Create/Update/Delete'
)}
</span>
</label>
</div>
</td>
<td></td>
</tr>
</>
)}
</tbody>
</table>
</div>
<div className="col-auto">
<div
className={`btn btn-primary w-100 ${isAddingUsers ? 'btn-loading' : ''} ${
selectedUserIds.length === 0 ? 'disabled' : ''
}`}
onClick={() => this.addSelectedUsersToGroup(groupPermission.id, selectedUserIds)}
>
{this.props.t('globals.add', 'Add')}
</div>
</div>
</div>
)}
<br />
<div>
<div className="table-responsive">
<table className="table table-vcenter">
<thead>
<tr>
<th data-cy="name-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.name',
'name'
)}
</th>
<th data-cy="email-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.email',
'email'
)}
</th>
<th></th>
</tr>
</thead>
<tbody>
{isLoadingGroup || isLoadingUsers ? (
<tr>
<td className="col-auto">
<div className="row">
<div className="skeleton-line w-10 col mx-3"></div>
</div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
</tr>
) : (
usersInGroup.map((user) => (
<tr key={user.id}>
<td>{`${user.first_name} ${user.last_name}`}</td>
<td>{user.email}</td>
<td className="text-muted">
{groupPermission.group !== 'all_users' && (
<Link
to="#"
onClick={() => {
this.removeUserFromGroup(groupPermission.id, user.id);
}}
>
{this.props.t('globals.delete', 'Delete')}
</Link>
)}
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
</div>
{/* Permissions Tab */}
<div className={`tab-pane ${currentTab === 'permissions' ? 'active show' : ''}`}>
<div>
<div className="table-responsive">
<table className="table table-vcenter">
<thead>
<tr>
<th data-cy="resource-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.resource',
'Resource'
)}
</th>
<th data-cy="permissions-header">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.permissions',
'Permissions'
)}
</th>
<th></th>
</tr>
</thead>
<tbody>
{isLoadingGroup ? (
<tr>
<td className="col-auto">
<div className="row">
<div className="skeleton-line w-10 col mx-3"></div>
</div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
<td className="col-auto">
<div className="skeleton-line w-10"></div>
</td>
</tr>
) : (
<>
<tr>
<td data-cy="resource-apps">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.apps',
'Apps'
)}
</td>
<td className="text-muted">
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateGroupPermission(groupPermission.id, {
app_create: !groupPermission.app_create,
});
}}
checked={groupPermission.app_create}
disabled={groupPermission.group === 'admin'}
data-cy="app-create-checkbox"
/>
<span className="form-check-label" data-cy="app-create-label">
{this.props.t('globals.create', 'Create')}
</span>
</label>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateGroupPermission(groupPermission.id, {
app_delete: !groupPermission.app_delete,
});
}}
checked={groupPermission.app_delete}
disabled={groupPermission.group === 'admin'}
data-cy="app-delete-checkbox"
/>
<span className="form-check-label" data-cy="app-delete-label">
{this.props.t('globals.delete', 'Delete')}
</span>
</label>
</div>
</td>
<td></td>
</tr>
<tr>
<td data-cy="resource-folders">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.folder',
'Folder'
)}
</td>
<td className="text-muted">
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateGroupPermission(groupPermission.id, {
folder_create: !folder_permission,
folder_delete: !folder_permission,
folder_update: !folder_permission,
});
}}
checked={folder_permission}
disabled={groupPermission.group === 'admin'}
data-cy="folder-create-checkbox"
/>
<span className="form-check-label" data-cy="folder-create-label">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.createUpdateDelete',
'Create/Update/Delete'
)}
</span>
</label>
</div>
</td>
<td></td>
</tr>
<tr>
<td>{this.props.t('globals.environmentVar', 'Environment variables')}</td>
<td className="text-muted">
<div>
<label className="form-check form-check-inline">
<input
className="form-check-input"
type="checkbox"
onChange={() => {
this.updateGroupPermission(groupPermission.id, {
org_environment_variable_create: !orgEnvironmentPermission,
org_environment_variable_update: !orgEnvironmentPermission,
org_environment_variable_delete: !orgEnvironmentPermission,
});
}}
checked={orgEnvironmentPermission}
disabled={groupPermission.group === 'admin'}
/>
<span className="form-check-label">
{this.props.t(
'header.organization.menus.manageGroups.permissionResources.createUpdateDelete',
'Create/Update/Delete'
)}
</span>
</label>
</div>
</td>
<td></td>
</tr>
</>
)}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
</div>
</div>