Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroto7 committed Oct 18, 2019
2 parents fbbe6ba + da40053 commit cc9e3f6
Show file tree
Hide file tree
Showing 10 changed files with 610 additions and 635 deletions.
10 changes: 10 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,14 @@

.btn-toolbar>*+* {
margin-left: .5em;
}

.dropdown-toggle {
align-items: center;
display: flex;
max-width: 100%;
}

.dropdown-toggle::after {
flex-shrink: 0;
}
34 changes: 26 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import 'bootstrap/dist/css/bootstrap.min.css';
import React, { useState } from 'react';
import { Alert, Container, Form, Navbar } from 'react-bootstrap';
import './App.css';
import confirmCourseMovement from './confirmCourseMovement';
import Course from './Course';
import CourseMovementConfirmationModal from './CourseMovementConfirmationModal';
import getValueFromModal from './getValueFromModal';
import RegistrationStatus from './RegistrationStatus';
import Requirements, { RegisteredCreditsCounts, RequirementWithChildren, RequirementWithCourses, SelectionRequirement } from './Requirements';
import RequirementSelector, { defaultRequirement } from './RequirementSelector';
Expand All @@ -16,7 +17,7 @@ const App = () => {
const [requirementToOthersCount, setRequirementToOthersCount] = useState(
new Map<RequirementWithCourses, { acquired: number, registered: number }>()
);
const [selectionToRequirement, setSelectionToRequirement] = useState(new Map<SelectionRequirement, Requirements>());
const [selectionNameToOptionName, setSelectionNameToOptionName] = useState(new Map<string, string>());
const [showsOnlyRegistered, setShowsOnlyRegistered] = useState(false);
const [modals, setModals] = useState(new Array<JSX.Element>());

Expand All @@ -34,7 +35,11 @@ const App = () => {
));
} else if (
currentRequirement !== undefined &&
!await confirmCourseMovement({ currentRequirement, courseToStatus, courseToRequirement, selectionToRequirement, requirementToOthersCount, modals, setModals })
!await getValueFromModal(
CourseMovementConfirmationModal,
{ currentRequirement, courseToStatus, courseToRequirement, selectionNameToOptionName, requirementToOthersCount },
modals, setModals
)
) {
return;
}
Expand All @@ -53,7 +58,20 @@ const App = () => {
}
}
} else {
clearCourseToRequirement(selectionToRequirement.get(requirement) || requirement.choices[0], newCourseToRequirement);
const selectedRequirement = requirement.getSelectedRequirement(selectionNameToOptionName);
if (selectedRequirement !== undefined) {
clearCourseToRequirement(selectedRequirement, newCourseToRequirement);
}
}
}

const clearCourseToRequirementInSelection = (selectionName: string, requirement: Requirements, newCourseToRequirement: Map<Course, RequirementWithCourses>) => {
if (requirement instanceof RequirementWithChildren) {
for (const child of requirement.children) {
clearCourseToRequirementInSelection(selectionName, child, newCourseToRequirement);
}
} else if (requirement instanceof SelectionRequirement && requirement.selectionName === selectionName) {
clearCourseToRequirement(requirement, newCourseToRequirement);
}
}

Expand All @@ -64,11 +82,11 @@ const App = () => {
]));
}

