Created
October 6, 2021 10:14
-
-
Save ayappaP/305638433f5b2eb1fdaeda4b8cdccd2f to your computer and use it in GitHub Desktop.
AddUsersToGroupSlider / AddGroupsToUserSlider Fluent UI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable @typescript-eslint/no-unused-vars */ | |
import { | |
DetailsList, | |
DetailsListLayoutMode, | |
IColumn, | |
} from '@fluentui/react/lib/DetailsList'; | |
import { | |
BaseButton, | |
CommandBarButton, | |
DefaultButton, | |
} from '@fluentui/react/lib/Button'; | |
import { Separator } from '@fluentui/react/lib/Separator'; | |
import { IContextualMenuProps } from '@fluentui/react/lib/ContextualMenu'; | |
import { mergeStyleSets, getTheme } from '@fluentui/react/lib/Styling'; | |
import { useBoolean } from '@fluentui/react-hooks'; | |
import { useMemo, useState, useCallback } from 'react'; | |
import { SearchBox, ISearchBoxStyles } from '@fluentui/react/lib/SearchBox'; | |
import { Icon, IIconProps, Link } from '@fluentui/react'; | |
import { Breadcrumb, IBreadcrumbItem } from '@fluentui/react/lib/Breadcrumb'; | |
import { ActiveStatusType, ApplicationRole, Group } from 'API'; | |
import { Panel } from '@fluentui/react/lib/Panel'; | |
import { PanelType } from 'office-ui-fabric-react'; | |
import Text from 'components/Text'; | |
import AddButton from 'components/Pages/AddButton'; | |
import Flex from 'components/Flex'; | |
import AddGroupSlider from 'components/Pages/Groups/AddGroupSlider'; | |
import DeleteModal from 'components/DeleteModal'; | |
import Button from 'components/Button'; | |
import AddUsersToGroupSlider from 'components/Pages/Groups/AddUsersToGroupSlider'; | |
import ExperimentalPanel from 'components/Pages/Groups/ExperimentalPanel'; | |
import HomeLoader from 'components/Loader/HomeLoader'; | |
import useSlider from 'hooks/useSlider'; | |
import useGroupMutations from 'hooks/useGroupMutations'; | |
import useModal from 'hooks/useModal'; | |
import useGroupsList from 'queries/groups.query'; | |
import useUsersList from 'queries/users.query'; | |
import { sortList } from 'helpers/sortList'; | |
const explanation = | |
'This panel uses "light dismiss" behavior: it can be closed by clicking or tapping ' + | |
'the area outside the panel (or using the close button as usual).'; | |
export const PanelLightDismissExample: React.FunctionComponent = () => { | |
const [isOpen, { setTrue: openPanel, setFalse: dismissPanel }] = useBoolean( | |
false, | |
); | |
return ( | |
<div> | |
{explanation} | |
<br /> | |
<br /> | |
<DefaultButton text="Open panel" onClick={openPanel} /> | |
<Panel | |
isLightDismiss | |
isOpen={isOpen} | |
onDismiss={dismissPanel} | |
closeButtonAriaLabel="Close" | |
headerText="Light dismiss panel" | |
> | |
<p>{explanation}</p> | |
</Panel> | |
</div> | |
); | |
}; | |
const Groups = () => { | |
const { isSliderOpen, openSlider, closeSlider } = useSlider(false); | |
const { onUpdateGroup } = useGroupMutations(); | |
const { data: groups, isLoading } = useGroupsList({ | |
filter: { status: { eq: ActiveStatusType.ACTIVE } }, | |
}); | |
console.log('🚀 ~ file: index.tsx ~ line 42 ~ Groups ~ groups foo', groups); | |
const { data: users, isLoading: isRolesLoading } = useUsersList({ | |
filter: { status: { eq: ActiveStatusType.ACTIVE } }, | |
}); | |
// console.log('data', groups); | |
// console.log('users', users); | |
// console.log(groups?.data?.listGroups?.items, 'listGroups'); | |
const { isModalOpen, openModal, closeModal } = useModal(false); | |
const { | |
isModalOpen: isModal1Open, | |
openModal: openModal1, | |
closeModal: closeModal1, | |
} = useModal(false); | |
const { | |
isSliderOpen: isUsersAssignSliderOpen, | |
openSlider: openUsersAssignSlider, | |
closeSlider: closeUsersAssignSlider, | |
} = useSlider(false); | |
const [isEdit, setIsEdit] = useState<boolean>(false); | |
const [groupToDelete, setGroupToDelete] = useState<string | null>(null); | |
const [showDropDown, setShow] = useState(false); | |
const [showId, setShowId] = useState(''); | |
const [selectedUser, setSelectedUser] = useState(null); | |
const AddIcon: IIconProps = { | |
iconName: 'Add', | |
style: { fontSize: 10, fontWeight: 'bold' }, | |
}; | |
const ContactIcon: IIconProps = { | |
iconName: 'Contact', | |
style: { fontSize: 20, fontWeight: 'bold' }, | |
}; | |
const deletegroup = () => { | |
if (groupToDelete) { | |
onUpdateGroup( | |
{ | |
id: groupToDelete, | |
status: ActiveStatusType.DELETED, | |
}, | |
closeModal, | |
); | |
} | |
}; | |
const saveRoles = () => { | |
// console.log('saveRoles'); | |
}; | |
const triggerDeleteAlert = useCallback( | |
(id: string) => { | |
setGroupToDelete(id); | |
openModal(); | |
}, | |
[openModal], | |
); | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
const items: any = groups?.data?.listGroups?.items || []; | |
const groupList: any = useMemo(() => sortList(items), [items]); | |
const userItems: any = users?.data?.listUsers?.items || []; | |
const userList: any = useMemo(() => sortList(userItems), [userItems]); | |
const hasGroups: boolean = items.length > 0; | |
const [groupToEdit, setUserToEdit] = useState<any>({ | |
id: '', | |
name: '', | |
description: '', | |
}); | |
const [ | |
groupToAssignUsersTo, | |
setGroupToAssignUsersTo, | |
] = useState<Group | null>(null); | |
const [ | |
isAssigningUsersToGroup, | |
setIsAssigningUsersToGroup, | |
] = useState<boolean>(false); | |
const [isOpen, { setTrue: openPanel, setFalse: dismissPanel }] = useBoolean( | |
false, | |
); | |
const openEditUserSlider = useCallback( | |
(group: Group) => { | |
setUserToEdit(group); | |
setIsEdit(true); | |
openSlider(); | |
}, | |
[openSlider], | |
); | |
const openCreateUserSlider = () => { | |
setUserToEdit({ id: '', name: '', description: '' }); | |
setIsEdit(false); | |
openSlider(); | |
}; | |
// const handleOpenUsersAssignSlider = useCallback( | |
// (item: Group) => { | |
// setIsAssigningUsersToGroup(true); | |
// setGroupToAssignUsersTo(item); | |
// openUsersAssignSlider(); | |
// setShow(false); | |
// setShowId(''); | |
// }, | |
// [openUsersAssignSlider], | |
// ); | |
const handleOpenUsersAssignSlider = useCallback( | |
(item: Group) => { | |
setIsAssigningUsersToGroup(true); | |
setGroupToAssignUsersTo(item); | |
// openUsersAssignSlider(); | |
openPanel(); | |
setShow(false); | |
setShowId(''); | |
}, | |
[openPanel], | |
); | |
const openAssignSlider = (item: any) => { | |
// setShowId(item.id); | |
// setSelectedUser(item?.users?.items); | |
openModal1(); | |
}; | |
const [ | |
showCallout, | |
{ setTrue: onShowCallout, setFalse: onHideCallout }, | |
] = useBoolean(false); | |
const MoreVerticalIcon: IIconProps = { | |
iconName: 'MoreVertical', | |
style: { fontSize: 10, fontWeight: 'bold' }, | |
}; | |
const [selectedGroup, setSelectedGroup] = useState<Group | null>(null); | |
console.log( | |
'🚀 ~ file: index.tsx ~ line 154 ~ Groups ~ selectedGroup', | |
selectedGroup, | |
); | |
const menuProps: IContextualMenuProps = useMemo( | |
() => ({ | |
shouldFocusOnMount: true, | |
items: [ | |
{ | |
key: 'addUser', | |
iconProps: { iconName: 'EditContact' }, | |
text: 'Add user', | |
onClick: () => { | |
console.log('Add user', selectedGroup); | |
if (selectedGroup) { | |
handleOpenUsersAssignSlider(selectedGroup); | |
} | |
}, | |
}, | |
{ | |
key: 'editGroup', | |
text: 'Edit group name', | |
iconProps: { iconName: 'Group' }, | |
onClick: () => { | |
console.log('Edit group name', selectedGroup); | |
if (selectedGroup) { | |
openEditUserSlider(selectedGroup); | |
} | |
}, | |
}, | |
{ | |
key: 'deleteGroup', | |
text: 'Delete Group', | |
iconProps: { iconName: 'Delete' }, | |
onClick: () => { | |
console.log('Manage Groups', selectedGroup); | |
if (selectedGroup) { | |
triggerDeleteAlert(selectedGroup.id); | |
} | |
}, | |
}, | |
], | |
}), | |
[ | |
selectedGroup, | |
handleOpenUsersAssignSlider, | |
openEditUserSlider, | |
triggerDeleteAlert, | |
], | |
); | |
const columns: IColumn[] = [ | |
{ | |
key: 'column1', | |
fieldName: 'name', | |
name: 'Group Name', | |
minWidth: 100, | |
maxWidth: 200, | |
isResizable: true, | |
onRender: (item: any) => ( | |
<div className="flex justify-between"> | |
<Text>{`${item.name}`}</Text> | |
<BaseButton | |
onMenuClick={(e) => { | |
console.log('foo', e?.target); | |
setSelectedGroup(item); | |
}} | |
// onAfterMenuDismiss={() => setSelectedUser(null)} | |
menuProps={menuProps} | |
menuIconProps={MoreVerticalIcon} | |
/> | |
{/* {showCallout && ( | |
<Callout setInitialFocus onDismiss={onHideCallout}> | |
<DefaultButton onClick={onHideCallout} text="Hello Popup" /> | |
</Callout> | |
)} */} | |
</div> | |
), | |
}, | |
{ | |
key: 'column2', | |
fieldName: 'description', | |
name: 'Description', | |
minWidth: 100, | |
maxWidth: 200, | |
isResizable: true, | |
}, | |
]; | |
const searchBoxStyles: Partial<ISearchBoxStyles> = { | |
root: { width: 200, borderColor: 'lightgray' }, | |
}; | |
const onBreadcrumbItemClicked = ( | |
ev?: React.MouseEvent<HTMLElement>, | |
item?: IBreadcrumbItem, | |
) => { | |
console.log(`Breadcrumb item with key "${item?.key}" has been clicked.`); | |
}; | |
const breadCrumbItems: IBreadcrumbItem[] = [ | |
{ | |
text: 'Groups', | |
key: 'f4', | |
onClick: onBreadcrumbItemClicked, | |
style: { fontSize: '.875rem' }, | |
}, | |
{ | |
text: 'Active Groups', | |
key: 'f5', | |
onClick: onBreadcrumbItemClicked, | |
isCurrentItem: true, | |
style: { fontSize: '.875rem', fontWeight: 'normal' }, | |
}, | |
]; | |
// return ( | |
// <div> | |
// {explanation} | |
// <br /> | |
// <br /> | |
// <DefaultButton text="Open panel" onClick={openPanel} /> | |
// <Panel | |
// isLightDismiss | |
// isOpen={isOpen} | |
// onDismiss={dismissPanel} | |
// closeButtonAriaLabel="Close" | |
// headerText="Light dismiss panel" | |
// > | |
// <p>{explanation}</p> | |
// </Panel> | |
// </div> | |
// ); | |
if (isLoading) return <HomeLoader />; | |
return ( | |
<> | |
<Flex | |
justify="center" | |
// padding="pt-8" | |
direction="col" | |
width="w-10/12 mx-auto" | |
> | |
<Breadcrumb | |
items={breadCrumbItems} | |
maxDisplayedItems={10} | |
ariaLabel="Breadcrumb with items rendered as buttons" | |
overflowAriaLabel="More links" | |
/> | |
</Flex> | |
<Flex | |
justify="center" | |
padding="pt-8" | |
direction="col" | |
width="w-10/12 mx-auto" | |
> | |
<Flex direction="col" width="lg:w-3/5 sm: w-full"> | |
<Text variant="xxLarge" weight={500} className="mb-4"> | |
Active Groups | |
</Text> | |
<Text variant="medium" className="mb-4"> | |
It can take up to an hour for distribution groups and mail-enabled | |
security groups to appear in your Active groups list. If you dont | |
see your new group yet. | |
<Link href="/#/">go to the Exchange admin center.</Link> | |
</Text> | |
<Link href="/#/" className="mb-8"> | |
Learn more about group types. | |
</Link>{' '} | |
</Flex> | |
<Flex width="w-full" justify="end" className="mb-8"> | |
<SearchBox | |
styles={searchBoxStyles} | |
placeholder="Search all groups" | |
onEscape={(ev) => { | |
console.log('Custom onEscape Called'); | |
}} | |
onClear={(ev) => { | |
console.log('Custom onClear Called'); | |
}} | |
onChange={(_, newValue) => | |
console.log(`SearchBox onChange fired: ${newValue}`) | |
} | |
onSearch={(newValue) => | |
console.log(`SearchBox onSearch fired: ${newValue}`) | |
} | |
/> | |
</Flex> | |
{/* <hr className="h-0.5 w-full bg-gray-200 my-5" /> */} | |
<Separator alignContent="center" /> | |
{/* <AddButton | |
title="Add Group" | |
openSlider={openCreateUserSlider} | |
hasProducts={hasGroups} | |
/> */} | |
<AddGroupSlider | |
key={groupToEdit.id} | |
isEdit={isEdit} | |
setIsEdit={setIsEdit} | |
group={groupToEdit} | |
closeSlider={closeSlider} | |
isSliderOpen={isSliderOpen} | |
/> | |
{/* <AddUsersToGroupSlider | |
key={groupToAssignUsersTo?.id || ''} | |
isEdit={isAssigningUsersToGroup} | |
setIsEdit={setIsAssigningUsersToGroup} | |
groupToAssignUsersTo={groupToAssignUsersTo} | |
setGroupToAssignUsersTo={setGroupToAssignUsersTo} | |
closeSlider={closeUsersAssignSlider} | |
allUsers={userList} | |
isSliderOpen={isUsersAssignSliderOpen} | |
/> */} | |
<ExperimentalPanel | |
key={groupToAssignUsersTo?.id || ''} | |
isEdit={isAssigningUsersToGroup} | |
setIsEdit={setIsAssigningUsersToGroup} | |
groupToAssignUsersTo={groupToAssignUsersTo} | |
setGroupToAssignUsersTo={setGroupToAssignUsersTo} | |
closeSlider={closeUsersAssignSlider} | |
allUsers={userList} | |
isSliderOpen={isUsersAssignSliderOpen} | |
isOpen={isOpen} | |
dismissPanel={dismissPanel} | |
/> | |
{/* <Panel | |
isLightDismiss | |
isOpen={isOpen} | |
onDismiss={dismissPanel} | |
closeButtonAriaLabel="Close" | |
headerText="Light dismiss panel" | |
type={PanelType.medium} | |
> | |
<p>{explanation}</p> | |
</Panel> */} | |
<div className="w-full mx-auto mb-10"> | |
<Flex width="w-full" justify="end" className="mb-4"> | |
<Flex justify="start" alignItems="center"> | |
<CommandBarButton | |
iconProps={ContactIcon} | |
text="Add a Group" | |
className="font-extrabold focus:outline-none" | |
onClick={openCreateUserSlider} | |
/> | |
</Flex> | |
<Flex justify="end" alignItems="center"> | |
<Text variant="mediumPlus" className="mr-2 text-black"> | |
{groupList.length} items | |
</Text> | |
<Icon | |
iconName="Filter" | |
onClick={() => setShow(!showDropDown)} | |
className="text-xl mr-2 my-auto text-blue-600" | |
/> | |
<Text variant="mediumPlus" className="mr-2 text-black"> | |
Filter | |
</Text> | |
</Flex> | |
<Icon | |
iconName="List" | |
onClick={() => setShow(!showDropDown)} | |
className="text-xl ml-4 my-auto text-blue-600" | |
/> | |
</Flex> | |
{hasGroups && ( | |
<DetailsList | |
items={groupList} | |
columns={columns} | |
setKey="set" | |
layoutMode={DetailsListLayoutMode.justified} | |
selectionPreservedOnEmptyClick | |
ariaLabelForSelectionColumn="Toggle selection" | |
ariaLabelForSelectAllCheckbox="Toggle selection for all items" | |
checkButtonAriaLabel="select row" | |
onRenderRow={(props, defaultRender) => { | |
if (!props) return null; | |
// eslint-disable-next-line no-param-reassign | |
props.styles = { | |
root: { | |
height: 42, | |
minHeight: 42, | |
}, | |
}; | |
return defaultRender ? defaultRender(props) : <></>; | |
}} | |
/> | |
)} | |
</div> | |
<DeleteModal | |
key={groupToDelete} | |
title="Are you sure you want to delete the Group?" | |
description="Deleting this group will delete its associated user role access" | |
isOpen={isModalOpen} | |
closeModal={closeModal} | |
onDelete={deletegroup} | |
/> | |
</Flex> | |
</> | |
); | |
}; | |
export default Groups; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable jsx-a11y/label-has-associated-control */ | |
/* eslint-disable @typescript-eslint/no-unused-vars */ | |
/* eslint-disable @typescript-eslint/unbound-method */ | |
import { DefaultButton, PrimaryButton } from '@fluentui/react/lib/Button'; | |
import { SearchBox, ISearchBoxStyles } from '@fluentui/react/lib/SearchBox'; | |
import { useForm, Controller } from 'react-hook-form'; | |
import { useEffect, useState, useCallback, useRef } from 'react'; | |
import { User, UserGroup } from 'API'; | |
import { group } from '@uiw/react-md-editor'; | |
import { | |
CheckboxVisibility, | |
ChoiceGroup, | |
DetailsList, | |
DetailsListLayoutMode, | |
Facepile, | |
IChoiceGroupOption, | |
MarqueeSelection, | |
Panel, | |
PanelType, | |
Persona, | |
PersonaSize, | |
Selection, | |
IColumn, | |
} from '@fluentui/react'; | |
import { useToasts } from 'react-toast-notifications'; | |
import { Stack, IStackStyles, IStackTokens } from '@fluentui/react/lib/Stack'; | |
import { IObjectWithKey } from 'office-ui-fabric-react'; | |
import { UserType } from 'types/user'; | |
import { AS_EMAIL, AS_NAME } from 'consts/validations'; | |
import Flex from 'components/Flex'; | |
import Text from 'components/Text'; | |
import InputField from 'components/InputField'; | |
import Slider from 'components/Slider'; | |
import useApplicationRoleMutations from 'hooks/useApplicationRoleMutations'; | |
import useAssignUsersToGroupMutation from 'hooks/useAssignUsersToGroupMutation'; | |
import useSendNotification from 'hooks/useSendNotification'; | |
import getS3InputObject from 'helpers/transformFile'; | |
import { sortList } from 'helpers/sortList'; | |
import styles from './usergroup.module.css'; | |
type CustomUser = User & { | |
checked: boolean; | |
}; | |
const colors: any = { | |
A: 'bg-blue-600', | |
B: 'bg-yellow-600', | |
C: 'bg-red-900', | |
D: 'bg-indigo-600', | |
E: 'bg-yellow-800', | |
F: 'bg-pink-500', | |
G: 'bg-yellow-900', | |
H: 'bg-blue-500', | |
I: 'bg-black', | |
J: 'bg-gray-600', | |
K: 'bg-blue-600', | |
L: 'bg-yellow-600', | |
M: 'bg-red-900', | |
N: 'bg-indigo-600', | |
O: 'bg-yellow-800', | |
P: 'bg-pink-500', | |
Q: 'bg-yellow-900', | |
R: 'bg-blue-500', | |
S: 'bg-black', | |
T: 'bg-gray-600', | |
U: 'bg-blue-600', | |
V: 'bg-yellow-600', | |
W: 'bg-red-900', | |
X: 'bg-indigo-600', | |
Y: 'bg-yellow-800', | |
Z: 'bg-pink-500', | |
}; | |
export interface IDetailsListBasicExampleItem { | |
key: number; | |
name: string; | |
value: number; | |
} | |
const useConstructor = (callBack = () => {}) => { | |
const hasBeenCalled = useRef(false); | |
if (hasBeenCalled.current) return; | |
callBack(); | |
hasBeenCalled.current = true; | |
}; | |
const AddUsersToGroupSlider = ({ | |
isEdit, | |
isSliderOpen, | |
closeSlider, | |
groupToAssignUsersTo, | |
setGroupToAssignUsersTo, | |
setIsEdit, | |
allUsers, | |
isOpen, | |
dismissPanel, | |
}: any) => { | |
const { | |
register, | |
handleSubmit, | |
reset, | |
formState: { errors }, | |
control, | |
setValue, | |
} = useForm<any>({ | |
defaultValues: { | |
users: [], | |
}, | |
}); | |
const { addToast } = useToasts(); | |
const [users, setUsers] = useState<CustomUser[]>([]); | |
const { | |
onAssignUsersToGroup, | |
isAssignUsersToGroupLoading, | |
isAssignUsersToGroupSuccess, | |
} = useAssignUsersToGroupMutation(); | |
useEffect(() => { | |
if (groupToAssignUsersTo) { | |
const constructedUsers = | |
allUsers.map((user: User) => { | |
const isUserAlreadyPresentInGroup = !!groupToAssignUsersTo?.users.items.find( | |
(usrGroup: UserGroup) => usrGroup.userId === user.id, | |
); | |
if (isUserAlreadyPresentInGroup) { | |
return { | |
...user, | |
checked: true, | |
}; | |
} | |
return { | |
...user, | |
checked: false, | |
}; | |
}) || []; | |
const constructedUsersSorted = sortList(constructedUsers); | |
setUsers(constructedUsersSorted); | |
} | |
}, [groupToAssignUsersTo, allUsers]); | |
const { | |
onCreateApplicationRole, | |
onUpdateApplicationRole, | |
isCreateLoading, | |
isUpdateLoading, | |
isCreateSuccess, | |
isUpdateSuccess, | |
} = useApplicationRoleMutations(); | |
useEffect(() => { | |
if (isCreateSuccess || isUpdateSuccess) { | |
reset(); | |
} | |
}, [isCreateSuccess, isUpdateSuccess, reset]); | |
const [application, setApplication] = useState<any>(null); | |
const [roleOptions, setRoleOptions] = useState<any>([]); | |
const { | |
onCreate: onSendNotification, | |
// isCreateLoading: isSendingNotification, | |
// isCreateSuccess: isNotificationSuccess, | |
} = useSendNotification(); | |
useEffect(() => { | |
console.log('selectedApplication', application); | |
if (application?.id) { | |
setRoleOptions(application?.defaultRoles); | |
console.log('roleOptions', application?.defaultRoles); | |
} | |
}, [application]); | |
const addNewApplicationRole = (data: any) => { | |
onCreateApplicationRole({ ...data }, closeSlider); | |
}; | |
const updateUser = (data: any) => { | |
// const argsData = transformArgs(data); | |
const final = { id: groupToAssignUsersTo.id, ...data }; | |
setIsEdit(false); | |
onUpdateApplicationRole({ ...final }, closeSlider); | |
}; | |
const submit = (event: any): void => { | |
event.preventDefault(); | |
const userGroups = groupToAssignUsersTo.users.items || []; | |
const alreadyExistingUsersInGroupToRemove = userGroups.filter( | |
(usr: UserGroup) => users.some((x) => x.id === usr.userId && !x.checked), | |
); | |
const newUsersToAddToGroup = users.filter( | |
(user) => | |
user.checked && | |
!userGroups.some((x: UserGroup) => x.userId === user.id), | |
); | |
console.log( | |
'submit', | |
alreadyExistingUsersInGroupToRemove, | |
newUsersToAddToGroup, | |
); | |
const userGroupIdsToRemove = alreadyExistingUsersInGroupToRemove.map( | |
(userGroup: UserGroup) => userGroup.id, | |
); | |
const userIdsToAddToGroup = newUsersToAddToGroup.map( | |
(user: User) => user.id, | |
); | |
// console.log('userEmailsToAddToGroup', userEmailsToAddToGroup); | |
// console.log('groupToAssignUsersTo', groupToAssignUsersTo); | |
if (userGroupIdsToRemove.length > 0 || userIdsToAddToGroup.length > 0) { | |
closeSlider(); | |
addToast( | |
`Assigning users to group "${groupToAssignUsersTo.name}". Please wait a few seconds.`, | |
{ | |
appearance: 'success', | |
autoDismiss: true, | |
}, | |
); | |
onAssignUsersToGroup( | |
groupToAssignUsersTo, | |
{ | |
groupId: groupToAssignUsersTo.id, | |
userGroupIdsToRemove, | |
userIdsToAddToGroup, | |
}, | |
() => { | |
setIsEdit(false); | |
closeSlider(); | |
const userEmailsToAddToGroup = newUsersToAddToGroup.map( | |
(user: User) => user.email, | |
); | |
if (userEmailsToAddToGroup.length > 0) { | |
onSendNotification( | |
{ | |
templateName: 'UsersToGroupAssign', | |
toAddresses: JSON.stringify(userEmailsToAddToGroup), | |
data: JSON.stringify({ | |
groupNames: [groupToAssignUsersTo?.name], | |
}), | |
}, | |
() => { | |
console.log('Mail send'); | |
}, | |
); | |
} | |
}, | |
); | |
} else { | |
closeSlider(); | |
addToast( | |
`Successfully assigned users to group "${groupToAssignUsersTo.name}".`, | |
{ | |
appearance: 'success', | |
autoDismiss: true, | |
}, | |
); | |
} | |
}; | |
const searchBoxStyles: Partial<ISearchBoxStyles> = { | |
root: { width: '100%', borderColor: 'lightgray' }, | |
}; | |
// return ( | |
// <Slider isOpen={isSliderOpen} closeModal={closeSlider}> | |
// <form onSubmit={submit}> | |
// <Slider.Body> | |
// <Flex width="w-full" direction="col" padding="px-6" space="space-y-6"> | |
// <Flex margin="mb-4" direction="col"> | |
// <Text variant="xxLarge" className="my-4 mt-6 font-semibold"> | |
// Add User | |
// </Text> | |
// <Text variant="small"> | |
// Select upto 20 people to join this group, including the members | |
// and owners. You can add additional members to the group later | |
// </Text> | |
// </Flex> | |
// <SearchBox | |
// styles={searchBoxStyles} | |
// placeholder="Search for a name or email address" | |
// onEscape={(ev) => { | |
// console.log('Custom onEscape Called'); | |
// }} | |
// onClear={(ev) => { | |
// console.log('Custom onClear Called'); | |
// }} | |
// onChange={(_, newValue) => | |
// console.log(`SearchBox onChange fired: ${newValue}`) | |
// } | |
// onSearch={(newValue) => | |
// console.log(`SearchBox onSearch fired: ${newValue}`) | |
// } | |
// /> | |
// <div className="flex flex-col"> | |
// <Flex | |
// justify="between" | |
// border="border-b border-gray-300" | |
// className="mt-2 py-2" | |
// alignItems="center" | |
// > | |
// <div className="flex items-center"> | |
// {/* eslint-disable-next-line react/forbid-elements */} | |
// <input className={styles.checkboxRound} type="checkbox" /> | |
// {/* <input type="radio" className="mr-6 w-4 h-4" /> */} | |
// <label className="sm:inline font-light ml-2 ml-6"> | |
// Display Name | |
// </label> | |
// </div> | |
// <label className="sm:inline font-light">Teams Enabled</label> | |
// </Flex> | |
// <div className="flex flex-col overflow-hidden overflow-y-auto"> | |
// {users.map((user: CustomUser) => { | |
// return ( | |
// <div key={user.id}> | |
// {/* <Checkbox | |
// defaultChecked={user.checked} | |
// name="users" | |
// onChange={(e: any) => { | |
// if (e?.target?.value) { | |
// const currentUser = users.find( | |
// (usr) => usr.id === e.target.value, | |
// ); | |
// if (currentUser) { | |
// const remainingUsers = users.filter( | |
// (usr) => usr.id !== e.target.value, | |
// ); | |
// setUsers([ | |
// ...remainingUsers, | |
// { ...currentUser, checked: e.target.checked }, | |
// ]); | |
// } | |
// } | |
// }} | |
// inputProps={{ value: user.id }} | |
// label={`${user.firstName} ${user.lastName}`} | |
// /> */} | |
// <Flex | |
// alignItems="center" | |
// className="mt-2 mb-4 py-2" | |
// border="border-b border-gray-300" | |
// > | |
// {/* eslint-disable-next-line react/forbid-elements */} | |
// <input | |
// defaultChecked={user.checked} | |
// className={styles.checkboxRound} | |
// value={user.id} | |
// onChange={(e: any) => { | |
// if (e?.target?.value) { | |
// const currentUser = users.find( | |
// (usr) => usr.id === e.target.value, | |
// ); | |
// if (currentUser) { | |
// const remainingUsers = users.filter( | |
// (usr) => usr.id !== e.target.value, | |
// ); | |
// setUsers( | |
// sortList([ | |
// ...remainingUsers, | |
// { | |
// ...currentUser, | |
// checked: e.target.checked, | |
// }, | |
// ]), | |
// ); | |
// } | |
// } | |
// }} | |
// type="checkbox" | |
// /> | |
// <Flex alignItems="center" padding="px-8"> | |
// <div | |
// className={`flex flex-col justify-center w-14 h-11 rounded-full ${ | |
// user.firstName[0].toUpperCase() | |
// ? colors[user.firstName[0].toUpperCase()] | |
// : colors.A | |
// }`} | |
// > | |
// <span className="m-auto text-white text-sm font-semibold"> | |
// {`${user.firstName[0].toUpperCase()} ${user.lastName[0].toUpperCase()}`} | |
// </span> | |
// </div> | |
// <Flex direction="col" className="ml-4 py-2"> | |
// <Text className="text-gray-400 text-base"> | |
// {user.firstName} | |
// </Text> | |
// <Text variant="small" className="text-gray-400"> | |
// {user.lastName} | |
// </Text> | |
// </Flex> | |
// </Flex> | |
// </Flex> | |
// </div> | |
// ); | |
// })} | |
// </div> | |
// </div> | |
// </Flex> | |
// </Slider.Body> | |
// <Slider.ButtonPannel> | |
// <Flex | |
// // position="absolute" | |
// justify="start" | |
// className="bottom-0" | |
// // border="border-t" | |
// padding="py-5 px-4" | |
// space="space-x-5" | |
// // borderColor="border-gray-300" | |
// > | |
// {isCreateLoading || isUpdateLoading ? ( | |
// <PrimaryButton disabled text="Add" /> | |
// ) : ( | |
// <DefaultButton | |
// text="Add" | |
// type="submit" | |
// className="border-none bg-gray-100 text-gray-400 focus:outline-none" | |
// /> | |
// )} | |
// <DefaultButton | |
// onClick={() => { | |
// closeSlider(); | |
// reset(); | |
// }} | |
// className="border-none bg-gray-100 text-gray-400" | |
// text="Cancel" | |
// /> | |
// </Flex> | |
// </Slider.ButtonPannel> | |
// </form> | |
// </Slider> | |
// ); | |
const overflowButtonProps = { | |
ariaLabel: 'More users', | |
onClick: (ev: React.MouseEvent<HTMLButtonElement>) => | |
alert('overflow icon clicked'), | |
}; | |
const columns = [ | |
{ | |
key: 'displayName', | |
name: 'Display name', | |
fieldName: 'name', | |
minWidth: 100, | |
maxWidth: 200, | |
isResizable: true, | |
onRender: (userItem: CustomUser) => ( | |
<Persona | |
text={`${userItem.firstName} ${userItem.lastName}`} | |
secondaryText={`${userItem.email}`} | |
/> | |
), | |
// 'sds', | |
// <Flex alignItems="center" padding="px-8"> | |
// <Facepile | |
// personas={[ | |
// { personaName: `${userItem.firstName} ${userItem.lastName}` }, | |
// ]} | |
// maxDisplayablePersonas={1} | |
// ariaDescription="To move through the items use left and right arrow keys." | |
// ariaLabel="Example list of Facepile personas" | |
// /> | |
// <div | |
// className={`flex flex-col justify-center w-14 h-11 rounded-full ${ | |
// userItem.firstName[0].toUpperCase() | |
// ? colors[userItem.firstName[0].toUpperCase()] | |
// : colors.A | |
// }`} | |
// > | |
// <span className="m-auto text-white text-sm font-semibold"> | |
// {`${userItem.firstName[0].toUpperCase()} ${userItem.lastName[0].toUpperCase()}`} | |
// </span> | |
// </div> | |
// <Flex direction="col" className="ml-4 py-2"> | |
// <Text className="text-gray-400 text-base"> | |
// {userItem.firstName} | |
// </Text> | |
// <Text variant="small" className="text-gray-400"> | |
// {userItem.lastName} | |
// </Text> | |
// </Flex> | |
// </Flex> | |
}, | |
]; | |
const [selectionDetails, setSelectionDetails] = useState(); | |
const [fooSelection, fooSetSelection] = useState<Selection<IObjectWithKey>>(); | |
console.log( | |
'🚀 ~ file: ExperimentalPanel.tsx ~ line 511 ~ fooSelection', | |
fooSelection, | |
); | |
const selection = new Selection({ | |
// onSelectionChanged: () => { | |
// console.log('Fddfdfdf'); | |
// }, | |
}); | |
console.log( | |
'🚀 ~ file: ExperimentalPanel.tsx ~ line 508 ~ selection', | |
selection, | |
); | |
useConstructor(() => { | |
console.log( | |
'This only happens ONCE and it happens BEFORE the initial render.', | |
); | |
const barSelection = new Selection({ | |
// onSelectionChanged: () => { | |
// console.log('Fddfdfdf'); | |
// }, | |
}); | |
fooSetSelection(barSelection); | |
}); | |
const getSelectionDetails = () => { | |
const selectionCount = selection.getSelectedCount(); | |
console.log( | |
'🚀 ~ file: ExperimentalPanel.tsx ~ line 511 ~ getSelectionDetails ~ selectionCount', | |
selectionCount, | |
); | |
switch (selectionCount) { | |
case 0: | |
return 'No items selected'; | |
case 1: | |
return `1 item selected: ${ | |
(selection.getSelection()[0] as IDetailsListBasicExampleItem).name | |
}`; | |
default: | |
return `${selectionCount} items selected`; | |
} | |
}; | |
// console.log('object', getSelectionDetails()); | |
return ( | |
<Panel | |
isLightDismiss | |
isOpen={isOpen} | |
onDismiss={dismissPanel} | |
closeButtonAriaLabel="Close" | |
// headerText="Light dismiss panel" | |
isFooterAtBottom | |
onRenderFooterContent={() => { | |
return ( | |
<Flex | |
// position="absolute" | |
justify="start" | |
className="bottom-0" | |
// border="border-t" | |
padding="py-5 px-4" | |
space="space-x-5" | |
// borderColor="border-gray-300" | |
> | |
{isCreateLoading || isUpdateLoading ? ( | |
<PrimaryButton disabled text="Add" /> | |
) : ( | |
<DefaultButton | |
text={`Add (${selection.getSelectedCount()})`} | |
type="submit" | |
className="border-none bg-gray-100 text-gray-400 focus:outline-none" | |
/> | |
)} | |
<DefaultButton | |
onClick={() => { | |
closeSlider(); | |
reset(); | |
}} | |
className="border-none bg-gray-100 text-gray-400" | |
text="Cancel" | |
/> | |
</Flex> | |
); | |
}} | |
type={PanelType.medium} | |
> | |
<Flex width="w-full" direction="col" padding="px-6" space="space-y-6"> | |
<Flex margin="mb-4" direction="col"> | |
<Text variant="xxLarge" className="my-4 mt-6 font-semibold"> | |
Add User | |
</Text> | |
<Text variant="small"> | |
Select upto 20 people to join this group, including the members and | |
owners. You can add additional members to the group later | |
</Text> | |
</Flex> | |
<SearchBox | |
styles={searchBoxStyles} | |
placeholder="Search for a name or email address" | |
onEscape={(ev) => { | |
console.log('Custom onEscape Called'); | |
}} | |
onClear={(ev) => { | |
console.log('Custom onClear Called'); | |
}} | |
onChange={(_, newValue) => | |
console.log(`SearchBox onChange fired: ${newValue}`) | |
} | |
onSearch={(newValue) => | |
console.log(`SearchBox onSearch fired: ${newValue}`) | |
} | |
/> | |
<MarqueeSelection selection={selection}> | |
<DetailsList | |
items={users} | |
columns={columns} | |
setKey="set" | |
layoutMode={DetailsListLayoutMode.justified} | |
checkboxVisibility={CheckboxVisibility.always} | |
checkboxCellClassName="flex items-center" | |
selection={selection} | |
// selection={this._selection} | |
selectionPreservedOnEmptyClick | |
ariaLabelForSelectionColumn="Toggle selection" | |
ariaLabelForSelectAllCheckbox="Toggle selection for all items" | |
checkButtonAriaLabel="select row" | |
// onItemInvoked={this._onItemInvoked} | |
/> | |
</MarqueeSelection> | |
<div className="flex flex-col"> | |
<Flex | |
justify="between" | |
border="border-b border-gray-300" | |
className="mt-2 py-2" | |
alignItems="center" | |
> | |
<div className="flex items-center"> | |
{/* eslint-disable-next-line react/forbid-elements */} | |
<input className={styles.checkboxRound} type="checkbox" /> | |
{/* <input type="radio" className="mr-6 w-4 h-4" /> */} | |
<label className="sm:inline font-light ml-2 ml-6"> | |
Display Name | |
</label> | |
</div> | |
<label className="sm:inline font-light">Teams Enabled</label> | |
</Flex> | |
<div className="flex flex-col overflow-hidden overflow-y-auto"> | |
{users.map((user: CustomUser) => { | |
return ( | |
<div key={user.id}> | |
{/* <Checkbox | |
defaultChecked={user.checked} | |
name="users" | |
onChange={(e: any) => { | |
if (e?.target?.value) { | |
const currentUser = users.find( | |
(usr) => usr.id === e.target.value, | |
); | |
if (currentUser) { | |
const remainingUsers = users.filter( | |
(usr) => usr.id !== e.target.value, | |
); | |
setUsers([ | |
...remainingUsers, | |
{ ...currentUser, checked: e.target.checked }, | |
]); | |
} | |
} | |
}} | |
inputProps={{ value: user.id }} | |
label={`${user.firstName} ${user.lastName}`} | |
/> */} | |
<Flex | |
alignItems="center" | |
className="mt-2 mb-4 py-2" | |
border="border-b border-gray-300" | |
> | |
{/* eslint-disable-next-line react/forbid-elements */} | |
<input | |
defaultChecked={user.checked} | |
className={styles.checkboxRound} | |
value={user.id} | |
onChange={(e: any) => { | |
if (e?.target?.value) { | |
const currentUser = users.find( | |
(usr) => usr.id === e.target.value, | |
); | |
if (currentUser) { | |
const remainingUsers = users.filter( | |
(usr) => usr.id !== e.target.value, | |
); | |
setUsers( | |
sortList([ | |
...remainingUsers, | |
{ | |
...currentUser, | |
checked: e.target.checked, | |
}, | |
]), | |
); | |
} | |
} | |
}} | |
type="checkbox" | |
/> | |
<Flex alignItems="center" padding="px-8"> | |
<div | |
className={`flex flex-col justify-center w-14 h-11 rounded-full ${ | |
user.firstName[0].toUpperCase() | |
? colors[user.firstName[0].toUpperCase()] | |
: colors.A | |
}`} | |
> | |
<span className="m-auto text-white text-sm font-semibold"> | |
{`${user.firstName[0].toUpperCase()} ${user.lastName[0].toUpperCase()}`} | |
</span> | |
</div> | |
<Flex direction="col" className="ml-4 py-2"> | |
<Text className="text-gray-400 text-base"> | |
{user.firstName} | |
</Text> | |
<Text variant="small" className="text-gray-400"> | |
{user.lastName} | |
</Text> | |
</Flex> | |
</Flex> | |
</Flex> | |
</div> | |
); | |
})} | |
</div> | |
</div> | |
</Flex> | |
</Panel> | |
); | |
}; | |
export default AddUsersToGroupSlider; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment