UNPKG

@plone/volto

Version:
222 lines (207 loc) 7.45 kB
import React, { useEffect, useState, useMemo } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useIntl } from 'react-intl'; import { Checkbox, Form, Input } from 'semantic-ui-react'; import isEqual from 'lodash/isEqual'; import debounce from 'lodash/debounce'; import { messages } from '@plone/volto/helpers/MessageLabels/MessageLabels'; import { listGroups } from '@plone/volto/actions/groups/groups'; // getRegistry import UserGroupMembershipListing from '@plone/volto/components/manage/Controlpanels/Users/UserGroupMembershipListing'; const UserGroupMembershipMatrix = ({ many_users, many_groups }) => { const intl = useIntl(); const dispatch = useDispatch(); const [query_user, setQuery_user] = useState(''); // Show users matching the search string const [query_group, setQuery_group] = useState(''); // Show groups matching the search string const [query_group_filter, setQuery_group_filter] = useState(''); // Offer groups matching the search string to filter users const [groups_filter, setGroups_filter] = useState([]); // Show users joining these groups. const [add_joined_groups, setAdd_joined_groups] = useState(false); let filter_options = useSelector((state) => state.groups.filter_groups); if (filter_options) { filter_options = filter_options.map((group) => ({ value: group.id, label: group.title || group.id, })); filter_options.sort(function (a, b) { var labelA = a.label.toUpperCase(); var labelB = b.label.toUpperCase(); if (labelA < labelB) { return -1; } if (labelA > labelB) { return 1; } return 0; }); } const debouncedListGroups = useMemo( () => debounce((query_group_filter) => { dispatch(listGroups('', query_group_filter)); }, 300), [dispatch], ); useEffect(() => { // TODO fetch group for at least query_group_filter.length > 1? if (!many_groups || (many_groups && query_group_filter.length > 1)) { debouncedListGroups(query_group_filter); } }, [debouncedListGroups, many_groups, query_group_filter]); const onReset = (event) => { // event.preventDefault(); let element = event.target.querySelector('input'); element.value = ''; element.focus(); let searchtype = element.name; switch (searchtype) { case 'SearchUser': setQuery_user(''); break; case 'SearchGroup': setQuery_group(''); break; case 'SearchGroupFilter': setQuery_group_filter(''); setGroups_filter([]); break; default: break; } }; const onChangeSearchUsers = (event) => { if (many_users || many_groups) { // search only on hitting return key if (event.keyCode === 13) { setQuery_user(event.target.value); event.preventDefault(); } } else { setQuery_user(event.target.value); } }; const onChangeSearchGroups = (event) => { if (many_users || many_groups) { // search only on hitting return key if (event.keyCode === 13) { setQuery_group(event.target.value); event.preventDefault(); } } else { setQuery_group(event.target.value); } }; const onSelectOptionHandler = (filter_option, checked) => { let groups_filter_set_new = []; if (checked) { groups_filter_set_new = new Set([...groups_filter, filter_option]); } else { groups_filter_set_new = groups_filter.filter( (el) => el.value !== filter_option.value, ); } if (!isEqual(groups_filter_set_new, new Set(groups_filter))) { setGroups_filter([...groups_filter_set_new]); } }; const onToggleJoinedGroups = (checked) => { setAdd_joined_groups(checked); }; const onChangeSearchGroupsFilter = (event) => { if (many_users || many_groups) { // search only on hitting return key if (event.keyCode === 13) { setQuery_group_filter(event.target.value); event.preventDefault(); } } else { setQuery_group_filter(event.target.value); } }; return ( <div className="controlpanel_matrix"> <div className="controlpanel_search_wrapper"> <div className="controlpanel_search_y"> <Form className="search_users" onSubmit={onReset}> <Form.Field> <Input name="SearchUser" action={{ icon: 'delete' }} placeholder={intl.formatMessage(messages.searchUsers)} onChange={onChangeSearchUsers} onKeyDown={onChangeSearchUsers} id="user-search-input" /> </Form.Field> </Form> </div> <div className="controlpanel_search_x"> <Form className="search_groups" onSubmit={onReset}> <Form.Field> <Input name="SearchGroup" action={{ icon: 'delete' }} placeholder={intl.formatMessage(messages.searchGroups)} onChange={onChangeSearchGroups} onKeyDown={onChangeSearchGroups} id="group-search-input" /> </Form.Field> <Form.Field> <Checkbox name="addJoinedGroups" label={intl.formatMessage(messages.addJoinedGroups)} title={intl.formatMessage(messages.addJoinedGroups)} defaultChecked={false} onChange={(event, { checked }) => { onToggleJoinedGroups(checked); }} /> </Form.Field> </Form> </div> </div> <div className="controlpanel_listing_wrapper"> <div className="controlpanel_filter"> <h3>{intl.formatMessage(messages.filterByGroups)}</h3> <Form className="search_filter_groups" onSubmit={onReset}> <Form.Field> <Input name="SearchGroupFilter" action={{ icon: 'delete' }} placeholder={intl.formatMessage(messages.searchGroups)} onChange={onChangeSearchGroupsFilter} onKeyDown={onChangeSearchGroupsFilter} id="groupfilter-search-input" /> </Form.Field> </Form> {(!many_groups || query_group_filter.length > 1) && filter_options?.map((filter_option) => ( <React.Fragment key={filter_option.value}> <Form.Field> <Checkbox name={`filter_option_${filter_option.value}`} key={filter_option.value} title={filter_option.label} label={filter_option.label} defaultChecked={false} onChange={(event, { checked }) => { onSelectOptionHandler(filter_option, checked); }} /> </Form.Field> </React.Fragment> ))} </div> <UserGroupMembershipListing query_user={query_user} query_group={query_group} groups_filter={groups_filter} add_joined_groups={add_joined_groups} many_users={many_users} many_groups={many_groups} /> </div> </div> ); }; export default UserGroupMembershipMatrix;