1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-20 14:54:15 +01:00

allow user to filter plans by groups

This commit is contained in:
Sylvain 2021-06-10 12:52:14 +02:00
parent 854db568bf
commit 4580bfc7d7
6 changed files with 83 additions and 3 deletions

View File

@ -8,7 +8,7 @@ export const Loader: React.FC = ({children }) => {
<div className="fa-3x">
<i className="fas fa-circle-notch fa-spin" />
</div>
);// compile
);
return (
<Suspense fallback={loading}>
{children}

View File

@ -0,0 +1,49 @@
import React from 'react';
import Select from 'react-select';
import { useTranslation } from 'react-i18next';
import { Group } from '../../models/group';
import { User } from '../../models/user';
interface PlansFilterProps {
user?: User,
groups: Array<Group>,
onGroupSelected: (groupId: number) => void,
}
/**
* Option format, expected by react-select
* @see https://github.com/JedWatson/react-select
*/
type selectOption = { value: number, label: string };
export const PlansFilter: React.FC<PlansFilterProps> = ({ user, groups, onGroupSelected }) => {
const { t } = useTranslation('public');
/**
* Convert all groups to the react-select format
*/
const buildGroupOptions = (): Array<selectOption> => {
return groups.filter(g => !g.disabled && g.slug !== 'admins').map(g => {
return { value: g.id, label: g.name }
});
}
/**
* Callback triggered when the user select a group in the dropdown list
*/
const handleGroupSelected = (option: selectOption): void => {
onGroupSelected(option.value);
}
return (
<div className="plans-filter">
{!user && <div className="group-filter">
<label htmlFor="group">{t('app.public.plans_filter.i_am')}</label>
<Select placeholder={t('app.public.plans_filter.select_group')}
className="group-select"
onChange={handleGroupSelected}
options={buildGroupOptions()}/>
</div>}
</div>
)
}

View File

@ -12,6 +12,7 @@ import { Loader } from '../base/loader';
import { react2angular } from 'react2angular';
import { IApplication } from '../../models/application';
import { useTranslation } from 'react-i18next';
import { PlansFilter } from './plans-filter';
declare var Application: IApplication;
@ -41,6 +42,8 @@ const PlansList: React.FC<PlansListProps> = ({ onError, onPlanSelection, onLogin
const [groups, setGroups] = useState<Array<Group>>(null);
// currently selected plan
const [selectedPlan, setSelectedPlan] = useState<Plan>(null);
// filter shown plans by only one group
const [groupFilter, setGroupFilter] = useState<number>(null);
// fetch data on component mounted
useEffect(() => {
@ -60,6 +63,7 @@ const PlansList: React.FC<PlansListProps> = ({ onError, onPlanSelection, onLogin
// reset the selected plan when the user changes
useEffect(() => {
setSelectedPlan(null);
setGroupFilter(null);
}, [customer, operator]);
/**
@ -96,10 +100,11 @@ const PlansList: React.FC<PlansListProps> = ({ onError, onPlanSelection, onLogin
}
/**
* Filter the plans to display, depending on the connected/selected user
* Filter the plans to display, depending on the connected/selected user and on the selected group filter (if any)
*/
const filteredPlans = (): PlansTree => {
if (_.isEmpty(customer)) return plans;
if (_.isEmpty(customer) && !groupFilter) return plans;
if (groupFilter) return new Map([[groupFilter, plans.get(groupFilter)]]);
return new Map([[customer.group_id, plans.get(customer.group_id)]]);
}
@ -154,6 +159,13 @@ const PlansList: React.FC<PlansListProps> = ({ onError, onPlanSelection, onLogin
onPlanSelection(plan);
}
/**
* Callback triggered when the user select a group to filter the current list
*/
const handleFilterByGroup = (groupId: number): void => {
setGroupFilter(groupId);
}
/**
* Render the provided list of categories, with each associated plans
*/
@ -197,6 +209,7 @@ const PlansList: React.FC<PlansListProps> = ({ onError, onPlanSelection, onLogin
return (
<div className="plans-list">
{groups && <PlansFilter user={customer} groups={groups} onGroupSelected={handleFilterByGroup} />}
{plans && Array.from(filteredPlans()).map(([groupId, plansByGroup]) => {
return (
<div key={groupId} className="plans-per-group">

View File

@ -49,5 +49,6 @@
@import "modules/create-plan-category";
@import "modules/edit-plan-category";
@import "modules/delete-plan-category";
@import "modules/plans-filter";
@import "app.responsive";

View File

@ -0,0 +1,14 @@
.plans-filter {
margin: 1.5em;
.group-filter {
& > * {
display: inline-block;
}
.group-select {
min-width: 40%;
margin-left: 10px;
}
}
}

View File

@ -259,6 +259,9 @@ en:
the_user_s_group_was_successfully_changed: "The user's group was successfully changed."
an_error_prevented_your_group_from_being_changed: "An error prevented your group from being changed."
an_error_prevented_to_change_the_user_s_group: "An error prevented to change the user's group."
plans_filter:
i_am: "I am"
select_group: "select a group"
#Fablab's events list
events_list:
the_fablab_s_events: "The Fablab's events"