20241113-a
This commit is contained in:
367
src/renderer/CourseList.tsx
Normal file
367
src/renderer/CourseList.tsx
Normal file
@@ -0,0 +1,367 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user