const handleSelectionChange = (selection: SelectionRequirement, chosen: Requirements) => {
const handleSelectionChange = (selectionName: string, newOptionName: string) => {
const newCourseToRequirement = new Map(courseToRequirement);
clearCourseToRequirement(selection, newCourseToRequirement);
clearCourseToRequirementInSelection(selectionName, requirement, newCourseToRequirement);
setCourseToRequirement(newCourseToRequirement);
setSelectionToRequirement(new Map([...selectionToRequirement, [selection, chosen]]));
setSelectionNameToOptionName(new Map([...selectionNameToOptionName, [selectionName, newOptionName]]));
}

return (
Expand All @@ -91,7 +109,7 @@ const App = () => {
<div className="my-3">
<RequirementView
requirement={requirement} showsOnlyRegistered={showsOnlyRegistered}
courseToStatus={courseToStatus} courseToRequirement={courseToRequirement} selectionToRequirement={selectionToRequirement}
courseToStatus={courseToStatus} courseToRequirement={courseToRequirement} selectionNameToOptionName={selectionNameToOptionName}
onCourseClick={handleCourseClick} onOthersCountsChange={handleOthersCountsChange}
onSelectionChange={handleSelectionChange} requirementToOthersCount={requirementToOthersCount}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import React, { useState } from "react";
import { Button, Card, Modal } from "react-bootstrap";
import Course from "./Course";
import RegistrationStatus from "./RegistrationStatus";
import Requirements, { RegisteredCreditsCounts, RequirementWithCourses, SelectionRequirement } from "./Requirements";
import Requirements, { RegisteredCreditsCounts, RequirementWithCourses } from "./Requirements";
import { RequirementSummaryView } from "./RequirementView";

const CourseMovementConfirmationModal = ({ currentRequirement, courseToStatus, courseToRequirement, selectionToRequirement, requirementToOthersCount, onReturn, onExited }: {
const CourseMovementConfirmationModal = ({ currentRequirement, courseToStatus, courseToRequirement, selectionNameToOptionName, requirementToOthersCount, onReturn, onExited }: {
currentRequirement: RequirementWithCourses,
courseToStatus: Map<Course, RegistrationStatus>,
courseToRequirement: Map<Course, Requirements>,
selectionToRequirement: Map<SelectionRequirement, Requirements>,
selectionNameToOptionName: Map<string, string>,
requirementToOthersCount: Map<RequirementWithCourses, RegisteredCreditsCounts>,
onReturn: (value: boolean) => void,
onExited: () => void,
Expand All @@ -28,7 +28,7 @@ const CourseMovementConfirmationModal = ({ currentRequirement, courseToStatus, c
<RequirementSummaryView
requirement={currentRequirement}
courseToStatus={courseToStatus} courseToRequirement={courseToRequirement}
selectionToRequirement={selectionToRequirement} requirementToOthersCount={requirementToOthersCount}
selectionNameToOptionName={selectionNameToOptionName} requirementToOthersCount={requirementToOthersCount}
/>
</Card>
</Modal.Body>
Expand All @@ -40,34 +40,4 @@ const CourseMovementConfirmationModal = ({ currentRequirement, courseToStatus, c
);
};

const confirmCourseMovement = async ({ currentRequirement, courseToStatus, courseToRequirement, selectionToRequirement, requirementToOthersCount, modals, setModals }: {
currentRequirement: RequirementWithCourses,
courseToStatus: Map<Course, RegistrationStatus>,
courseToRequirement: Map<Course, Requirements>,
selectionToRequirement: Map<SelectionRequirement, Requirements>,
requirementToOthersCount: Map<RequirementWithCourses, RegisteredCreditsCounts>,
modals: JSX.Element[],
setModals: React.Dispatch<React.SetStateAction<JSX.Element[]>>
}): Promise<boolean> => {
return new Promise((resolve, reject) => {
try {
const modal = (
<CourseMovementConfirmationModal
currentRequirement={currentRequirement}
courseToStatus={courseToStatus} courseToRequirement={courseToRequirement}
selectionToRequirement={selectionToRequirement} requirementToOthersCount={requirementToOthersCount}
onReturn={value => resolve(value)}
onExited={() => {
setModals(newModals.filter(value => value !== modal));
}}
/>
);
const newModals = [...modals, modal];
setModals(newModals);
} catch (e) {
reject(e);
}
});
};

export default confirmCourseMovement;
export default CourseMovementConfirmationModal;
58 changes: 39 additions & 19 deletions src/RequirementSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ const numberOrRangeToRange = (numberOrRange: number | Range) =>
max: numberOrRange,
};

const convertJSONToRichRequirement = (json: unknown): Requirements => {
const convertJSONToRichRequirement = (json: unknown, selectionNameToCount: Map<string, number>): Requirements => {
if (isCompatible(json, $object({
title: $string,
name: $string,
description: $optional($string),
creditsCount: $union($number, $object({
min: $number,
Expand All @@ -41,7 +41,7 @@ const convertJSONToRichRequirement = (json: unknown): Requirements => {
allowsOthers: $optional($boolean),
}))) {
return new RequirementWithCourses({
title: json.title,
name: json.name,
description: json.description,
creditsCount: numberOrRangeToRange(json.creditsCount),
courses: json.courses.map(courseCode => {
Expand All @@ -52,39 +52,59 @@ const convertJSONToRichRequirement = (json: unknown): Requirements => {
allowsOthers: json.allowsOthers,
});
} else if (isCompatible(json, $object({
title: $string,
name: $string,
description: $optional($string),
children: $array($object({})),
creditsCount: $optional($union($number, $object({
min: $number,
max: $number,
}))),
creditsCount: $optional($union(
$number,
$object({
min: $number,
max: $number,
}),
)),
}))) {
return new RequirementWithChildren({
title: json.title,
name: json.name,
description: json.description,
children: json.children.map(child => convertJSONToRichRequirement(child)),
children: json.children.map(child => convertJSONToRichRequirement(child, selectionNameToCount)),
creditsCount: json.creditsCount === undefined ? undefined : numberOrRangeToRange(json.creditsCount),
});
} else if (isCompatible(json, $object({
title: $string,
description: $optional($string),
choices: $array($object({})),
selectionName: $string,
options: $array($object({})),
}))) {
const selectionCount = selectionNameToCount.get(json.selectionName) || 0;
selectionNameToCount.set(json.selectionName, selectionCount + 1);
return new SelectionRequirement({
title: json.title,
description: json.description,
choices: json.choices.map(choice => convertJSONToRichRequirement(choice)),
name: `${json.selectionName}_${selectionCount}`,
selectionName: json.selectionName,
options: json.options.map(option => {
if (isCompatible(option, $object({
name: $string,
requirement: $object({}),
}))) {
return {
name: option.name,
requirement: convertJSONToRichRequirement(option.requirement, selectionNameToCount),
};
} else {
const requirement = convertJSONToRichRequirement(option, selectionNameToCount);
return {
name: requirement.name,
requirement
};
}
}),
})
} else {
throw new Error('要件定義が不正です。')
}
}

const requirements = {
coins17: convertJSONToRichRequirement(coins17_0),
mast17: convertJSONToRichRequirement(mast17_0),
klis17: convertJSONToRichRequirement(klis17_0),
coins17: convertJSONToRichRequirement(coins17_0, new Map()),
mast17: convertJSONToRichRequirement(mast17_0, new Map()),
klis17: convertJSONToRichRequirement(klis17_0, new Map()),
};

console.log(requirements);
Expand Down
Loading

0 comments on commit cc9e3f6

Please sign in to comment.