Files
alab-amis-fix-exam/src/renderer/CourseList.tsx

368 lines
19 KiB
TypeScript
Raw Normal View History

2024-11-13 09:05:45 +08:00
import React from 'react';
import cx from 'classnames';
import { isAfter, isBefore, parse } from 'date-fns';
import { getVariable, isEffectiveApi, OptionsControlProps, Payload, OptionsControl, Select } from 'amis';
@OptionsControl({
test: /(^|\/)course\-list$/,
name: 'course-list',
})
export class CourseListRenderer extends React.Component<
OptionsControlProps,
{
options: Array<any>;
selectedOptions: Array<any>;
selectedProjects: Array<any>;
selectedClasses: Array<any>;
}
> {
constructor(props: OptionsControlProps) {
super(props);
this.state = {
options: [],
selectedOptions: [],
selectedProjects: [],
selectedClasses: [],
};
}
componentDidMount() {
const { data, value, env, source } = this.props;
const dateRange = getVariable(data, 'date');
const startDate = parse(
dateRange.split(',')[0],
'yyyy-MM-dd',
new Date()
);
const endDate = parse(
dateRange.split(',')[1],
'yyyy-MM-dd',
new Date()
);
let selectedOptions: Array<any> = [];
if (value) {
selectedOptions = value.map((item: any) => {
return {
id: item.id,
name: item.name,
value: item.id,
label: item.name,
subjectList: item.subjectList.map((sub: any) => {
return {
value: sub.id,
label: sub.name,
id: sub.id,
name: sub.name,
validRoomList: sub.validRoomList
? sub.validRoomList.map((room: any) => {
return {
id: room.id,
name: room.name,
timeslotList: room.timeslotlist
? room.timeslotlist
.filter(
(t: any) =>
!isBefore(
parse(
t.date,
'yyyy-MM-dd',
new Date()
),
startDate
) &&
!isAfter(
parse(
t.date,
'yyyy-MM-dd',
new Date()
),
endDate
)
)
.map((t: any) => {
return {
id: t.id,
date: t.date,
period: {
id: t.period.id,
name: t.period
.name,
startTime:
t.period
.start_time,
endTime:
t.period
.end_time,
},
};
})
: [],
};
})
: [],
preSubjectList: sub.preSubjectList
? sub.preSubjectList
: [],
};
}),
studentGroupList: item.studentGroupList.map((sub: any) => {
return {
value: sub.id,
label: sub.name,
id: sub.id,
name: sub.name,
validTimeslotList: sub.validTimeslotList
? sub.validTimeslotList.filter((t: any) => {
let tDate = parse(
t.date,
'yyyy-MM-dd',
new Date()
);
return (
!isBefore(tDate, startDate) &&
!isAfter(tDate, endDate)
);
})
: [],
};
}),
};
});
}
if (isEffectiveApi(source)) {
env.fetcher(source, data).then((payload: Payload) => {
this.setState({
options: payload.data.items.map((item: any) => {
return {
id: item.id,
name: item.name,
value: item.id,
label: item.name,
subjectList: item.course2projects.map(
(sub: any) => {
return {
id: sub.projects.id,
name: sub.projects.name,
validRoomList: sub.projects
.validRoomList
? sub.projects.validRoomList.map(
(room: any) => {
return {
id: room.id,
name: room.name,
timeslotList:
room.timeslotlist
? room.timeslotlist
.filter(
(
t: any
) =>
!isBefore(
parse(
t.date,
'yyyy-MM-dd',
new Date()
),
startDate
) &&
!isAfter(
parse(
t.date,
'yyyy-MM-dd',
new Date()
),
endDate
)
)
.map(
(
t: any
) => {
return {
id: t.id,
date: t.date,
period: {
id: t
.period
.id,
name: t
.period
.name,
startTime:
t
.period
.start_time,
endTime:
t
.period
.end_time,
},
};
}
)
: [],
};
}
)
: [],
preSubjectList: sub.projects
.preSubjectList
? sub.projects.preSubjectList
: [],
value: sub.projects.id,
label: sub.projects.name,
};
}
),
studentGroupList: item.course2orgs.map(
(sub: any) => {
return {
id: sub.orgs.id,
name: sub.orgs.name,
validTimeslotList: sub.orgs
.validTimeslotList
? sub.orgs.validTimeslotList.filter(
(t: any) => {
let tDate = parse(
t.date,
'yyyy-MM-dd',
new Date()
);
return (
!isBefore(
tDate,
startDate
) &&
!isAfter(
tDate,
endDate
)
);
}
)
: [],
value: sub.orgs.id,
label: sub.orgs.name,
};
}
),
};
}),
selectedOptions: selectedOptions,
});
});
}
}
handleClick(option: any, e: React.MouseEvent<HTMLElement>) {
if (e.target && (e.target as HTMLElement).closest('a,button')) {
return;
}
const { onChange } = this.props;
let index = this.state.selectedOptions.findIndex(
(item: any) => item.value === option.value
);
let newOptions = Object.assign([], this.state.selectedOptions);
if (index === -1) {
newOptions.push(option);
this.setState({
selectedOptions: newOptions,
});
} else {
newOptions.splice(index, 1);
this.setState({
selectedOptions: newOptions,
});
}
onChange(newOptions);
}
render() {
const { placeholder, className, onChange } = this.props;
const { options, selectedOptions } = this.state;
let body: JSX.Element | null = null;
if (options && options.length) {
body = (
<div>
<div className={cx('a-ListControl-items')}>
{options.map((option, key) => (
<div
key={key}
className={cx(`a-ListControl-item`, 'w-full', {
'is-active':
selectedOptions.findIndex(
(o: any) => o.value === option.value
) !== -1,
'is-disabled': option.disabled,
})}
style={{ maxWidth: '100%' }}
onClick={this.handleClick.bind(this, option)}
>
{option.label}
</div>
))}
</div>
<div className={`m-t-md`}>
{selectedOptions.map((option, key) => {
let optionData = options.find(
(item: any) => item.value === option.value
);
return (
<div
key={key}
className={cx('w-full', 'm-t-xs')}
>
<div>{optionData.label}</div>
<Select
multiple
clearable={false}
joinValues
defaultCheckAll
className={`w-full m-xs`}
options={optionData.subjectList}
onChange={(value: any) => {
option.subjectList = value;
onChange(
this.state.selectedOptions
);
}}
/>
<Select
multiple
clearable={false}
joinValues
defaultCheckAll
className={`w-full m-xs`}
options={optionData.studentGroupList}
onChange={(value: any) => {
option.studentGroupList = value;
onChange(
this.state.selectedOptions
);
}}
/>
</div>
);
})}
</div>
</div>
);
}
return (
<div className={cx('a-ListControl', className)}>
{body ? (
body
) : (
<span className={cx('a-ListControl-placeholder')}>
{placeholder}
</span>
)}
</div>
);
}
}