mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-02 22:52:21 +01:00
143 lines
5.0 KiB
TypeScript
143 lines
5.0 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import * as React from 'react';
|
|
import { Machine, MachineListFilter } from '../../models/machine';
|
|
import { IApplication } from '../../models/application';
|
|
import { react2angular } from 'react2angular';
|
|
import { Loader } from '../base/loader';
|
|
import MachineAPI from '../../api/machine';
|
|
import MachineCategoryAPI from '../../api/machine-category';
|
|
import { MachineCategory } from '../../models/machine-category';
|
|
import { MachineCard } from './machine-card';
|
|
import { MachinesFilters } from './machines-filters';
|
|
import { User } from '../../models/user';
|
|
import { EditorialBlock } from '../editorial-block/editorial-block';
|
|
import SettingAPI from '../../api/setting';
|
|
import SettingLib from '../../lib/setting';
|
|
import { SettingValue, machinesSettings } from '../../models/setting';
|
|
|
|
declare const Application: IApplication;
|
|
|
|
interface MachinesListProps {
|
|
user?: User,
|
|
onError: (message: string) => void,
|
|
onSuccess: (message: string) => void,
|
|
onShowMachine: (machine: Machine) => void,
|
|
onReserveMachine: (machine: Machine) => void,
|
|
onLoginRequested: () => Promise<User>,
|
|
onEnrollRequested: (trainingId: number) => void,
|
|
canProposePacks: boolean,
|
|
}
|
|
|
|
/**
|
|
* This component shows a list of all machines and allows filtering on that list.
|
|
*/
|
|
export const MachinesList: React.FC<MachinesListProps> = ({ onError, onSuccess, onShowMachine, onReserveMachine, onLoginRequested, onEnrollRequested, user, canProposePacks }) => {
|
|
// shown machines
|
|
const [machines, setMachines] = useState<Array<Machine>>(null);
|
|
// we keep the full list of machines, for filtering
|
|
const [allMachines, setAllMachines] = useState<Array<Machine>>(null);
|
|
// shown machine categories
|
|
const [machineCategories, setMachineCategories] = useState<Array<MachineCategory>>([]);
|
|
// machine list filter
|
|
const [filter, setFilter] = useState<MachineListFilter>({
|
|
status: true,
|
|
category: null
|
|
});
|
|
|
|
const [banner, setBanner] = useState<Record<string, SettingValue>>({});
|
|
|
|
// retrieve the full list of machines and the machines Banner on component mount
|
|
useEffect(() => {
|
|
MachineAPI.index()
|
|
.then(data => setAllMachines(data))
|
|
.catch(e => onError(e));
|
|
MachineCategoryAPI.index()
|
|
.then(data => setMachineCategories(data))
|
|
.catch(e => onError(e));
|
|
SettingAPI.query(machinesSettings)
|
|
.then(settings => {
|
|
setBanner({ ...SettingLib.bulkMapToObject(settings) });
|
|
})
|
|
.catch(onError);
|
|
}, []);
|
|
|
|
// filter the machines shown when the full list was retrieved
|
|
useEffect(() => {
|
|
handleFilter();
|
|
}, [allMachines]);
|
|
|
|
// filter the machines shown when the filter was changed
|
|
useEffect(() => {
|
|
handleFilter();
|
|
}, [filter]);
|
|
|
|
/**
|
|
* Callback triggered when the user changes the filter.
|
|
* filter the machines shown when the filter was changed.
|
|
*/
|
|
const handleFilter = (): void => {
|
|
let machinesFiltered = [];
|
|
if (allMachines) {
|
|
if (filter.status === null) {
|
|
machinesFiltered = allMachines;
|
|
} else {
|
|
// enabled machines may have the m.disabled property null (for never disabled machines)
|
|
// or false (for re-enabled machines)
|
|
machinesFiltered = allMachines.filter(m => !!m.disabled === !filter.status);
|
|
}
|
|
if (filter.category !== null) {
|
|
machinesFiltered = machinesFiltered.filter(m => m.machine_category_id === filter.category);
|
|
}
|
|
}
|
|
setMachines(machinesFiltered);
|
|
};
|
|
|
|
/**
|
|
* Callback triggered when the user changes the filter.
|
|
* @param type, status, category
|
|
* @param value, status and category value
|
|
*/
|
|
const handleFilterChangedBy = (type: string, value: number | boolean | void) => {
|
|
setFilter({
|
|
...filter,
|
|
[type]: value
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className="machines-list">
|
|
{banner.machines_banner_active &&
|
|
<EditorialBlock
|
|
text={banner.machines_banner_text}
|
|
cta={banner.machines_banner_cta_active && banner.machines_banner_cta_label}
|
|
url={banner.machines_banner_cta_active && banner.machines_banner_cta_url} />
|
|
}
|
|
<MachinesFilters onFilterChangedBy={handleFilterChangedBy} machineCategories={machineCategories}/>
|
|
<div className="all-machines">
|
|
{machines && machines.map(machine => {
|
|
return <MachineCard key={machine.id}
|
|
user={user}
|
|
machine={machine}
|
|
onShowMachine={onShowMachine}
|
|
onReserveMachine={onReserveMachine}
|
|
onError={onError}
|
|
onSuccess={onSuccess}
|
|
onLoginRequested={onLoginRequested}
|
|
onEnrollRequested={onEnrollRequested}
|
|
canProposePacks={canProposePacks}/>;
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const MachinesListWrapper: React.FC<MachinesListProps> = (props) => {
|
|
return (
|
|
<Loader>
|
|
<MachinesList {...props} />
|
|
</Loader>
|
|
);
|
|
};
|
|
|
|
Application.Components.component('machinesList', react2angular(MachinesListWrapper, ['user', 'onError', 'onSuccess', 'onShowMachine', 'onReserveMachine', 'onLoginRequested', 'onEnrollRequested', 'canProposePacks']));
|