️ This Gitlab will be shut down at 2021-12-31 23:59:59.
Students and staff can migrate to gitlab.utwente.nl.
SNT members can migrate to gitlab.snt.utwente.nl.
Contact bestuur@snt.utwente.nl for more information.

Migrate your projects today!
Export your project using the webinterface or use a script.

Commit 8ea3f0a7 authored by TJHeeringa's avatar TJHeeringa

Updated matchings

parent 4a1f0c55
......@@ -18,10 +18,14 @@ import useCollectionAPI from "../../Components/Hooks/useCollectionAPI";
import Block from "../../Components/PageLayout/Content/Block";
import MemberTable from "../../Components/Tables/MemberTable";
import {useAPI} from "../../Contexts/API";
import {useDataFields} from "../../Contexts/Members";
import {useDataFields, useMembers, useMemberTypes} from "../../Contexts/Members";
import ConfirmationModal from "../../Components/Modals/ConfirmationModal";
import Wrapper from "../../Components/Fields/Wrapper";
import {deriveMemberTableHeadersFromDataFields, flattenMembers} from "../../Transformers/Members";
import {useStudies} from "../../Contexts/Studies";
import {ToolbarButton} from "../../Components/Tables/Plugins/ToolbarButton";
import RefreshIcon from "@material-ui/icons/Refresh";
import DeleteIcon from '@material-ui/icons/Delete';
const useStyles = makeStyles(theme => ({
wrapper: {
......@@ -49,22 +53,45 @@ const useStyles = makeStyles(theme => ({
}
}));
// function to help add the "left_" and "right_" to keys
const prependKeys = (prefactor, obj) =>
Object.keys(obj).reduce(
(acc, key) => ({
...acc,
...{ [prefactor+key]: obj[key] }
}),
{}
);
const Matchings = ({ association }) => {
const classes = useStyles();
const alertHandler = useAlertHandler();
const API = useAPI();
const DataFieldsApi = useDataFields();
const MatchesAPI = useCollectionAPI("/matchings",
{limit: 10000, current: true, association__slug: association.slug}
);
const matches = MatchesAPI.list() || [];
const MembersApi = useMembers();
const MemberTypesApi = useMemberTypes();
const MatchesAPI = useCollectionAPI("/matchings", {limit: 10000, current: true, association__slug: association.slug});
const StudyApi = useStudies();
useEffect(()=>{
if (!MembersApi.loaded) {
MembersApi.refresh();
}
}, [MembersApi.loaded]);
const matches = MatchesAPI.collection;
const setMatches = MatchesAPI.set;
const member_types = MemberTypesApi.collection;
const members = MembersApi.collection;
const studies = StudyApi.collection;
const [confirmationModal, setConfirmationModal] = useState(false);
const [show, setShowMatches] = useState(true);
const [selectedLeft, setLeft] = useState([]);
const [selectedRight, setRight] = useState([]);
const [selection, setSelection] = useState([]);
const toggleShowMatches = () => setShowMatches(prevState => !prevState);
......@@ -236,6 +263,103 @@ const Matchings = ({ association }) => {
"have an email informing them. Do you want to sent them an email now?";
const allowEmailModal = numberOfMatchesStillNeededToBeEmailed > 0;
// TODO:
// 1. map left_profile, right_profile to membership
// 2. compute proper headers (left_... and right_...).
// 3. Put that into table
// 4. add delete button
// first flatten the member, since otherwise they don't fit nicely inside a single table
const rows = useMemo(()=> {
if (members.length === 0) {
return [];
}
const flatttened_members = flattenMembers(members, studies);
console.log(members, flatttened_members, matches);
return matches.map(match=>({
...prependKeys("left_", flatttened_members.find(member=>member.urls.profile === match.left_profile)),
...prependKeys("right_", flatttened_members.find(member=>member.urls.profile === match.right_profile)),
slug: match.slug,
email_send: match.email_send
}));
}, [matches.length, members, studies]);
const headers = useMemo(()=>{
const base_headers = deriveMemberTableHeadersFromDataFields(data_fields);
const left_headers = base_headers.map(({name: name, title: title}) => ({name: "left_"+name, title: "Left "+title}));
const right_headers = base_headers.map(({name: name, title: title}) => ({name: "right_"+name, title: "Right "+title}));
return left_headers.concat(right_headers).concat({name: "email_send", title: "Got email"});
}, [data_fields]);
const defaultHiddenColumnNames = useMemo(()=>{
const base_headers = ["given_name", "surname", "email", "type"].concat(data_fields.map(field=>field.name));
const left_headers = base_headers.map(header=>"left_"+header);
const right_headers = base_headers.map(header=>"right_"+header);
const visible_headers = left_headers.concat(right_headers).concat("email_send");
return headers
.map(header=>header.name)
.filter(header_name => !visible_headers.includes(header_name));
}, [headers]);
const booleanColumns = useMemo(()=>{
const base_columns = data_fields.filter(field=>field.type === "Boolean").map(field=>field.name);
const left_columns = base_columns.map(header=>"left_"+header);
const right_columns = base_columns.map(header=>"right_"+header);
return left_columns.concat(right_columns).concat("email_send");
}, [data_fields]);
const numberColumns = useMemo(()=>{
const base_columns = data_fields.filter(field=>field.type === "Number").map(field=>field.name);
const left_columns = base_columns.map(header=>"left_"+header);
const right_columns = base_columns.map(header=>"right_"+header);
return left_columns.concat(right_columns);
}, [data_fields]);
const choiceColumns = useMemo(()=>{
const base_columns = data_fields.filter(field=>field.type === "Choice").map(field=>field.name).concat(["phase", "type", "new_type"]);
const left_columns = base_columns.map(header=>"left_"+header);
const right_columns = base_columns.map(header=>"right_"+header);
return left_columns.concat(right_columns);
}, [data_fields]);
const choiceSelectionOptions = useMemo(()=>({
"left_phase": ["PhD", "Master", "Premaster", "Bachelor", "Other"],
"left_type": member_types.map(member_type=>member_type.type),
"left_new_type": member_types.map(member_type=>member_type.type),
"right_phase": ["PhD", "Master", "Premaster", "Bachelor", "Other"],
"right_type": member_types.map(member_type=>member_type.type),
"right_new_type": member_types.map(member_type=>member_type.type),
...Object.fromEntries(data_fields.map(field=>["left_"+field.name, field.choices.split(",")])),
...Object.fromEntries(data_fields.map(field=>["right_"+field.name, field.choices.split(",")]))
}), [member_types, data_fields]);
const currencyColumns = useMemo(()=>{
const base_columns = ["membership_fee"];
const left_columns = base_columns.map(header=>"left_"+header);
const right_columns = base_columns.map(header=>"right_"+header);
return left_columns.concat(right_columns);
}, [headers]);
const dateColumns = useMemo(()=>{
const base_columns = ["date_of_birth", "date_joined", "date_left"];
const left_columns = base_columns.map(header=>"left_"+header);
const right_columns = base_columns.map(header=>"right_"+header);
return left_columns.concat(right_columns);
}, [headers]);
const onRefresh = () => MatchesAPI.refresh();
const onRemove = () => {
API.callv4({
url: "/matchings",
queryParams: {slug__in: selection, association__slug: association.slug},
method: "DELETE",
headers: {"X-BULK-OPERATION": true},
on_succes: ()=>{
alertHandler.handleAlertHandler("green", "Succesfully deleted " + selection.length + " matches.");
setMatches(matches.filter(match=>!selection.includes(match.slug)));
},
on_failure: ()=> {
alertHandler.handleAlertHandler("red", "Deletion of match(es) failed.");
}
});
};
const custom_miscelaneous_plugins = [
<ToolbarButton key={1} tooltip={"Reload table"} Icon={RefreshIcon} onClick={onRefresh}/>,
<ToolbarButton key={2} tooltip={"Remove selected"} Icon={DeleteIcon} onClick={onRemove}/>,
];
return (
<React.Fragment>
<ConfirmationModal
......@@ -245,6 +369,35 @@ const Matchings = ({ association }) => {
onConfirm={sentEmails}
open={confirmationModal}
/>
<Block>
<Wrapper>
<Typography variant={"h4"}>Matchings</Typography>
<div>
<Button color={"secondary"} variant={"outlined"} onClick={openModal} disabled={!allowEmailModal}>
Email
</Button>
&nbsp;
<Button variant={"outlined"} onClick={toggleShowMatches}>
{ show ? "Hide Matches" : "Show Matches" }
</Button>
</div>
</Wrapper>
<hr className={"box-title-separator"}/>
<ExtremeTable
headers={headers}
rows={rows}
showGrouping={false}
selection={{selection: selection, setSelection:setSelection}}
defaultHiddenColumnNames={defaultHiddenColumnNames}
booleanColumns={booleanColumns}
choiceColumns={choiceColumns}
choiceSelectionOptions={choiceSelectionOptions}
currencyColumns={currencyColumns}
numberColumns={numberColumns}
dateColumns={dateColumns}
custom_miscelaneous_plugins={custom_miscelaneous_plugins}
/>
</Block>
<Container>
<Block>
<Row>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment