Add more functionality to TransferBox
This commit is contained in:
parent
fe13b651ed
commit
892134d63b
3 changed files with 213 additions and 89 deletions
|
|
@ -5,6 +5,70 @@ import DoNotDisturbIcon from '@mui/icons-material/DoNotDisturb';
|
||||||
import KeyboardArrowLeftIcon from '@mui/icons-material/KeyboardArrowLeft';
|
import KeyboardArrowLeftIcon from '@mui/icons-material/KeyboardArrowLeft';
|
||||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||||
|
|
||||||
|
const OuterShell = styled('div')`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-around;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TransferShell = styled('div')`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TransferButtonShell = styled('div')`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 25%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TransferHeader = styled('div')`
|
||||||
|
padding-bottom: 10px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TransferOuterBox = styled('div')`
|
||||||
|
display: flex;
|
||||||
|
width: 200px;
|
||||||
|
height: 250px;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #E8E8E8;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TransferInnerBox = styled('div')`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TransferBoxItem = styled('div')`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 188px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
background-color: ${({ isSelected }) => (isSelected ? '#D3D3D3' : 'transparent')};
|
||||||
|
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
|
||||||
|
color: ${({ disabled }) => (disabled ? '#999' : 'inherit')};
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: ${({ disabled }) => (disabled ? 'none' : 'auto')};
|
||||||
|
opacity: ${({ disabled }) => (disabled ? 0.5 : 1)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TransferBoxLabel = styled('span')`
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
`;
|
||||||
|
|
||||||
const CenterButton = styled('div')`
|
const CenterButton = styled('div')`
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -26,7 +90,21 @@ const CenterButton = styled('div')`
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const TransferBox = ({ fields, leftGroup, rightGroup }) => {
|
const sortByLastThenFirst = (arr) => {
|
||||||
|
return [...arr].sort((a, b) => {
|
||||||
|
const [aLast, aFirst] = a.value.split(',').map(s => s.trim());
|
||||||
|
const [bLast, bFirst] = b.value.split(',').map(s => s.trim());
|
||||||
|
|
||||||
|
if (aLast < bLast) return -1;
|
||||||
|
if (aLast > bLast) return 1;
|
||||||
|
if (aFirst < bFirst) return -1;
|
||||||
|
if (aFirst > bFirst) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const TransferBox = ({ fields, leftGroup, rightGroup, onSave, user={} }) => {
|
||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
exclusionList,
|
exclusionList,
|
||||||
|
|
@ -35,104 +113,141 @@ export const TransferBox = ({ fields, leftGroup, rightGroup }) => {
|
||||||
} = fields;
|
} = fields;
|
||||||
|
|
||||||
const [itemSelected, setItemSelected] = useState({});
|
const [itemSelected, setItemSelected] = useState({});
|
||||||
const [containsSelection, setContainsSelection] = useState([]);
|
const [leftItems, setLeftItems] = useState(sortByLastThenFirst(leftGroup || []));
|
||||||
|
const [rightItems, setRightItems] = useState(sortByLastThenFirst(rightGroup || []));
|
||||||
|
|
||||||
|
const handleItemClick = (item, side) => {
|
||||||
|
setItemSelected({ ...item, from: side });
|
||||||
|
};
|
||||||
|
|
||||||
|
const arraysEqual = (a, b) => {
|
||||||
|
if (a.length !== b.length) return false;
|
||||||
|
const aIds = a.map(i => i.id).sort();
|
||||||
|
const bIds = b.map(i => i.id).sort();
|
||||||
|
return JSON.stringify(aIds) === JSON.stringify(bIds);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isLeftArrowEnabled = itemSelected?.from === 'right';
|
||||||
|
const isRightArrowEnabled = itemSelected?.from === 'left';
|
||||||
|
|
||||||
|
const hasChanges = !arraysEqual(leftItems, leftGroup) || !arraysEqual(rightItems, rightGroup);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', flexDirection: 'row', width: '100%', justifyContent: 'space-around' }}>
|
<OuterShell>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', width: '100%', alignItems: 'center', padding: '5px' }}>
|
<TransferShell>
|
||||||
<div style={{ paddingBottom: '10px' }}>
|
<TransferHeader>
|
||||||
<h2>{oldListLabel}</h2>
|
<h2>{oldListLabel}</h2>
|
||||||
</div>
|
</TransferHeader>
|
||||||
<div style={{ display: 'flex', width: '200px', height: '250px', border: '1px solid black', borderRadius: '5px', backgroundColor: '#E8E8E8' }}>
|
<TransferOuterBox>
|
||||||
<div
|
<TransferInnerBox>
|
||||||
style={{
|
{leftItems?.filter(leftItem => !rightItems.some(rightItem => rightItem.id === leftItem.id))?.map((j) => {
|
||||||
display: 'flex',
|
const isUser = user?.id === j?.id;
|
||||||
flexDirection: 'column',
|
const isSelected = itemSelected?.id === j?.id && itemSelected?.from === 'left' && !isUser;
|
||||||
padding: '5px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{leftGroup?.map((j, index) => {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<TransferBoxItem
|
||||||
key={index}
|
key={j?.id}
|
||||||
style={{
|
isSelected={isSelected}
|
||||||
whiteSpace: 'nowrap',
|
disabled={isUser}
|
||||||
overflow: 'hidden',
|
onClick={() => {
|
||||||
textOverflow: 'ellipsis',
|
if (isUser) return;
|
||||||
width: '80%',
|
handleItemClick(j, 'left');
|
||||||
padding: '2px',
|
|
||||||
}}
|
}}
|
||||||
title={j?.value}
|
title={j?.value}
|
||||||
>
|
>
|
||||||
<span>{j?.value}</span>
|
<TransferBoxLabel>
|
||||||
</div>
|
{j?.value}
|
||||||
|
</TransferBoxLabel>
|
||||||
|
</TransferBoxItem>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</TransferInnerBox>
|
||||||
</div>
|
</TransferOuterBox>
|
||||||
</div>
|
</TransferShell>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', width: '25%', alignItems: 'center', justifyContent: 'center' }}>
|
<TransferButtonShell>
|
||||||
<CenterButton
|
<CenterButton
|
||||||
onClick={() => { console.log('clicked Right') }}
|
onClick={() => {
|
||||||
|
if (!itemSelected) return;
|
||||||
|
if (itemSelected.from === 'left') {
|
||||||
|
setLeftItems(prev => prev.filter(item => item.id !== itemSelected.id));
|
||||||
|
setRightItems(prev => sortByLastThenFirst([
|
||||||
|
...rightItems.filter(item => item.id !== itemSelected.id),
|
||||||
|
itemSelected
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
setItemSelected({});
|
||||||
|
}}
|
||||||
color='#A8A8A8'
|
color='#A8A8A8'
|
||||||
buttonEnabled={itemSelected?.id}
|
buttonEnabled={isRightArrowEnabled}
|
||||||
>
|
>
|
||||||
<KeyboardArrowRightIcon />
|
<KeyboardArrowRightIcon />
|
||||||
</CenterButton>
|
</CenterButton>
|
||||||
<CenterButton
|
<CenterButton
|
||||||
onClick={() => { console.log('clicked Clear') }}
|
onClick={() => {
|
||||||
|
setLeftItems(sortByLastThenFirst(leftGroup));
|
||||||
|
setRightItems(sortByLastThenFirst(rightGroup));
|
||||||
|
setItemSelected({});
|
||||||
|
}}
|
||||||
color='#FF6666'
|
color='#FF6666'
|
||||||
buttonEnabled={containsSelection?.length > 0}
|
buttonEnabled={hasChanges}
|
||||||
>
|
>
|
||||||
<DoNotDisturbIcon />
|
<DoNotDisturbIcon />
|
||||||
</CenterButton>
|
</CenterButton>
|
||||||
<CenterButton
|
<CenterButton
|
||||||
onClick={() => { console.log('clicked Save') }}
|
onClick={() => {
|
||||||
|
return onSave(rightItems?.map((item) => { return item?.id }))
|
||||||
|
}}
|
||||||
color='#00B33C'
|
color='#00B33C'
|
||||||
buttonEnabled={containsSelection?.length > 0}
|
buttonEnabled={hasChanges}
|
||||||
>
|
>
|
||||||
<CheckIcon />
|
<CheckIcon />
|
||||||
</CenterButton>
|
</CenterButton>
|
||||||
<CenterButton
|
<CenterButton
|
||||||
onClick={() => { console.log('clicked Left') }}
|
onClick={() => {
|
||||||
|
if (!itemSelected) return;
|
||||||
|
if (itemSelected.from === 'right') {
|
||||||
|
setRightItems(prev => prev.filter(item => item.id !== itemSelected.id));
|
||||||
|
setLeftItems(prev => sortByLastThenFirst([
|
||||||
|
...leftItems.filter(item => item.id !== itemSelected.id),
|
||||||
|
itemSelected
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
setItemSelected({});
|
||||||
|
}}
|
||||||
color='#A8A8A8'
|
color='#A8A8A8'
|
||||||
buttonEnabled={itemSelected?.id}
|
buttonEnabled={isLeftArrowEnabled}
|
||||||
>
|
>
|
||||||
<KeyboardArrowLeftIcon />
|
<KeyboardArrowLeftIcon />
|
||||||
</CenterButton>
|
</CenterButton>
|
||||||
</div>
|
</TransferButtonShell>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', width: '100%', alignItems: 'center', padding: '5px' }}>
|
<TransferShell>
|
||||||
<div style={{ paddingBottom: '10px' }}>
|
<TransferHeader>
|
||||||
<h2>{newListLabel}</h2>
|
<h2>{newListLabel}</h2>
|
||||||
</div>
|
</TransferHeader>
|
||||||
<div style={{ display: 'flex', width: '200px', height: '250px', border: '1px solid black', borderRadius: '5px', backgroundColor: '#E8E8E8' }}>
|
<TransferOuterBox>
|
||||||
<div
|
<TransferInnerBox>
|
||||||
style={{
|
{rightItems?.map((j) => {
|
||||||
display: 'flex',
|
const isUser = user?.id === j?.id;
|
||||||
flexDirection: 'column',
|
const isSelected = itemSelected?.id === j?.id && itemSelected?.from === 'right' && !isUser;
|
||||||
padding: '5px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{rightGroup?.map((j, index) => {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<TransferBoxItem
|
||||||
key={index}
|
key={j?.id}
|
||||||
style={{
|
isSelected={isSelected}
|
||||||
whiteSpace: 'nowrap',
|
disabled={isUser}
|
||||||
overflow: 'hidden',
|
onClick={() => {
|
||||||
textOverflow: 'ellipsis',
|
if (isUser) return;
|
||||||
width: '80%',
|
handleItemClick(j, 'right');
|
||||||
padding: '2px',
|
|
||||||
}}
|
}}
|
||||||
title={j?.value}
|
title={j?.value}
|
||||||
>
|
>
|
||||||
<span>{j?.value}</span>
|
<TransferBoxLabel>
|
||||||
</div>
|
{j?.value}
|
||||||
|
</TransferBoxLabel>
|
||||||
|
</TransferBoxItem>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</TransferInnerBox>
|
||||||
</div>
|
</TransferOuterBox>
|
||||||
</div>
|
</TransferShell>
|
||||||
</div>
|
</OuterShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -285,8 +285,22 @@ export const Settings = () => {
|
||||||
}, [pageValue?.id, windowWidth, window.innerHeight]);
|
}, [pageValue?.id, windowWidth, window.innerHeight]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPageValue(settingsFields?.filter((field) => field?.tab === tabValue?.value)[0]);
|
const filteredFields = settingsFields?.filter((field) => {
|
||||||
}, [tabValue]);
|
const hasAccess =
|
||||||
|
(field?.accessRequired === 'administrator' && isAdministrator) ||
|
||||||
|
(field?.accessRequired === 'manager' && isManager) ||
|
||||||
|
(field?.accessRequired === 'scheduler' && isScheduler) ||
|
||||||
|
(!field?.accessRequired || field?.accessRequired === 'user');
|
||||||
|
|
||||||
|
return field?.tab === tabValue?.value && hasAccess;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (filteredFields.length > 0) {
|
||||||
|
setPageValue(filteredFields[0]);
|
||||||
|
} else {
|
||||||
|
setPageValue(null);
|
||||||
|
}
|
||||||
|
}, [tabValue, isAdministrator, isManager, isScheduler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -433,9 +447,11 @@ export const Settings = () => {
|
||||||
} else if (field?.type === 'transfer') {
|
} else if (field?.type === 'transfer') {
|
||||||
fieldType = <TransferBox
|
fieldType = <TransferBox
|
||||||
style={{ display: 'flex', flexDirection: 'row' }}
|
style={{ display: 'flex', flexDirection: 'row' }}
|
||||||
|
user={user}
|
||||||
fields={field}
|
fields={field}
|
||||||
leftGroup={department[field?.origList]}
|
leftGroup={department[field?.origList]}
|
||||||
rightGroup={department[field?.id]}
|
rightGroup={department[field?.id]}
|
||||||
|
onSave={(t) => console.log(t)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
return field?.type !== 'header' && (
|
return field?.type !== 'header' && (
|
||||||
|
|
|
||||||
|
|
@ -85,22 +85,22 @@ export const settingsFields = [
|
||||||
title: 'Roles',
|
title: 'Roles',
|
||||||
tab: 'department',
|
tab: 'department',
|
||||||
cards: [
|
cards: [
|
||||||
{
|
// Need to decide if Admins should be able to Add other Admins
|
||||||
id: 'companyAdmins',
|
// {
|
||||||
label: 'Company Administrators',
|
// id: 'companyAdmins',
|
||||||
fields: [
|
// label: 'Company Administrators',
|
||||||
{
|
// fields: [
|
||||||
id: 'administrators',
|
// {
|
||||||
type: 'transfer',
|
// id: 'administrators',
|
||||||
exclusionList: [],
|
// type: 'transfer',
|
||||||
origList: 'users',
|
// origList: 'users',
|
||||||
oldListLabel: 'Users',
|
// oldListLabel: 'Users',
|
||||||
newListLabel: 'Administrators'
|
// newListLabel: 'Administrators'
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
accessRequired: 'administrator',
|
// accessRequired: 'administrator',
|
||||||
removeEdit: true
|
// removeEdit: true
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
id: 'companyMgrs',
|
id: 'companyMgrs',
|
||||||
label: 'Company Managers',
|
label: 'Company Managers',
|
||||||
|
|
@ -108,9 +108,6 @@ export const settingsFields = [
|
||||||
{
|
{
|
||||||
id: 'managers',
|
id: 'managers',
|
||||||
type: 'transfer',
|
type: 'transfer',
|
||||||
exclusionList: [
|
|
||||||
'administrators'
|
|
||||||
],
|
|
||||||
origList: 'users',
|
origList: 'users',
|
||||||
oldListLabel: 'Users',
|
oldListLabel: 'Users',
|
||||||
newListLabel: 'Managers'
|
newListLabel: 'Managers'
|
||||||
|
|
@ -126,10 +123,6 @@ export const settingsFields = [
|
||||||
{
|
{
|
||||||
id: 'schedulers',
|
id: 'schedulers',
|
||||||
type: 'transfer',
|
type: 'transfer',
|
||||||
exclusionList: [
|
|
||||||
'administrators',
|
|
||||||
'managers'
|
|
||||||
],
|
|
||||||
origList: 'users',
|
origList: 'users',
|
||||||
oldListLabel: 'Users',
|
oldListLabel: 'Users',
|
||||||
newListLabel: 'Schedulers'
|
newListLabel: 'Schedulers'
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue