change(ui) - preferences - edit button
This commit is contained in:
parent
050ce038cc
commit
ca6a6db63f
7 changed files with 355 additions and 374 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import { Icon } from 'UI';
|
||||
import { Button } from 'UI';
|
||||
import styles from './listItem.module.css';
|
||||
|
||||
const ListItem = ({ field, onEdit, disabled }) => {
|
||||
|
|
@ -17,9 +17,7 @@ const ListItem = ({ field, onEdit, disabled }) => {
|
|||
>
|
||||
<span>{field.key}</span>
|
||||
<div className="invisible group-hover:visible" data-hidden={field.index === 0}>
|
||||
<div className={styles.button}>
|
||||
<Icon name="edit" color="teal" size="18" />
|
||||
</div>
|
||||
<Button variant="text-primary" icon="pencil" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,156 +1,154 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import cn from 'classnames'
|
||||
import { Loader, IconButton, Popup, NoContent, SlideModal } from 'UI'
|
||||
import { connect } from 'react-redux'
|
||||
import stl from './roles.module.css'
|
||||
import RoleForm from './components/RoleForm'
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import cn from 'classnames';
|
||||
import { Loader, IconButton, Popup, NoContent, SlideModal } from 'UI';
|
||||
import { connect } from 'react-redux';
|
||||
import stl from './roles.module.css';
|
||||
import RoleForm from './components/RoleForm';
|
||||
import { init, edit, fetchList, remove as deleteRole, resetErrors } from 'Duck/roles';
|
||||
import RoleItem from './components/RoleItem'
|
||||
import RoleItem from './components/RoleItem';
|
||||
import { confirm } from 'UI';
|
||||
import { toast } from 'react-toastify';
|
||||
import withPageTitle from 'HOCs/withPageTitle';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
|
||||
interface Props {
|
||||
loading: boolean
|
||||
init: (role?: any) => void,
|
||||
edit: (role: any) => void,
|
||||
instance: any,
|
||||
roles: any[],
|
||||
deleteRole: (id: any) => Promise<void>,
|
||||
fetchList: () => Promise<void>,
|
||||
account: any,
|
||||
permissionsMap: any,
|
||||
removeErrors: any,
|
||||
resetErrors: () => void,
|
||||
projectsMap: any,
|
||||
loading: boolean;
|
||||
init: (role?: any) => void;
|
||||
edit: (role: any) => void;
|
||||
instance: any;
|
||||
roles: any[];
|
||||
deleteRole: (id: any) => Promise<void>;
|
||||
fetchList: () => Promise<void>;
|
||||
account: any;
|
||||
permissionsMap: any;
|
||||
removeErrors: any;
|
||||
resetErrors: () => void;
|
||||
projectsMap: any;
|
||||
}
|
||||
|
||||
function Roles(props: Props) {
|
||||
const { loading, instance, roles, init, edit, deleteRole, account, permissionsMap, projectsMap, removeErrors } = props
|
||||
const [showModal, setShowmModal] = useState(false)
|
||||
const isAdmin = account.admin || account.superAdmin;
|
||||
const { loading, instance, roles, init, edit, deleteRole, account, permissionsMap, projectsMap, removeErrors } = props;
|
||||
// const [showModal, setShowmModal] = useState(false);
|
||||
const { showModal, hideModal } = useModal();
|
||||
const isAdmin = account.admin || account.superAdmin;
|
||||
|
||||
useEffect(() => {
|
||||
props.fetchList()
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
props.fetchList();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (removeErrors && removeErrors.size > 0) {
|
||||
removeErrors.forEach(e => {
|
||||
toast.error(e)
|
||||
})
|
||||
}
|
||||
return () => {
|
||||
props.resetErrors()
|
||||
}
|
||||
}, [removeErrors])
|
||||
useEffect(() => {
|
||||
if (removeErrors && removeErrors.size > 0) {
|
||||
removeErrors.forEach((e) => {
|
||||
toast.error(e);
|
||||
});
|
||||
}
|
||||
return () => {
|
||||
props.resetErrors();
|
||||
};
|
||||
}, [removeErrors]);
|
||||
|
||||
const closeModal = (showToastMessage) => {
|
||||
if (showToastMessage) {
|
||||
toast.success(showToastMessage)
|
||||
props.fetchList()
|
||||
}
|
||||
setShowmModal(false)
|
||||
setTimeout(() => {
|
||||
init()
|
||||
}, 100)
|
||||
}
|
||||
const closeModal = (showToastMessage) => {
|
||||
if (showToastMessage) {
|
||||
toast.success(showToastMessage);
|
||||
props.fetchList();
|
||||
}
|
||||
setShowmModal(false);
|
||||
setTimeout(() => {
|
||||
init();
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const editHandler = role => {
|
||||
init(role)
|
||||
setShowmModal(true)
|
||||
}
|
||||
const editHandler = (role: any) => {
|
||||
init(role);
|
||||
showModal(<RoleForm closeModal={hideModal} permissionsMap={permissionsMap} deleteHandler={deleteHandler} />, { right: true });
|
||||
// setShowmModal(true);
|
||||
};
|
||||
|
||||
const deleteHandler = async (role) => {
|
||||
if (await confirm({
|
||||
header: 'Roles',
|
||||
confirmation: `Are you sure you want to remove this role?`
|
||||
})) {
|
||||
deleteRole(role.roleId)
|
||||
}
|
||||
}
|
||||
const deleteHandler = async (role: any) => {
|
||||
if (
|
||||
await confirm({
|
||||
header: 'Roles',
|
||||
confirmation: `Are you sure you want to remove this role?`,
|
||||
})
|
||||
) {
|
||||
deleteRole(role.roleId);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Loader loading={ loading }>
|
||||
<SlideModal
|
||||
title={ instance.exists() ? "Edit Role" : "Create Role" }
|
||||
size="small"
|
||||
isDisplayed={showModal }
|
||||
content={ showModal && <RoleForm closeModal={closeModal} permissionsMap={permissionsMap} deleteHandler={deleteHandler} /> }
|
||||
onClose={ closeModal }
|
||||
/>
|
||||
<div className={ stl.wrapper }>
|
||||
<div className={ cn(stl.tabHeader, 'flex items-center') }>
|
||||
<div className="flex items-center mr-auto">
|
||||
<h3 className={ cn(stl.tabTitle, "text-2xl") }>Roles and Access</h3>
|
||||
<Popup
|
||||
content="You don’t have the permissions to perform this action."
|
||||
disabled={ isAdmin }
|
||||
>
|
||||
<div>
|
||||
<IconButton
|
||||
id="add-button"
|
||||
circle
|
||||
icon="plus"
|
||||
outline
|
||||
disabled={ !isAdmin }
|
||||
onClick={ () => setShowmModal(true) }
|
||||
/>
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Loader loading={loading}>
|
||||
{/* <SlideModal
|
||||
title={instance.exists() ? 'Edit Role' : 'Create Role'}
|
||||
size="small"
|
||||
isDisplayed={showModal}
|
||||
content={showModal && <RoleForm closeModal={closeModal} permissionsMap={permissionsMap} deleteHandler={deleteHandler} />}
|
||||
onClose={closeModal}
|
||||
/> */}
|
||||
<div className={stl.wrapper}>
|
||||
<div className={cn(stl.tabHeader, 'flex items-center')}>
|
||||
<div className="flex items-center mr-auto">
|
||||
<h3 className={cn(stl.tabTitle, 'text-2xl')}>Roles and Access</h3>
|
||||
<Popup content="You don’t have the permissions to perform this action." disabled={isAdmin}>
|
||||
<div>
|
||||
<IconButton id="add-button" circle icon="plus" outline disabled={!isAdmin} onClick={() => setShowmModal(true)} />
|
||||
</div>
|
||||
</Popup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<NoContent title="No roles are available." size="small" show={false} icon>
|
||||
<div className={''}>
|
||||
<div className={cn('flex items-start py-3 border-b px-3 pr-20 font-medium')}>
|
||||
<div className="" style={{ width: '20%' }}>
|
||||
Title
|
||||
</div>
|
||||
<div className="" style={{ width: '30%' }}>
|
||||
Project Access
|
||||
</div>
|
||||
<div className="" style={{ width: '50%' }}>
|
||||
Feature Access
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
{roles.map((role) => (
|
||||
<RoleItem
|
||||
role={role}
|
||||
isAdmin={isAdmin}
|
||||
permissions={permissionsMap}
|
||||
projects={projectsMap}
|
||||
editHandler={editHandler}
|
||||
deleteHandler={deleteHandler}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</NoContent>
|
||||
</div>
|
||||
</Popup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<NoContent
|
||||
title="No roles are available."
|
||||
size="small"
|
||||
show={ false }
|
||||
icon
|
||||
>
|
||||
<div className={''}>
|
||||
<div className={cn('flex items-start py-3 border-b px-3 pr-20 font-medium')}>
|
||||
<div className="" style={{ width: '20%'}}>Title</div>
|
||||
<div className="" style={{ width: '30%'}}>Project Access</div>
|
||||
<div className="" style={{ width: '50%'}}>Feature Access</div>
|
||||
<div></div>
|
||||
</div>
|
||||
{roles.map(role => (
|
||||
<RoleItem
|
||||
role={role}
|
||||
isAdmin={isAdmin}
|
||||
permissions={permissionsMap}
|
||||
projects={projectsMap}
|
||||
editHandler={editHandler}
|
||||
deleteHandler={deleteHandler}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</NoContent>
|
||||
</div>
|
||||
</Loader>
|
||||
</React.Fragment>
|
||||
)
|
||||
</Loader>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(state => {
|
||||
const permissions = state.getIn(['roles', 'permissions'])
|
||||
const permissionsMap = {}
|
||||
permissions.forEach(p => {
|
||||
permissionsMap[p.value] = p.text
|
||||
});
|
||||
const projects = state.getIn([ 'site', 'list' ])
|
||||
return {
|
||||
instance: state.getIn(['roles', 'instance']) || null,
|
||||
permissionsMap: permissionsMap,
|
||||
roles: state.getIn(['roles', 'list']),
|
||||
removeErrors: state.getIn(['roles', 'removeRequest', 'errors']),
|
||||
loading: state.getIn(['roles', 'fetchRequest', 'loading']),
|
||||
account: state.getIn([ 'user', 'account' ]),
|
||||
projectsMap: projects.reduce((acc, p) => {
|
||||
acc[ p.get('id') ] = p.get('name')
|
||||
return acc
|
||||
}
|
||||
, {}),
|
||||
}
|
||||
}, { init, edit, fetchList, deleteRole, resetErrors })(withPageTitle('Roles & Access - OpenReplay Preferences')(Roles))
|
||||
export default connect(
|
||||
(state: any) => {
|
||||
const permissions = state.getIn(['roles', 'permissions']);
|
||||
const permissionsMap = {};
|
||||
permissions.forEach((p: any) => {
|
||||
permissionsMap[p.value] = p.text;
|
||||
});
|
||||
const projects = state.getIn(['site', 'list']);
|
||||
return {
|
||||
instance: state.getIn(['roles', 'instance']) || null,
|
||||
permissionsMap: permissionsMap,
|
||||
roles: state.getIn(['roles', 'list']),
|
||||
removeErrors: state.getIn(['roles', 'removeRequest', 'errors']),
|
||||
loading: state.getIn(['roles', 'fetchRequest', 'loading']),
|
||||
account: state.getIn(['user', 'account']),
|
||||
projectsMap: projects.reduce((acc: any, p: any) => {
|
||||
acc[p.get('id')] = p.get('name');
|
||||
return acc;
|
||||
}, {}),
|
||||
};
|
||||
},
|
||||
{ init, edit, fetchList, deleteRole, resetErrors }
|
||||
)(withPageTitle('Roles & Access - OpenReplay Preferences')(Roles));
|
||||
|
|
|
|||
|
|
@ -1,203 +1,195 @@
|
|||
import React, { useRef, useEffect } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import stl from './roleForm.module.css'
|
||||
import { save, edit } from 'Duck/roles'
|
||||
import { Form, Input, Button, Checkbox, Icon } from 'UI'
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import stl from './roleForm.module.css';
|
||||
import { save, edit } from 'Duck/roles';
|
||||
import { Form, Input, Button, Checkbox, Icon } from 'UI';
|
||||
import Select from 'Shared/Select';
|
||||
|
||||
interface Permission {
|
||||
name: string,
|
||||
value: string
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
role: any,
|
||||
edit: (role: any) => void,
|
||||
save: (role: any) => Promise<void>,
|
||||
closeModal: (toastMessage?: string) => void,
|
||||
saving: boolean,
|
||||
permissions: Array<Permission>[]
|
||||
projectOptions: Array<any>[],
|
||||
permissionsMap: any,
|
||||
projectsMap: any,
|
||||
deleteHandler: (id: any) => Promise<void>,
|
||||
role: any;
|
||||
edit: (role: any) => void;
|
||||
save: (role: any) => Promise<void>;
|
||||
closeModal: (toastMessage?: string) => void;
|
||||
saving: boolean;
|
||||
permissions: Array<Permission>[];
|
||||
projectOptions: Array<any>[];
|
||||
permissionsMap: any;
|
||||
projectsMap: any;
|
||||
deleteHandler: (id: any) => Promise<void>;
|
||||
}
|
||||
|
||||
const RoleForm = (props: Props) => {
|
||||
const { role, edit, save, closeModal, saving, permissions, projectOptions, permissionsMap, projectsMap } = props
|
||||
let focusElement = useRef<any>(null)
|
||||
const _save = () => {
|
||||
save(role).then(() => {
|
||||
closeModal(role.exists() ? "Role updated" : "Role created");
|
||||
})
|
||||
}
|
||||
const { role, edit, save, closeModal, saving, permissions, projectOptions, permissionsMap, projectsMap } = props;
|
||||
let focusElement = useRef<any>(null);
|
||||
const _save = () => {
|
||||
save(role).then(() => {
|
||||
closeModal(role.exists() ? 'Role updated' : 'Role created');
|
||||
});
|
||||
};
|
||||
|
||||
const write = ({ target: { value, name } }) => edit({ [ name ]: value })
|
||||
const write = ({ target: { value, name } }) => edit({ [name]: value });
|
||||
|
||||
const onChangePermissions = (e) => {
|
||||
const { permissions } = role
|
||||
const index = permissions.indexOf(e)
|
||||
const _perms = permissions.contains(e) ? permissions.remove(index) : permissions.push(e)
|
||||
edit({ permissions: _perms })
|
||||
}
|
||||
const onChangePermissions = (e) => {
|
||||
const { permissions } = role;
|
||||
const index = permissions.indexOf(e);
|
||||
const _perms = permissions.contains(e) ? permissions.remove(index) : permissions.push(e);
|
||||
edit({ permissions: _perms });
|
||||
};
|
||||
|
||||
const onChangeProjects = (e) => {
|
||||
const { projects } = role
|
||||
const index = projects.indexOf(e)
|
||||
const _projects = index === -1 ? projects.push(e) : projects.remove(index)
|
||||
edit({ projects: _projects })
|
||||
}
|
||||
const onChangeProjects = (e) => {
|
||||
const { projects } = role;
|
||||
const index = projects.indexOf(e);
|
||||
const _projects = index === -1 ? projects.push(e) : projects.remove(index);
|
||||
edit({ projects: _projects });
|
||||
};
|
||||
|
||||
const writeOption = ({ name, value }: any) => {
|
||||
if (name === 'permissions') {
|
||||
onChangePermissions(value)
|
||||
} else if (name === 'projects') {
|
||||
onChangeProjects(value)
|
||||
}
|
||||
}
|
||||
const writeOption = ({ name, value }: any) => {
|
||||
if (name === 'permissions') {
|
||||
onChangePermissions(value);
|
||||
} else if (name === 'projects') {
|
||||
onChangeProjects(value);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleAllProjects = () => {
|
||||
const { allProjects } = role
|
||||
edit({ allProjects: !allProjects })
|
||||
}
|
||||
const toggleAllProjects = () => {
|
||||
const { allProjects } = role;
|
||||
edit({ allProjects: !allProjects });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
focusElement && focusElement.current && focusElement.current.focus()
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
focusElement && focusElement.current && focusElement.current.focus();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={ stl.form }>
|
||||
<Form onSubmit={ _save } >
|
||||
<Form.Field>
|
||||
<label>{ 'Title' }</label>
|
||||
<Input
|
||||
ref={ focusElement }
|
||||
name="name"
|
||||
value={ role.name }
|
||||
onChange={ write }
|
||||
className={ stl.input }
|
||||
id="name-field"
|
||||
placeholder="Ex. Admin"
|
||||
/>
|
||||
</Form.Field>
|
||||
return (
|
||||
<div className="bg-white h-screen overflow-y-auto" style={{ width: '350px' }}>
|
||||
<h3 className="p-5 text-2xl">{role.exists() ? 'Edit Role' : 'Create Role'}</h3>
|
||||
<div className="px-5">
|
||||
<Form onSubmit={_save}>
|
||||
<Form.Field>
|
||||
<label>{'Title'}</label>
|
||||
<Input
|
||||
ref={focusElement}
|
||||
name="name"
|
||||
value={role.name}
|
||||
onChange={write}
|
||||
className={stl.input}
|
||||
id="name-field"
|
||||
placeholder="Ex. Admin"
|
||||
/>
|
||||
</Form.Field>
|
||||
|
||||
<Form.Field>
|
||||
<label>{ 'Project Access' }</label>
|
||||
<Form.Field>
|
||||
<label>{'Project Access'}</label>
|
||||
|
||||
<div className="flex my-3">
|
||||
<Checkbox
|
||||
name="allProjects"
|
||||
className="font-medium"
|
||||
type="checkbox"
|
||||
checked={ role.allProjects }
|
||||
onClick={toggleAllProjects}
|
||||
label={''}
|
||||
/>
|
||||
<div className="cursor-pointer" onClick={toggleAllProjects}>
|
||||
<div>All Projects</div>
|
||||
<span className="text-xs text-gray-600">
|
||||
(Uncheck to select specific projects)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{ !role.allProjects && (
|
||||
<>
|
||||
<Select
|
||||
isSearchable
|
||||
name="projects"
|
||||
options={ projectOptions }
|
||||
onChange={ ({ value }: any) => writeOption({ name: 'projects', value: value.value }) }
|
||||
value={null}
|
||||
/>
|
||||
{ role.projects.size > 0 && (
|
||||
<div className="flex flex-row items-start flex-wrap mt-4">
|
||||
{ role.projects.map(p => (
|
||||
OptionLabel(projectsMap, p, onChangeProjects)
|
||||
)) }
|
||||
<div className="flex my-3">
|
||||
<Checkbox
|
||||
name="allProjects"
|
||||
className="font-medium mr-3"
|
||||
type="checkbox"
|
||||
checked={role.allProjects}
|
||||
onClick={toggleAllProjects}
|
||||
label={''}
|
||||
/>
|
||||
<div className="cursor-pointer leading-none select-none" onClick={toggleAllProjects}>
|
||||
<div>All Projects</div>
|
||||
<span className="text-xs text-gray-600">(Uncheck to select specific projects)</span>
|
||||
</div>
|
||||
</div>
|
||||
{!role.allProjects && (
|
||||
<>
|
||||
<Select
|
||||
isSearchable
|
||||
name="projects"
|
||||
options={projectOptions}
|
||||
onChange={({ value }: any) => writeOption({ name: 'projects', value: value.value })}
|
||||
value={null}
|
||||
/>
|
||||
{role.projects.size > 0 && (
|
||||
<div className="flex flex-row items-start flex-wrap mt-4">
|
||||
{role.projects.map((p) => OptionLabel(projectsMap, p, onChangeProjects))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Form.Field>
|
||||
|
||||
<Form.Field>
|
||||
<label>{'Capability Access'}</label>
|
||||
<Select
|
||||
isSearchable
|
||||
name="permissions"
|
||||
options={permissions}
|
||||
onChange={({ value }: any) => writeOption({ name: 'permissions', value: value.value })}
|
||||
value={null}
|
||||
/>
|
||||
{role.permissions.size > 0 && (
|
||||
<div className="flex flex-row items-start flex-wrap mt-4">
|
||||
{role.permissions.map((p) => OptionLabel(permissionsMap, p, onChangePermissions))}
|
||||
</div>
|
||||
)}
|
||||
</Form.Field>
|
||||
</Form>
|
||||
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center mr-auto">
|
||||
<Button onClick={_save} disabled={!role.validate()} loading={saving} variant="primary" className="float-left mr-2">
|
||||
{role.exists() ? 'Update' : 'Add'}
|
||||
</Button>
|
||||
{role.exists() && <Button onClick={closeModal}>{'Cancel'}</Button>}
|
||||
</div>
|
||||
{role.exists() && (
|
||||
<Button variant="text" onClick={() => props.deleteHandler(role)}>
|
||||
<Icon name="trash" size="18" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Form.Field>
|
||||
|
||||
<Form.Field>
|
||||
<label>{ 'Capability Access' }</label>
|
||||
<Select
|
||||
isSearchable
|
||||
name="permissions"
|
||||
options={ permissions }
|
||||
onChange={ ({ value }: any) => writeOption({ name: 'permissions', value: value.value }) }
|
||||
value={null}
|
||||
/>
|
||||
{ role.permissions.size > 0 && (
|
||||
<div className="flex flex-row items-start flex-wrap mt-4">
|
||||
{ role.permissions.map(p => (
|
||||
OptionLabel(permissionsMap, p, onChangePermissions)
|
||||
)) }
|
||||
</div>
|
||||
)}
|
||||
</Form.Field>
|
||||
</Form>
|
||||
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center mr-auto">
|
||||
<Button
|
||||
onClick={ _save }
|
||||
disabled={ !role.validate() }
|
||||
loading={ saving }
|
||||
variant="primary"
|
||||
className="float-left mr-2"
|
||||
>
|
||||
{ role.exists() ? 'Update' : 'Add' }
|
||||
</Button>
|
||||
{ role.exists() && (
|
||||
<Button
|
||||
onClick={ closeModal }
|
||||
>
|
||||
{ 'Cancel' }
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{ role.exists() && (
|
||||
<Button
|
||||
variant="text"
|
||||
onClick={ () => props.deleteHandler(role) }
|
||||
>
|
||||
<Icon name="trash" size="18"/>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default connect((state: any) => {
|
||||
const role = state.getIn(['roles', 'instance'])
|
||||
const projects = state.getIn([ 'site', 'list' ])
|
||||
return {
|
||||
role,
|
||||
projectOptions: projects.map((p: any) => ({
|
||||
key: p.get('id'),
|
||||
value: p.get('id'),
|
||||
label: p.get('name'),
|
||||
// isDisabled: role.projects.includes(p.get('id')),
|
||||
})).filter(({ value }: any) => !role.projects.includes(value)).toJS(),
|
||||
permissions: state.getIn(['roles', 'permissions']).filter(({ value }: any) => !role.permissions.includes(value))
|
||||
.map(({ text, value }: any) => ({ label: text, value })).toJS(),
|
||||
saving: state.getIn([ 'roles', 'saveRequest', 'loading' ]),
|
||||
projectsMap: projects.reduce((acc: any, p: any) => {
|
||||
acc[ p.get('id') ] = p.get('name')
|
||||
return acc
|
||||
}
|
||||
, {}),
|
||||
}
|
||||
}, { edit, save })(RoleForm);
|
||||
export default connect(
|
||||
(state: any) => {
|
||||
const role = state.getIn(['roles', 'instance']);
|
||||
const projects = state.getIn(['site', 'list']);
|
||||
return {
|
||||
role,
|
||||
projectOptions: projects
|
||||
.map((p: any) => ({
|
||||
key: p.get('id'),
|
||||
value: p.get('id'),
|
||||
label: p.get('name'),
|
||||
// isDisabled: role.projects.includes(p.get('id')),
|
||||
}))
|
||||
.filter(({ value }: any) => !role.projects.includes(value))
|
||||
.toJS(),
|
||||
permissions: state
|
||||
.getIn(['roles', 'permissions'])
|
||||
.filter(({ value }: any) => !role.permissions.includes(value))
|
||||
.map(({ text, value }: any) => ({ label: text, value }))
|
||||
.toJS(),
|
||||
saving: state.getIn(['roles', 'saveRequest', 'loading']),
|
||||
projectsMap: projects.reduce((acc: any, p: any) => {
|
||||
acc[p.get('id')] = p.get('name');
|
||||
return acc;
|
||||
}, {}),
|
||||
};
|
||||
},
|
||||
{ edit, save }
|
||||
)(RoleForm);
|
||||
|
||||
function OptionLabel(nameMap: any, p: any, onChangeOption: (e: any) => void) {
|
||||
return <div className="px-2 py-1 rounded bg-gray-lightest mr-2 mb-2 border flex items-center justify-between">
|
||||
<div>{nameMap[p]}</div>
|
||||
<div className="cursor-pointer ml-2" onClick={() => onChangeOption(p)}>
|
||||
<Icon name="close" size="12" />
|
||||
</div>
|
||||
</div>
|
||||
return (
|
||||
<div className="px-2 py-1 rounded bg-gray-lightest mr-2 mb-2 border flex items-center justify-between">
|
||||
<div>{nameMap[p]}</div>
|
||||
<div className="cursor-pointer ml-2" onClick={() => onChangeOption(p)}>
|
||||
<Icon name="close" size="12" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,64 +1,58 @@
|
|||
import React from 'react'
|
||||
import { Icon, Link } from 'UI'
|
||||
import stl from './roleItem.module.css'
|
||||
import cn from 'classnames'
|
||||
import React from 'react';
|
||||
import { Icon, Link, Button } from 'UI';
|
||||
import stl from './roleItem.module.css';
|
||||
import cn from 'classnames';
|
||||
import { CLIENT_TABS, client as clientRoute } from 'App/routes';
|
||||
|
||||
|
||||
function PermisionLabel({ label }: any) {
|
||||
return (
|
||||
<div className={cn(stl.label, 'mb-2')}>{ label }</div>
|
||||
);
|
||||
return <div className={cn(stl.label, 'mb-2')}>{label}</div>;
|
||||
}
|
||||
|
||||
function PermisionLabelLinked({ label, route }: any) {
|
||||
return (
|
||||
<Link to={route}><div className={cn(stl.label, 'mb-2 bg-active-blue color-teal')}>{ label }</div></Link>
|
||||
);
|
||||
return (
|
||||
<Link to={route}>
|
||||
<div className={cn(stl.label, 'mb-2 bg-active-blue color-teal')}>{label}</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
interface Props {
|
||||
role: any,
|
||||
deleteHandler?: (role: any) => void,
|
||||
editHandler?: (role: any) => void,
|
||||
permissions: any,
|
||||
isAdmin: boolean,
|
||||
projects: any,
|
||||
role: any;
|
||||
deleteHandler?: (role: any) => void;
|
||||
editHandler?: (role: any) => void;
|
||||
permissions: any;
|
||||
isAdmin: boolean;
|
||||
projects: any;
|
||||
}
|
||||
function RoleItem({ role, deleteHandler, editHandler, isAdmin, permissions, projects }: Props) {
|
||||
return (
|
||||
<div className={cn('flex items-start relative py-4 hover border-b last:border-none px-3 pr-20 group')}>
|
||||
<div className="flex" style={{ width: '20%'}}>
|
||||
<Icon name="user-alt" size="16" marginRight="10" />
|
||||
{ role.name }
|
||||
</div>
|
||||
<div className="flex items-start flex-wrap" style={{ width: '30%'}}>
|
||||
{role.allProjects ? (
|
||||
<PermisionLabelLinked label="All projects" route={clientRoute(CLIENT_TABS.SITES)}/>
|
||||
) : (
|
||||
role.projects.map(p => (
|
||||
<PermisionLabel label={projects[p]} />
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-start flex-wrap" style={{ width: '50%'}}>
|
||||
<div className="flex items-center flex-wrap">
|
||||
{role.permissions.map((permission: any) => (
|
||||
<PermisionLabel label={permissions[permission]} key={permission.id} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className={ cn(stl.actions, 'absolute right-0 top-0 bottom-0 mr-8 invisible group-hover:visible') }>
|
||||
{isAdmin && !!editHandler &&
|
||||
<div className={ cn(stl.button, {[stl.disabled] : role.protected }) } onClick={ () => editHandler(role) }>
|
||||
<Icon name="edit" size="16" color="teal"/>
|
||||
return (
|
||||
<div className={cn('flex items-start relative py-4 hover border-b last:border-none px-3 pr-20 group')}>
|
||||
<div className="flex" style={{ width: '20%' }}>
|
||||
<Icon name="user-alt" size="16" marginRight="10" />
|
||||
{role.name}
|
||||
</div>
|
||||
<div className="flex items-start flex-wrap" style={{ width: '30%' }}>
|
||||
{role.allProjects ? (
|
||||
<PermisionLabelLinked label="All projects" route={clientRoute(CLIENT_TABS.SITES)} />
|
||||
) : (
|
||||
role.projects.map((p) => <PermisionLabel label={projects[p]} />)
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-start flex-wrap" style={{ width: '50%' }}>
|
||||
<div className="flex items-center flex-wrap">
|
||||
{role.permissions.map((permission: any) => (
|
||||
<PermisionLabel label={permissions[permission]} key={permission.id} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className={cn(stl.actions, 'absolute right-0 top-0 bottom-0 mr-8 invisible group-hover:visible')}>
|
||||
{isAdmin && !!editHandler && (
|
||||
<Button variant="text-primary" icon="pencil" disabled={role.protected} onClick={() => editHandler(role)} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default RoleItem;
|
||||
export default RoleItem;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ function InstallButton(props: Props) {
|
|||
);
|
||||
};
|
||||
return (
|
||||
<Button size="small" variant="primary" onClick={onClick}>
|
||||
<Button size="small" variant="text-primary" onClick={onClick}>
|
||||
{'Installation Steps'}
|
||||
</Button>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -130,5 +130,5 @@ function EditButton({ isAdmin, onClick }) {
|
|||
onClick();
|
||||
showModal(<NewSiteForm onClose={hideModal} />);
|
||||
};
|
||||
return <Button icon="edit" variant="text" disabled={!isAdmin} onClick={_onClick} />;
|
||||
return <Button icon="edit" variant="text-primary" disabled={!isAdmin} onClick={_onClick} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Icon } from 'UI';
|
||||
import styles from './listItem.module.css';
|
||||
import { Button } from 'UI';
|
||||
|
||||
const ListItem = ({ webhook, onEdit, onDelete }) => {
|
||||
return (
|
||||
|
|
@ -10,9 +11,7 @@ const ListItem = ({ webhook, onEdit, onDelete }) => {
|
|||
<div className={styles.endpoint}>{webhook.endpoint}</div>
|
||||
</div>
|
||||
<div className="invisible group-hover:visible">
|
||||
<div className={styles.button}>
|
||||
<Icon name="edit" color="teal" size="16" />
|
||||
</div>
|
||||
<Button variant="text-primary" icon="pencil" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue