139 lines
5.8 KiB
TypeScript
139 lines
5.8 KiB
TypeScript
import {observer} from "mobx-react";
|
||
import {Page} from "../layout/Page";
|
||
import {action, makeObservable, observable, reaction, runInAction} from "mobx";
|
||
import React from "react";
|
||
import {DataTable} from "../data-tables/DataTable";
|
||
import {Column, TableDescriptor} from "../../utils/tables";
|
||
import {PreparationDirection} from "../../models/preparationDirection";
|
||
import {get} from "../../utils/request";
|
||
import {datetimeConverter} from "../../utils/converters";
|
||
import {Button, Col, Row} from "react-bootstrap";
|
||
import {ModalState} from "../../utils/modalState";
|
||
import {UserService} from "../../services/UserService";
|
||
import {DiplomaTopic} from "../../models/diplomaTopic";
|
||
import {TeacherData} from "../../models/teacherData";
|
||
import {fullName} from "../../models/participant";
|
||
import DiplomaTopicModal from "./DiplomaTopicModal";
|
||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||
import _ from "lodash";
|
||
import {ThinkService} from "../../services/ThinkService";
|
||
import {DiplomaTopicFilterModal} from "./DiplomaTopicFilterModal";
|
||
|
||
const getAllDiplomaTopics = () => {
|
||
return get<DiplomaTopic[]>("diploma-topic/all");
|
||
}
|
||
|
||
class DiplomaTopicPageState {
|
||
constructor() {
|
||
makeObservable(this);
|
||
this.updateDiplomaTopics();
|
||
reaction(() => this.diplomaTopics, () => {
|
||
this.tableDescriptor = new TableDescriptor<DiplomaTopic>([
|
||
new Column<DiplomaTopic, string>('name', 'Название', undefined, (dp) => {
|
||
return <FontAwesomeIcon icon={'file-pen'} style={{'cursor': 'pointer'}}
|
||
data-value={dp.id} onClick={this.onIconClicked}/>;
|
||
}),
|
||
new Column<DiplomaTopic, TeacherData>('teacher', 'Преподаватель', (value) => {
|
||
return value ? fullName(value.participant) : "Не указан";
|
||
}),
|
||
new Column<DiplomaTopic, PreparationDirection>('preparationDirection', 'Код направления подготовки', value => {
|
||
return value ? value.code : "Не указано";
|
||
}),
|
||
new Column<DiplomaTopic, PreparationDirection>('preparationDirection', 'Название Направления подготовки', value => {
|
||
return value ? value.name : "Не указано";
|
||
}),
|
||
new Column<DiplomaTopic, string>('createdAt', 'Дата создания', datetimeConverter),
|
||
new Column<DiplomaTopic, string>('updatedAt', 'Дата обновления', datetimeConverter),
|
||
], this.diplomaTopics, true, this.filters
|
||
);
|
||
}, {fireImmediately: true});
|
||
}
|
||
|
||
@observable diplomaTopics: DiplomaTopic[] = [];
|
||
@observable selectedTopic: DiplomaTopic = undefined;
|
||
@observable tableDescriptor: TableDescriptor<DiplomaTopic>;
|
||
@observable diplomaTopicModalState = new ModalState(false, this.updateDiplomaTopics);
|
||
@observable diplomaTopicEditModalState = new ModalState(false, this.updateDiplomaTopics);
|
||
|
||
@observable filters: ((group: DiplomaTopic) => boolean)[] = [];
|
||
|
||
@observable filterModalState = new ModalState();
|
||
|
||
@action.bound
|
||
updateDiplomaTopics() {
|
||
ThinkService.think();
|
||
getAllDiplomaTopics().then(dt => {
|
||
runInAction(() => {
|
||
this.diplomaTopics = dt;
|
||
})
|
||
}).finally(() => {
|
||
ThinkService.completeAll();
|
||
});
|
||
}
|
||
|
||
@action.bound
|
||
onIconClicked(event: React.MouseEvent<any>) {
|
||
const pd = this.diplomaTopics.find(pd => pd.id === _.toNumber(event.currentTarget.getAttribute('data-value')));
|
||
if (pd) {
|
||
this.selectedTopic = pd;
|
||
this.diplomaTopicEditModalState.open();
|
||
}
|
||
}
|
||
}
|
||
|
||
@observer
|
||
export class DiplomaTopicListPage extends Page {
|
||
constructor(props: any) {
|
||
super(props);
|
||
makeObservable(this);
|
||
this.fields = new DiplomaTopicPageState();
|
||
}
|
||
|
||
@observable fields: DiplomaTopicPageState;
|
||
|
||
get page() {
|
||
return <>
|
||
{
|
||
<>
|
||
{
|
||
this.fields.tableDescriptor &&
|
||
<>
|
||
<DataTable tableDescriptor={this.fields.tableDescriptor} name={'Темы ВКР'}
|
||
additionalButtons={<AdditionalButtons state={this.fields}/>}
|
||
filterModalState={this.fields.filterModalState}
|
||
/>
|
||
<DiplomaTopicFilterModal modalState={this.fields.filterModalState} filters={this.fields.filters}/>
|
||
</>
|
||
}
|
||
<DiplomaTopicModal modalState={this.fields.diplomaTopicModalState}/>
|
||
{
|
||
this.fields.selectedTopic &&
|
||
<DiplomaTopicModal modalState={this.fields.diplomaTopicEditModalState} topic={this.fields.selectedTopic}/>
|
||
}
|
||
</>
|
||
}
|
||
</>
|
||
}
|
||
}
|
||
|
||
const AdditionalButtons = observer(({state}: {state: DiplomaTopicPageState}) => {
|
||
return (
|
||
<div className={'d-flex'}>
|
||
<div>
|
||
{(UserService.isSecretary || UserService.isAdministrator) && (
|
||
<Button variant="outline-secondary" size="sm" className="me-2" onClick={state.diplomaTopicModalState.open}>
|
||
<FontAwesomeIcon icon={'add'} style={{'cursor': 'pointer'}}/>
|
||
</Button>
|
||
)}
|
||
</div>
|
||
<div>
|
||
<Button variant="outline-secondary" size="sm" className="me-2" onClick={state.updateDiplomaTopics}>
|
||
<FontAwesomeIcon icon={'rotate'} style={{'cursor': 'pointer'}}/>
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
);
|
||
});
|
||
|
||
|