From 433c24e8d1848b1c0fe17b2a6baf4223e84743e7 Mon Sep 17 00:00:00 2001 From: BenjaVR Date: Sun, 6 Jan 2019 21:51:24 +0100 Subject: [PATCH] EducationsPage (based on SchoolsPage) --- ...able.module.scss => DataTable.module.scss} | 0 web/src/components/EducationsTable.tsx | 180 ------------------ web/src/components/Root.tsx | 1 + .../educations/EducationsFormModal.tsx | 118 ++++++++++++ .../components/educations/EducationsPage.tsx | 162 ++++++++++++++++ .../components/educations/EducationsTable.tsx | 107 +++++++++++ .../layouts/AuthenticatedLayout.tsx | 10 +- .../components/schools/SchoolList.module.scss | 7 - ...hoolFormModal.tsx => SchoolsFormModal.tsx} | 14 +- web/src/components/schools/SchoolsPage.tsx | 34 ++-- .../{SchoolList.tsx => SchoolsTable.tsx} | 65 +++---- web/src/routes.ts | 8 + 12 files changed, 459 insertions(+), 247 deletions(-) rename web/src/components/{EducationsTable.module.scss => DataTable.module.scss} (100%) delete mode 100644 web/src/components/EducationsTable.tsx create mode 100644 web/src/components/educations/EducationsFormModal.tsx create mode 100644 web/src/components/educations/EducationsPage.tsx create mode 100644 web/src/components/educations/EducationsTable.tsx delete mode 100644 web/src/components/schools/SchoolList.module.scss rename web/src/components/schools/{SchoolFormModal.tsx => SchoolsFormModal.tsx} (88%) rename web/src/components/schools/{SchoolList.tsx => SchoolsTable.tsx} (59%) diff --git a/web/src/components/EducationsTable.module.scss b/web/src/components/DataTable.module.scss similarity index 100% rename from web/src/components/EducationsTable.module.scss rename to web/src/components/DataTable.module.scss diff --git a/web/src/components/EducationsTable.tsx b/web/src/components/EducationsTable.tsx deleted file mode 100644 index 6d9f5cc..0000000 --- a/web/src/components/EducationsTable.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { Button, Col, notification, Popconfirm, Row, Table } from "antd"; -import { ColumnProps } from "antd/lib/table"; -import React from "react"; -import { stringSorter } from "../helpers/sorters"; -import { IEducation } from "../models/Education"; -import { EducationsService } from "../services/EducationsService"; -import styles from "./EducationsTable.module.scss"; - -interface IEducationsTableProps { -} - -interface IEducationsTableState { - educations: IEducation[]; - loading: boolean; -} - -class EducationsTable extends React.Component { - - private educationsService = new EducationsService(); - - private columns: Array> = [ - { - title: "Naam", - dataIndex: "name", - key: "name", - sorter: (a, b) => stringSorter(a.name, b.name), - }, - { - title: "Acties", - key: "actions", - width: 120, - align: "center", - render: (record: IEducation) => this.renderRowActions(record), - }, - ]; - - constructor(props: IEducationsTableProps) { - super(props); - - this.state = { - educations: [], - loading: true, - }; - - this.renderRowActions = this.renderRowActions.bind(this); - this.renderTableTitle = this.renderTableTitle.bind(this); - this.handleRequestAddEducation = this.handleRequestAddEducation.bind(this); - this.handleDeleteEducation = this.handleDeleteEducation.bind(this); - this.handleRequestEditEducation = this.handleRequestEditEducation.bind(this); - } - - public componentDidMount(): void { - this.educationsService.subscribe((educations): void => { - this.setState({ - educations, - loading: false, - }); - }); - } - - public render(): React.ReactNode { - return ( - - - - ); - } - - private renderTableTitle(): React.ReactNode { - return ( - - -

Opleidingen

- - - - - - ); - } - - private renderRowActions(record: IEducation): React.ReactNode { - const deleteFunc = () => { this.handleDeleteEducation(record); }; - const editFunc = () => { this.handleRequestEditEducation(record); }; - return ( - - + + + + + + + + ); + } + + private openAddEducationModal(): void { + this.setState({ isAddEducationModalVisible: true }); + } + + private closeAddEducationModal(): void { + this.setState({ isAddEducationModalVisible: false }); + } + + private openEditEducationModal(education: IEducation): void { + this.setState({ + isEditEducationModalVisible: true, + educationToEdit: education, + }); + } + + private closeEditEducationModal(): void { + this.setState({ isEditEducationModalVisible: false }); + } + + private addEducation(education: IEducation): Promise { + return new Promise((resolve, reject): void => { + this.educationsService.add(education) + .then(() => { + notification.success({ + message: `Opleiding "${education.name}" succesvol toegevoegd`, + }); + resolve(); + }) + .catch(() => { + notification.error({ + message: "Kon opleiding niet toevoegen", + }); + reject(); + }); + }); + } + + private editEducation(education: IEducation): Promise { + education.id = this.state.educationToEdit!.id; + return new Promise((resolve, reject): void => { + this.educationsService.update(education) + .then(() => { + notification.success({ + message: `Opleiding "${education.name}" succesvol bewerkt`, + }); + resolve(); + }) + .catch(() => { + notification.error({ + message: "Kon opleiding niet bewerken", + }); + reject(); + }); + }); + } + + private deleteEducation(education: IEducation): Promise { + return new Promise((resolve, reject): void => { + this.educationsService.delete(education) + .then(() => { + notification.success({ + message: `Opleiding "${education.name}" succesvol verwijderd`, + }); + resolve(); + }) + .catch(() => { + notification.error({ + message: `Kon opleiding "${education.name}" niet verwijderen, probeer later opnieuw`, + }); + reject(); + }); + }); + } +} diff --git a/web/src/components/educations/EducationsTable.tsx b/web/src/components/educations/EducationsTable.tsx new file mode 100644 index 0000000..8fad6a4 --- /dev/null +++ b/web/src/components/educations/EducationsTable.tsx @@ -0,0 +1,107 @@ +import { Button, Col, Popconfirm, Row, Table, Tooltip } from "antd"; +import { ColumnProps } from "antd/lib/table"; +import React from "react"; +import { stringSorter } from "../../helpers/sorters"; +import { IEducation } from "../../models/Education"; +import styles from "../DataTable.module.scss"; + +interface IEducationsTableProps { + isLoading: boolean; + educations: IEducation[]; + deleteEducation: (education: IEducation) => Promise; + onAddEducationRequest: () => void; + onEditEducationRequest: (education: IEducation) => void; +} + +class EducationsTable extends React.Component { + + private columns: Array> = [ + { + title: "Naam", + dataIndex: "name", + key: "name", + sorter: (a, b) => stringSorter(a.name, b.name), + }, + { + title: "Acties", + key: "actions", + width: 120, + align: "center", + render: (record: IEducation) => this.renderActions(record), + }, + ]; + + constructor(props: IEducationsTableProps) { + super(props); + + this.renderActions = this.renderActions.bind(this); + this.renderTableTitle = this.renderTableTitle.bind(this); + } + + public render(): React.ReactNode { + return ( +
+ ); + } + + private renderActions(education: IEducation): React.ReactNode { + const deleteFunc = () => this.props.deleteEducation(education); + const editFunc = () => this.props.onEditEducationRequest(education); + return ( + + + + + + + ); + } + + private generateTableRowKey(record: IEducation, index: number): string { + return record.id || index.toString(); + } +} + +export default EducationsTable; diff --git a/web/src/components/layouts/AuthenticatedLayout.tsx b/web/src/components/layouts/AuthenticatedLayout.tsx index 9d2aba2..5c16c4b 100644 --- a/web/src/components/layouts/AuthenticatedLayout.tsx +++ b/web/src/components/layouts/AuthenticatedLayout.tsx @@ -11,6 +11,7 @@ import styles from "./AuthenticatedLayout.module.scss"; interface IAuthenticatedLayoutProps { router: RouterProps; + initialRoute: IRoute; } interface IAuthenticatedLayoutState { @@ -32,6 +33,7 @@ class AuthenticatedLayout extends React.Component menuItem.route.url === selectParam.key); + const newMenuItem = this.getMenuItemByUrl(selectParam.key); if (newMenuItem !== undefined) { this.setState({ @@ -176,6 +178,10 @@ class AuthenticatedLayout extends React.Component menuItem.route.url === url); + } + private getUsername(): string { const user = Firebase.auth().currentUser; diff --git a/web/src/components/schools/SchoolList.module.scss b/web/src/components/schools/SchoolList.module.scss deleted file mode 100644 index 8a22adb..0000000 --- a/web/src/components/schools/SchoolList.module.scss +++ /dev/null @@ -1,7 +0,0 @@ -.actionButton { - margin: 0 4px; -} - -.tableTitleText { - margin: 0; -} diff --git a/web/src/components/schools/SchoolFormModal.tsx b/web/src/components/schools/SchoolsFormModal.tsx similarity index 88% rename from web/src/components/schools/SchoolFormModal.tsx rename to web/src/components/schools/SchoolsFormModal.tsx index 8126f5b..0457c1c 100644 --- a/web/src/components/schools/SchoolFormModal.tsx +++ b/web/src/components/schools/SchoolsFormModal.tsx @@ -5,7 +5,7 @@ import React from "react"; import { FormValidationTrigger } from "../../helpers/types"; import { ISchool } from "../../models/School"; -interface ISchoolFormModalProps { +interface ISchoolsFormModalProps { title: string; okText: string; isVisible: boolean; @@ -14,14 +14,14 @@ interface ISchoolFormModalProps { submitSchool(school: ISchool): Promise; } -type SchoolFormModalProps = ISchoolFormModalProps & FormComponentProps; +type SchoolFormModalProps = ISchoolsFormModalProps & FormComponentProps; -interface ISchoolFormModalState { +interface ISchoolsFormModalState { isSubmitting: boolean; formValidateTrigger: FormValidationTrigger; } -class SchoolFormModal extends React.Component { +class SchoolsFormModal extends React.Component { constructor(props: SchoolFormModalProps) { super(props); @@ -67,6 +67,7 @@ class SchoolFormModal extends React.Component, @@ -112,6 +113,5 @@ class SchoolFormModal extends React.Component()(SchoolFormModal); - -export default WrappedSchoolFormModal; +const WrappedSchoolsFormModal = Form.create()(SchoolsFormModal); +export default WrappedSchoolsFormModal; diff --git a/web/src/components/schools/SchoolsPage.tsx b/web/src/components/schools/SchoolsPage.tsx index 2c83ade..e2dd767 100644 --- a/web/src/components/schools/SchoolsPage.tsx +++ b/web/src/components/schools/SchoolsPage.tsx @@ -1,20 +1,19 @@ import { Col, notification, Row } from "antd"; import React from "react"; import { ISchool } from "../../models/School"; -import { RoutePageComponentProps } from "../../routes"; +import { RoutePageComponentProps, routes } from "../../routes"; import { SchoolsService } from "../../services/SchoolsService"; -import EducationsTable from "../EducationsTable"; import AuthenticatedLayout from "../layouts/AuthenticatedLayout"; -import SchoolFormModal from "./SchoolFormModal"; -import SchoolList from "./SchoolList"; +import SchoolFormModal from "./SchoolsFormModal"; +import SchoolList from "./SchoolsTable"; type SchoolsPageProps = RoutePageComponentProps; interface ISchoolsPageState { schools: ISchool[]; isFetching: boolean; - isAddSchoolModalVisible: boolean; - isEditSchoolModalVisible: boolean; + isAddSchoolsModalVisible: boolean; + isEditSchoolsModalVisible: boolean; schoolToEdit: ISchool | undefined; } @@ -28,8 +27,8 @@ export default class SchoolsPage extends React.Component - + - + - - - { diff --git a/web/src/components/schools/SchoolList.tsx b/web/src/components/schools/SchoolsTable.tsx similarity index 59% rename from web/src/components/schools/SchoolList.tsx rename to web/src/components/schools/SchoolsTable.tsx index 77e6d0c..48938f3 100644 --- a/web/src/components/schools/SchoolList.tsx +++ b/web/src/components/schools/SchoolsTable.tsx @@ -1,11 +1,11 @@ -import { Button, Col, Popconfirm, Row, Table } from "antd"; +import { Button, Col, Popconfirm, Row, Table, Tooltip } from "antd"; import { ColumnProps } from "antd/lib/table"; import React from "react"; import { stringSorter } from "../../helpers/sorters"; import { ISchool } from "../../models/School"; -import styles from "./SchoolList.module.scss"; +import styles from "../DataTable.module.scss"; -interface ISchoolListProps { +interface ISchoolsTableProps { isLoading: boolean; schools: ISchool[]; deleteSchool: (school: ISchool) => Promise; @@ -13,7 +13,7 @@ interface ISchoolListProps { onEditSchoolRequest: (school: ISchool) => void; } -class SchoolList extends React.Component { +class SchoolsTable extends React.Component { private columns: Array> = [ { @@ -31,7 +31,7 @@ class SchoolList extends React.Component { }, ]; - constructor(props: ISchoolListProps) { + constructor(props: ISchoolsTableProps) { super(props); this.renderActions = this.renderActions.bind(this); @@ -41,14 +41,15 @@ class SchoolList extends React.Component { public render(): React.ReactNode { return (
); } @@ -58,27 +59,30 @@ class SchoolList extends React.Component { const editFunc = () => this.props.onEditSchoolRequest(school); return ( - -

Scholen

- - - + + ); } - private getTableRowKey(record: ISchool, index: number): string { + private generateTableRowKey(record: ISchool, index: number): string { return record.id || index.toString(); } } -export default SchoolList; +export default SchoolsTable; diff --git a/web/src/routes.ts b/web/src/routes.ts index a6e2610..9e66774 100644 --- a/web/src/routes.ts +++ b/web/src/routes.ts @@ -1,6 +1,7 @@ import * as React from "react"; import { RouteComponentProps } from "react-router"; import LoginPage from "./components/auth/login/LoginPage"; +import EducationsPage from "./components/educations/EducationsPage"; import SchoolsPage from "./components/schools/SchoolsPage"; export type RoutePageComponentProps = RouteComponentProps; @@ -35,6 +36,12 @@ const schoolsRoute: IRoute = { component: SchoolsPage, }; +const educationsRoute: IRoute = { + title: "Opleidingen", + url: "/educations", + component: EducationsPage, +}; + const departmentsRoute: IRoute = { title: "Afdelingen", url: "/departments", @@ -49,5 +56,6 @@ export const routes = { planningsRoute, studentsRoute, schoolsRoute, + educationsRoute, departmentsRoute, };