[FIX] Units Edit and adds the option to hide own department in useDepartmentList

pull/22466/head
Martin 4 years ago
parent b4d7c66561
commit 68e83b8662
  1. 5
      client/components/AutoCompleteDepartment.js
  2. 51
      client/components/AutoCompleteDepartmentMultiple.js
  3. 27
      client/components/Omnichannel/hooks/useDepartmentsList.ts
  4. 2
      client/views/omnichannel/businessHours/EditBusinessHoursPage.js
  5. 2
      client/views/omnichannel/businessHours/NewBusinessHoursPage.js
  6. 8
      client/views/omnichannel/departments/EditDepartment.js
  7. 13
      ee/client/omnichannel/additionalForms/BusinessHoursMultiple.js
  8. 37
      ee/client/omnichannel/additionalForms/BusinessHoursMultipleContainer.js
  9. 51
      ee/client/omnichannel/additionalForms/DepartmentForwarding.js
  10. 2
      ee/client/omnichannel/units/UnitEdit.js

@ -5,7 +5,7 @@ import React, { memo, useMemo, useState } from 'react';
import { useTranslation } from '../contexts/TranslationContext';
import { useRecordList } from '../hooks/lists/useRecordList';
import { AsyncStatePhase } from '../hooks/useAsyncState';
import { useDepartmentsList } from '../views/hooks/useDepartmentsList';
import { useDepartmentsList } from './Omnichannel/hooks/useDepartmentsList';
const AutoCompleteDepartment = (props) => {
const { value, onlyMyDepartments = false, onChange = () => { } } = props;
@ -36,8 +36,9 @@ const AutoCompleteDepartment = (props) => {
setFilter={setDepartmentsFilter}
options={departmentsItems}
maxWidth='100%'
flexShrink={0}
flexGrow={0}
placeholder={t('Select_an_option')}
flexGrow={1}
endReached={
departmentsPhase === AsyncStatePhase.LOADING
? () => { }

@ -0,0 +1,51 @@
import { PaginatedMultiSelectFiltered } from '@rocket.chat/fuselage';
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import React, { memo, useMemo, useState } from 'react';
import { useTranslation } from '../contexts/TranslationContext';
import { useRecordList } from '../hooks/lists/useRecordList';
import { AsyncStatePhase } from '../hooks/useAsyncState';
import { useDepartmentsList } from './Omnichannel/hooks/useDepartmentsList';
const AutoCompleteDepartment = (props) => {
const { value, onlyMyDepartments = false, onChange = () => {} } = props;
const t = useTranslation();
const [departmentsFilter, setDepartmentsFilter] = useState('');
const debouncedDepartmentsFilter = useDebouncedValue(departmentsFilter, 500);
const { itemsList: departmentsList, loadMoreItems: loadMoreDepartments } = useDepartmentsList(
useMemo(() => ({ filter: debouncedDepartmentsFilter, onlyMyDepartments }), [
debouncedDepartmentsFilter,
onlyMyDepartments,
]),
);
const {
phase: departmentsPhase,
items: departmentsItems,
itemCount: departmentsTotal,
} = useRecordList(departmentsList);
return (
<PaginatedMultiSelectFiltered
value={value}
onChange={onChange}
filter={departmentsFilter}
setFilter={setDepartmentsFilter}
options={departmentsItems}
width='100%'
flexShrink={0}
flexGrow={0}
placeholder={t('Select_an_option')}
endReached={
departmentsPhase === AsyncStatePhase.LOADING
? () => {}
: (start) => loadMoreDepartments(start, Math.min(50, departmentsTotal))
}
/>
);
};
export default memo(AutoCompleteDepartment);

@ -8,6 +8,8 @@ import { RecordList } from '../../../lib/lists/RecordList';
type DepartmentsListOptions = {
filter: string;
departmentId?: string;
onlyMyDepartments?: boolean;
};
export const useDepartmentsList = (
@ -20,7 +22,9 @@ export const useDepartmentsList = (
} => {
const [itemsList, setItemsList] = useState(() => new RecordList<ILivechatDepartmentRecord>());
const reload = useCallback(() => setItemsList(new RecordList<ILivechatDepartmentRecord>()), []);
const endpoint = 'livechat/department';
const endpoint = `livechat/department${
options.onlyMyDepartments ? '?onlyMyDepartments=true' : ''
}` as 'livechat/department';
const getDepartments = useEndpoint('GET', endpoint);
@ -37,13 +41,20 @@ export const useDepartmentsList = (
});
return {
items: departments.map((department: any) => {
department._updatedAt = new Date(department._updatedAt);
department.label = department.name;
department.value = { value: department._id, label: department.name };
return department;
}),
itemCount: total,
items: departments
.filter((department) => {
if (options.departmentId && department._id === options.departmentId) {
return false;
}
return true;
})
.map((department: any) => {
department._updatedAt = new Date(department._updatedAt);
department.label = department.name;
department.value = { value: department._id, label: department.name };
return department;
}),
itemCount: options.departmentId ? total - 1 : total,
};
},
[getDepartments, options],

@ -55,7 +55,7 @@ const EditBusinessHoursPage = ({ id, type }) => {
const mappedForm = mapBusinessHoursForm(form, data.businessHour);
const departmentsToApplyBusinessHour = departments?.join(',') || '';
const departmentsToApplyBusinessHour = departments?.map((dep) => dep.value).join(',') || '';
try {
const payload = {

@ -60,7 +60,7 @@ const NewBusinessHoursPage = () => {
const mappedForm = mapBusinessHoursForm(form, defaultBusinessHour);
const departmentsToApplyBusinessHour = departments?.join(',') || '';
const departmentsToApplyBusinessHour = departments?.map((dep) => dep.value).join(',') || '';
try {
const payload = {

@ -80,7 +80,11 @@ function EditDepartment({ data, id, title, reload }) {
visitorInactivityTimeoutInSeconds:
(department && department.visitorInactivityTimeoutInSeconds) || undefined,
waitingQueueMessage: (department && department.waitingQueueMessage) || '',
departmentsAllowedToForward: (department && department.departmentsAllowedToForward) || [],
departmentsAllowedToForward:
(department &&
department.departmentsAllowedToForward &&
department.departmentsAllowedToForward.map((dep) => ({ label: dep, value: dep }))) ||
[],
});
const {
handleName,
@ -211,7 +215,7 @@ function EditDepartment({ data, id, title, reload }) {
abandonedRoomsCloseCustomMessage,
waitingQueueMessage,
departmentsAllowedToForward:
departmentsAllowedToForward && departmentsAllowedToForward.join(),
departmentsAllowedToForward && departmentsAllowedToForward.map((dep) => dep.label).join(),
};
const agentListPayload = {

@ -1,9 +1,10 @@
import { Field, TextInput, ToggleSwitch, MultiSelectFiltered, Box } from '@rocket.chat/fuselage';
import { Field, TextInput, ToggleSwitch, Box } from '@rocket.chat/fuselage';
import React from 'react';
import AutoCompleteDepartmentMultiple from '../../../../client/components/AutoCompleteDepartmentMultiple';
import { useTranslation } from '../../../../client/contexts/TranslationContext';
const BusinessHoursMultiple = ({ values = {}, handlers = {}, className, departmentList = [] }) => {
const BusinessHoursMultiple = ({ values = {}, handlers = {}, className }) => {
const t = useTranslation();
const { active, name, departments } = values;
@ -29,13 +30,7 @@ const BusinessHoursMultiple = ({ values = {}, handlers = {}, className, departme
<Field className={className}>
<Field.Label>{t('Departments')}</Field.Label>
<Field.Row>
<MultiSelectFiltered
options={departmentList}
value={departments}
onChange={handleDepartments}
maxWidth='100%'
placeholder={t('Departments')}
/>
<AutoCompleteDepartmentMultiple value={departments} onChange={handleDepartments} />
</Field.Row>
</Field>
</>

@ -1,12 +1,10 @@
import { Skeleton } from '@rocket.chat/fuselage';
import React, { useMemo } from 'react';
import React from 'react';
import { AsyncStatePhase } from '../../../../client/hooks/useAsyncState';
import { useEndpointData } from '../../../../client/hooks/useEndpointData';
import { useForm } from '../../../../client/hooks/useForm';
import BusinessHoursMultiple from './BusinessHoursMultiple';
const mapDepartments = (departments) => departments.map(({ _id }) => _id);
const mapDepartments = (departments) =>
departments.map(({ _id, name }) => ({ value: _id, label: name }));
const getInitialData = (data = {}) => ({
active: data.active ?? true,
@ -20,11 +18,6 @@ const BusinessHoursMultipleContainer = ({
className,
hasChangesAndIsValid = () => {},
}) => {
const onlyMyDepartments = true;
const params = useMemo(() => ({ onlyMyDepartments }), [onlyMyDepartments]);
const { value: data, phase: state } = useEndpointData('livechat/department', params);
const { values, handlers, hasUnsavedChanges } = useForm(getInitialData(initialData));
const { name } = values;
@ -32,29 +25,7 @@ const BusinessHoursMultipleContainer = ({
onChange(values);
hasChangesAndIsValid(hasUnsavedChanges && !!name);
const departmentList = useMemo(
() => data && data.departments?.map(({ _id, name }) => [_id, name]),
[data],
);
if (state === AsyncStatePhase.LOADING) {
return (
<>
<Skeleton />
<Skeleton />
<Skeleton />
</>
);
}
return (
<BusinessHoursMultiple
values={values}
handlers={handlers}
departmentList={departmentList}
className={className}
/>
);
return <BusinessHoursMultiple values={values} handlers={handlers} className={className} />;
};
export default BusinessHoursMultipleContainer;

@ -1,38 +1,47 @@
import { Field, MultiSelectFiltered, Box } from '@rocket.chat/fuselage';
import React, { useMemo } from 'react';
import { Field, Box, PaginatedMultiSelectFiltered } from '@rocket.chat/fuselage';
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import React, { useMemo, useState } from 'react';
import { useDepartmentsList } from '../../../../client/components/Omnichannel/hooks/useDepartmentsList';
import { useTranslation } from '../../../../client/contexts/TranslationContext';
import { useEndpointData } from '../../../../client/hooks/useEndpointData';
import { useRecordList } from '../../../../client/hooks/lists/useRecordList';
import { AsyncStatePhase } from '../../../../client/hooks/useAsyncState';
const param = { onlyMyDepartments: true };
export const DepartmentForwarding = ({ departmentId, value, handler, label, placeholder }) => {
export const DepartmentForwarding = ({ departmentId, value, handler, label }) => {
const t = useTranslation();
const { value: data } = useEndpointData('livechat/department', param);
const [departmentsFilter, setDepartmentsFilter] = useState('');
const options = useMemo(
() =>
(data && [
...data.departments
.filter((department) => department._id !== departmentId)
.map((department) => [department._id, department.name]),
]) ||
[],
[data, departmentId],
const debouncedDepartmentsFilter = useDebouncedValue(departmentsFilter, 500);
const { itemsList: departmentsList, loadMoreItems: loadMoreDepartments } = useDepartmentsList(
useMemo(() => ({ filter: departmentsFilter, departmentId }), [departmentId, departmentsFilter]),
);
const {
phase: departmentsPhase,
items: departmentsItems,
itemCount: departmentsTotal,
} = useRecordList(departmentsList);
return (
<Field>
<Field.Label>{t(label)}</Field.Label>
<Field.Row>
<Box w='100%'>
<MultiSelectFiltered
<PaginatedMultiSelectFiltered
maxWidth='100%'
w='100%'
value={value}
options={options}
onChange={handler}
disabled={!options}
placeholder={t(placeholder)}
flexGrow={1}
filter={debouncedDepartmentsFilter}
setFilter={setDepartmentsFilter}
onChange={handler}
options={departmentsItems}
value={value}
endReached={
departmentsPhase === AsyncStatePhase.LOADING
? () => {}
: (start) => loadMoreDepartments(start, Math.min(50, departmentsTotal))
}
/>
</Box>
</Field.Row>

@ -8,7 +8,7 @@ import {
Icon,
FieldGroup,
} from '@rocket.chat/fuselage';
import { useDebouncedValue, useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useMutableCallback, useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import React, { useMemo, useState } from 'react';
import Page from '../../../../client/components/Page';

Loading…
Cancel
Save