mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-30 19:52:20 +01:00
filter machines by status
This commit is contained in:
parent
80d206fc99
commit
4aa3fdff0e
@ -16,6 +16,21 @@ interface MachineCardProps {
|
|||||||
const MachineCardComponent: React.FC<MachineCardProps> = ({ machine, onShowMachine, onReserveMachine }) => {
|
const MachineCardComponent: React.FC<MachineCardProps> = ({ machine, onShowMachine, onReserveMachine }) => {
|
||||||
const { t } = useTranslation('public');
|
const { t } = useTranslation('public');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback triggered when the user clicks on the 'reserve' button.
|
||||||
|
* We handle the training verification process here, before redirecting the user to the reservation calendar.
|
||||||
|
*/
|
||||||
|
const handleReserveMachine = (): void => {
|
||||||
|
onReserveMachine(machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback triggered when the user clicks on the 'view' button
|
||||||
|
*/
|
||||||
|
const handleShowMachine = (): void => {
|
||||||
|
onShowMachine(machine);
|
||||||
|
}
|
||||||
|
|
||||||
const machinePicture = (): ReactNode => {
|
const machinePicture = (): ReactNode => {
|
||||||
if (!machine.machine_image) {
|
if (!machine.machine_image) {
|
||||||
return (
|
return (
|
||||||
@ -33,13 +48,6 @@ const MachineCardComponent: React.FC<MachineCardProps> = ({ machine, onShowMachi
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleReserveMachine = (): void => {
|
|
||||||
onReserveMachine(machine);
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleShowMachine = (): void => {
|
|
||||||
onShowMachine(machine);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<div className="machine-card">
|
<div className="machine-card">
|
||||||
{machinePicture()}
|
{machinePicture()}
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Select from 'react-select';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
interface MachinesFiltersProps {
|
||||||
|
onStatusSelected: (enabled: boolean) => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option format, expected by react-select
|
||||||
|
* @see https://github.com/JedWatson/react-select
|
||||||
|
*/
|
||||||
|
type selectOption = { value: boolean, label: string };
|
||||||
|
|
||||||
|
export const MachinesFilters: React.FC<MachinesFiltersProps> = ({ onStatusSelected }) => {
|
||||||
|
const { t } = useTranslation('public');
|
||||||
|
|
||||||
|
const defaultValue = { value: true, label: t('app.public.machines_filters.status_enabled') };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides boolean options in the react-select format (yes/no/all)
|
||||||
|
*/
|
||||||
|
const buildBooleanOptions = (): Array<selectOption> => {
|
||||||
|
return [
|
||||||
|
defaultValue,
|
||||||
|
{ value: false, label: t('app.public.machines_filters.status_disabled') },
|
||||||
|
{ value: null, label: t('app.public.machines_filters.status_all') },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback triggered when the user selects a machine status in the dropdown list
|
||||||
|
*/
|
||||||
|
const handleStatusSelected = (option: selectOption): void => {
|
||||||
|
onStatusSelected(option.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="machines-filters">
|
||||||
|
<div className="status-filter">
|
||||||
|
<label htmlFor="status">{t('app.public.machines_filters.show_machines')}</label>
|
||||||
|
<Select defaultValue={defaultValue}
|
||||||
|
id="status"
|
||||||
|
className="status-select"
|
||||||
|
onChange={handleStatusSelected}
|
||||||
|
options={buildBooleanOptions()}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -5,6 +5,7 @@ import { react2angular } from 'react2angular';
|
|||||||
import { Loader } from '../base/loader';
|
import { Loader } from '../base/loader';
|
||||||
import MachineAPI from '../../api/machine';
|
import MachineAPI from '../../api/machine';
|
||||||
import { MachineCard } from './machine-card';
|
import { MachineCard } from './machine-card';
|
||||||
|
import { MachinesFilters } from './machines-filters';
|
||||||
|
|
||||||
declare var Application: IApplication;
|
declare var Application: IApplication;
|
||||||
|
|
||||||
@ -18,19 +19,42 @@ interface MachinesListProps {
|
|||||||
* This component shows a list of all machines and allows filtering on that list.
|
* This component shows a list of all machines and allows filtering on that list.
|
||||||
*/
|
*/
|
||||||
const MachinesList: React.FC<MachinesListProps> = ({ onError, onShowMachine, onReserveMachine }) => {
|
const MachinesList: React.FC<MachinesListProps> = ({ onError, onShowMachine, onReserveMachine }) => {
|
||||||
|
// shown machines
|
||||||
const [machines, setMachines] = useState<Array<Machine>>(null);
|
const [machines, setMachines] = useState<Array<Machine>>(null);
|
||||||
|
// we keep the full list of machines, for filtering
|
||||||
|
const [allMachines, setAllMachines] = useState<Array<Machine>>(null);
|
||||||
|
|
||||||
|
// retrieve the full list of machines on component mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
MachineAPI.index()
|
MachineAPI.index()
|
||||||
.then(data => setMachines(data))
|
.then(data => setAllMachines(data))
|
||||||
.catch(e => onError(e));
|
.catch(e => onError(e));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// filter the machines shown when the full list was retrieved
|
||||||
|
useEffect(() => {
|
||||||
|
handleFilterByStatus(true);
|
||||||
|
}, [allMachines])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback triggered when the user changes the status filter.
|
||||||
|
* Set the 'machines' state to a filtered list, depending on the provided parameter.
|
||||||
|
*/
|
||||||
|
const handleFilterByStatus = (status: boolean): void => {
|
||||||
|
if (!allMachines) return;
|
||||||
|
if (status === null) return setMachines(allMachines);
|
||||||
|
|
||||||
|
setMachines(allMachines.filter(m => m.disabled === !status));
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="machines-list">
|
<div className="machines-list">
|
||||||
{machines && machines.map(machine => {
|
<MachinesFilters onStatusSelected={handleFilterByStatus} />
|
||||||
return <MachineCard key={machine.id} machine={machine} onShowMachine={onShowMachine} onReserveMachine={onReserveMachine} />
|
<div className="all-machines">
|
||||||
})}
|
{machines && machines.map(machine => {
|
||||||
|
return <MachineCard key={machine.id} machine={machine} onShowMachine={onShowMachine} onReserveMachine={onReserveMachine} />
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -52,5 +52,6 @@
|
|||||||
@import "modules/plan-categories/delete-plan-category";
|
@import "modules/plan-categories/delete-plan-category";
|
||||||
@import "modules/machines/machine-card";
|
@import "modules/machines/machine-card";
|
||||||
@import "modules/machines/machines-list";
|
@import "modules/machines/machines-list";
|
||||||
|
@import "modules/machines/machines-filters";
|
||||||
|
|
||||||
@import "app.responsive";
|
@import "app.responsive";
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
.machines-filters {
|
||||||
|
margin: 1.5em;
|
||||||
|
|
||||||
|
.status-filter {
|
||||||
|
& {
|
||||||
|
display: inline-flex;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
& > label {
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
& > * {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.status-select {
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 720px){
|
||||||
|
.machines-filters {
|
||||||
|
.status-filter {
|
||||||
|
padding-right: 0;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
.machines-list {
|
.machines-list {
|
||||||
display: flex;
|
.all-machines {
|
||||||
flex-wrap: wrap;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,6 +210,8 @@ en:
|
|||||||
new_availability: "Open reservations"
|
new_availability: "Open reservations"
|
||||||
book: "Book"
|
book: "Book"
|
||||||
_or_the_: " or the "
|
_or_the_: " or the "
|
||||||
|
machines_filters:
|
||||||
|
show_machines: "Show machines"
|
||||||
status_enabled: "Enabled"
|
status_enabled: "Enabled"
|
||||||
status_disabled: "Disabled"
|
status_disabled: "Disabled"
|
||||||
status_all: "All"
|
status_all: "All"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user