Skip to content

Commit

Permalink
feat(dashoard): possibilité de filtrer par équipe dans les actions vi…
Browse files Browse the repository at this point in the history
…sibles via le dossier social de la personne suivie
  • Loading branch information
Arnaud AMBROSELLI committed Nov 6, 2023
1 parent eb95612 commit 3461ff1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 28 deletions.
4 changes: 1 addition & 3 deletions dashboard/src/scenes/action/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,7 @@ const List = () => {
<label htmlFor="action-select-categories-filter">Filtrer par équipe&nbsp;:</label>
<div className="tw-w-full">
<SelectTeamMultiple
onChange={(teamIds) => {
setSelectedTeamIds(teamIds);
}}
onChange={setSelectedTeamIds}
value={selectedTeamIds}
colored
isDisabled={viewAllOrganisationData || viewNoTeamData}
Expand Down
65 changes: 43 additions & 22 deletions dashboard/src/scenes/person/components/Actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ import { FullScreenIcon } from './FullScreenIcon';
import UserName from '../../../components/UserName';
import { itemsGroupedByPersonSelector } from '../../../recoil/selectors';
import DescriptionIcon from '../../../components/DescriptionIcon';
import SelectTeamMultiple from '../../../components/SelectTeamMultiple';

const filteredPersonActionsSelector = selectorFamily({
key: 'filteredPersonActionsSelector',
get:
({ personId, filterCategories, filterStatus }) =>
({ personId, filterCategories, filterStatus, filterTeamIds }) =>
({ get }) => {
const person = get(itemsGroupedByPersonSelector)[personId];
let actionsToSet = person?.actions || [];

if (filterCategories.length) {
actionsToSet = actionsToSet.filter((a) =>
filterCategories.some((c) => (c === '-- Aucune --' ? a.categories?.length === 0 : a.categories?.includes(c)))
Expand All @@ -31,6 +33,16 @@ const filteredPersonActionsSelector = selectorFamily({
if (filterStatus.length) {
actionsToSet = actionsToSet.filter((a) => filterStatus.some((s) => a.status === s));
}
if (filterTeamIds.length) {
actionsToSet = actionsToSet.filter((action) => {
if (Array.isArray(action.teams)) {
if (!filterTeamIds.some((t) => action.teams.includes(t))) return false;
} else {
if (!filterTeamIds.includes(action.team)) return false;
}
return true;
});
}
return [...actionsToSet]
.sort((p1, p2) => ((p1.completedAt || p1.dueAt) > (p2.completedAt || p2.dueAt) ? -1 : 1))
.map((a) => (a.urgent ? { ...a, style: { backgroundColor: '#fecaca99' } } : a));
Expand All @@ -42,11 +54,12 @@ export const Actions = ({ person }) => {
const [fullScreen, setFullScreen] = useState(false);
const [filterCategories, setFilterCategories] = useState([]);
const [filterStatus, setFilterStatus] = useState([]);
const filteredData = useRecoilValue(filteredPersonActionsSelector({ personId: person._id, filterCategories, filterStatus }));
const [filterTeamIds, setFilterTeamIds] = useState([]);
const filteredData = useRecoilValue(filteredPersonActionsSelector({ personId: person._id, filterCategories, filterStatus, filterTeamIds }));
const history = useHistory();

return (
<section title="Actions de la personne suivie" className="tw-relative">
<section title="Actions de la personne suivie" className="tw-relative tw-overflow-x-hidden">
<div className="tw-sticky tw-top-0 tw-z-10 tw-flex tw-bg-white tw-p-3 tw-shadow-sm">
<h4 className="tw-flex-1 tw-text-xl">Actions {filteredData.length ? `(${filteredData.length})` : ''}</h4>
<div className="flex-col tw-flex tw-items-center tw-gap-2">
Expand All @@ -73,22 +86,24 @@ export const Actions = ({ person }) => {
</div>
<ActionsFilters
data={data}
filteredData={filteredData}
filterCategories={filterCategories}
setFilterCategories={setFilterCategories}
filterCategories={filterCategories}
setFilterStatus={setFilterStatus}
filterStatus={filterStatus}
setFilterTeamIds={setFilterTeamIds}
filterTeamIds={filterTeamIds}
/>
<ModalContainer open={!!fullScreen} className="" size="prose" onClose={() => setFullScreen(false)}>
<ModalHeader title={`Actions de ${person?.name} (${filteredData.length})`}>
<div className="tw-mt-2 tw-w-full tw-max-w-2xl">
<ActionsFilters
data={data}
filteredData={filteredData}
filterCategories={filterCategories}
setFilterCategories={setFilterCategories}
filterCategories={filterCategories}
setFilterStatus={setFilterStatus}
filterStatus={filterStatus}
setFilterTeamIds={setFilterTeamIds}
filterTeamIds={filterTeamIds}
/>
</div>
</ModalHeader>
Expand Down Expand Up @@ -116,30 +131,36 @@ export const Actions = ({ person }) => {
);
};

const ActionsFilters = ({ data, filteredData, setFilterCategories, setFilterStatus, filterStatus, filterCategories }) => {
const ActionsFilters = ({ data, setFilterCategories, setFilterTeamIds, setFilterStatus, filterStatus, filterTeamIds, filterCategories }) => {
const categories = useRecoilValue(flattenedActionsCategoriesSelector);

const catsSelect = ['-- Aucune --', ...(categories || [])];

return (
<>
{data.length ? (
<div className="tw-mb-4 tw-flex tw-basis-full tw-justify-between tw-gap-2 tw-px-3">
<div className="tw-shrink-0 tw-flex-grow">
<div className="tw-mb-4 tw-flex tw-justify-between">
<div className="tw-shrink-0 tw-grow tw-basis-1/3 tw-pl-2 tw-pr-1">
<label htmlFor="action-select-categories-filter">Filtrer par catégorie</label>
<SelectCustom
options={catsSelect.map((_option) => ({ value: _option, label: _option }))}
value={filterCategories?.map((_option) => ({ value: _option, label: _option })) || []}
getOptionValue={(i) => i.value}
getOptionLabel={(i) => i.label}
onChange={(values) => setFilterCategories(values.map((v) => v.value))}
inputId="action-select-categories-filter"
name="categories"
isClearable
isMulti
/>
<div className="tw-max-w-full">
<SelectCustom
options={catsSelect.map((_option) => ({ value: _option, label: _option }))}
value={filterCategories?.map((_option) => ({ value: _option, label: _option })) || []}
getOptionValue={(i) => i.value}
getOptionLabel={(i) => i.label}
onChange={(values) => setFilterCategories(values.map((v) => v.value))}
inputId="action-select-categories-filter"
name="categories"
isClearable
isMulti
/>
</div>
</div>
<div className="tw-shrink-0 tw-grow tw-basis-1/3 tw-px-1">
<label htmlFor="action-select-categories-filter">Filtrer par équipe</label>
<SelectTeamMultiple onChange={(teamIds) => setFilterTeamIds(teamIds)} value={filterTeamIds} colored inputId="action-team-select" />
</div>
<div className="tw-shrink-0 tw-flex-grow">
<div className="tw-shrink-0 tw-grow tw-basis-1/3 tw-pl-1 tw-pr-2">
<label htmlFor="action-select-status-filter">Filtrer par statut</label>
<SelectCustom
inputId="action-select-status-filter"
Expand Down
6 changes: 3 additions & 3 deletions dashboard/src/scenes/person/components/SummaryPrint.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo } from 'react';
import React, { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { customFieldsPersonsSelector } from '../../../recoil/persons';
import { currentTeamAuthentifiedState, teamsState, userState, usersState } from '../../../recoil/auth';
Expand Down Expand Up @@ -62,7 +62,7 @@ export function SummaryPrint({ person }: { person: PersonPopulated }) {
{customFieldsPersons.map(({ name, fields }) => {
const enabledFields = fields.filter((f) => f.enabled || f.enabledTeams?.includes(team._id));
return (
<>
<React.Fragment key={name}>
<div className="tw-mx-0 tw-mt-16 tw-mb-5 tw-flex tw-items-center">
<h2 className="tw-flex tw-justify-between tw-text-xl tw-font-extrabold">{name}</h2>
</div>
Expand All @@ -75,7 +75,7 @@ export function SummaryPrint({ person }: { person: PersonPopulated }) {
);
})}
</div>
</>
</React.Fragment>
);
})}
<hr className="tw-my-8" />
Expand Down

1 comment on commit 3461ff1

@arnaudambro
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.