You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/public/react/src/modules/courses/boards/index.js

455 lines
15 KiB

import React,{ Component } from "react";
import { Input, Checkbox, Table, Tooltip, Pagination,Spin } from "antd";
import CourseLayoutcomponent from '../common/CourseLayoutComponent'
import BoardsListItem from './BoardsListItem'
import Titlesearchsection from '../common/titleSearch/TitleSearchSection'
import ColorCountText from '../common/titleSearch/ColorCountText'
import SendToCourseModal from '../coursesPublic/modal/SendToCourseModal'
import NoneData from "../coursesPublic/NoneData"
import axios from 'axios'
import _ from 'lodash'
import './board.css'
import '../css/members.css'
import { RouteHOC } from './common.js'
import { on, off, trigger, WordsBtn } from 'educoder'
class Boards extends Component{
constructor(props){
super(props);
this.state = {
searchValue: '',
checkAllValue: false,
checkBoxValues: [],
pagination: {
page: 1,
page_size: 15,
total_count: 0
},
messages: [
],
sort_type: 'time',
boardid:undefined,
isSpin:false
}
}
fetchAll = (searchText, page) => {
this.setState({
isSpin:true
})
const _serachText = searchText || this.state.searchValue
const _page = page || this.state.pagination.page
const cid = this.props.match.params.coursesId
const bid = this.props.match.params.boardId
//
// hot
const sort_type = this.state.sort_type
// page_size
const url = `/boards/${bid}/messages.json?page_size=15&search=${_serachText || ''}&page=${_page}&sort=0&sort_type=${sort_type}`
axios.get(url, {
})
.then((response) => {
if (response.data.status == 0 && response.data.data) {
let _newBoards = response.data.data.messages
// if (_page > 1) {
// _newBoards = this.state.boards.slice().concat(_newBoards)
// }
this.setState({
messages: _newBoards,
boardName: response.data.data.name,
boardid:response.data.data.id,
parent_id: response.data.data.parent_id,
pagination: response.data.pagination || Object.assign({}, this.state.pagination
, { page: _page, total_count: response.data.data.total_count }),
isSpin:false
})
}
})
.catch(function (error) {
console.log(error);
this.setState({
isSpin:false
})
});
}
fetchBoards = () => {
const boardId = this.props.match.params.boardId
const boardsUrl = `/courses/board_list.json?board_id=${boardId}`
axios.get(boardsUrl, { })
.then((response) => {
if (response.data.status == 0) {
this.setState({
boards: response.data.data.boards,
course_id: response.data.data.course_id
})
}
})
.catch(function (error) {
console.log(error);
});
}
componentDidMount = () => {
this.setState({
isSpin:true
})
this.fetchBoards()
this.fetchAll()
on('updateNavSuccess', this.updateNavSuccess)
}
componentWillUnmount() {
off('updateNavSuccess', this.updateNavSuccess)
}
updateNavSuccess = () => {
this.fetchBoards()
if (this.props.match.params.boardId == this.state.boardid) {
this.fetchAll()
}
}
componentDidUpdate = (prevProps) => {
if ( prevProps.match.params.boardId != this.props.match.params.boardId ) {
this.setState({
isSpin:true
})
this.fetchAll(null, 1)
}
}
moveTo = (board) => {
const len = this.state.checkBoxValues.length
if (len == 0) {
this.props.showNotification('请先在列表中选择要移动的帖子')
return;
}
const bid = this.props.match.params.boardId
const checkBoxValues = this.state.checkBoxValues
const url = `/boards/${bid}/messages/bulk_move.json`
axios.put(url, {
ids: checkBoxValues,
to_board_id: board.id
})
.then((response) => {
if (response.data.status == 0) {
console.log('--- 成功')
this.props.showNotification('帖子移动成功')
this.props.updataleftNavfun()
// TODO 停留在当前board 或 目标board
this.clearAllCheck()
this.fetchAll()
}
})
.catch(function (error) {
console.log(error);
});
}
onDelete = () => {
const len = this.state.checkBoxValues.length
if (len == 0) {
this.props.showNotification('请先选择要删除的帖子')
return;
}
this.props.confirm({
// content: `确认要删除所选的${len}个帖子吗?`,
content: `是否确认删除?`,
onOk: () => {
// const cid = this.props.match.params.coursesId
const bid = this.props.match.params.boardId
const url = `/boards/${bid}/messages/bulk_delete.json`
const board_id = 5897
axios.delete(url, { data: {
// course_id: cid,
ids: this.state.checkBoxValues
}})
.then((response) => {
if (response.data.status == 0) {
// {"status":1,"message":"删除成功"}
console.log('--- 删除成功')
this.clearAllCheck()
this.fetchAll(null, 1)
}
})
.catch(function (error) {
console.log(error);
});
}
})
}
onSticky = (message) => {
const cid = this.props.match.params.coursesId
const url = `/messages/${message.id}/sticky_top.json`
axios.put(url, {
course_id: cid,
})
.then((response) => {
if (response.data.status == 0) {
console.log('--- 置顶/取消置顶成功')
// const boards = this.state.boards;
// for (let _i = 0; _i < boards.length; _i++) {
// boards[]
// }
this.fetchAll()
}
})
.catch(function (error) {
console.log(error);
});
}
onItemClick = (item) => {
const checkBoxValues = this.state.checkBoxValues.slice(0);
const index = checkBoxValues.indexOf(item.id);
if (index != -1) {
_.remove(checkBoxValues, (listItem)=> listItem === item.id)
} else {
checkBoxValues.push(item.id)
}
this.onCheckBoxChange(checkBoxValues)
}
onPressEnter = (e) => {
this.fetchAll(this.state.searchValue, 1)
}
onInputSearchChange = (e) => {
this.setState({
searchValue:e.target.value
})
if (this.timeoutHandler) {
clearTimeout(this.timeoutHandler)
}
this.timeoutHandler = setTimeout(() => {
this.fetchAll(this.state.searchValue, 1)
}, 1200)
}
addDir = () => {
let {boardid}=this.state;
trigger('boardAdd', parseInt(boardid))
}
renameDir = () => {
const boardId = this.props.match.params.boardId
trigger('boardRename', { category_id: parseInt(boardId), category_name: this.state.boardName})
}
onToBoardsNew = () => {
const courseId = this.state.course_id
const boardId = this.props.match.params.boardId
this.props.toNewPage(courseId, boardId)
}
onCheckAll = (e) => {
this.setState({
checkAllValue: e.target.checked
})
const values = this.state.messages.map(item => {
return item.id
})
if (e.target.checked) {
const concated = this.state.checkBoxValues.concat(values);
const sortedUniqed = _.uniq(concated)
this.setState({
checkBoxValues: sortedUniqed
})
} else {
this.setState({
checkBoxValues: _.difference(this.state.checkBoxValues, values)
})
}
}
clearAllCheck = () => {
this.setState({
checkBoxValues: [],
checkAllValue: false
})
}
onCheckBoxChange = (checkedValues) => {
this.setState({
checkBoxValues: checkedValues,
checkAllValue: checkedValues.length == this.state.messages.length
})
console.log('checked = ', checkedValues);
}
onPageChange = (pageNumber) => {
this.fetchAll(null, pageNumber)
}
onSendToOtherCourse = () => {
const len = this.state.checkBoxValues.length
if (len == 0) {
this.props.showNotification('请先在列表中选择要发送的帖子')
return;
}
this.refs.sendToCourseModal.setVisible(true)
}
onSetToOpen = () => {
const { checkBoxValues } = this.state;
if (checkBoxValues.length == 0) {
this.props.showNotification('请先在列表中选择要公开的帖子')
return;
}
const boardId = this.props.match.params.boardId
const url = `/boards/${boardId}/messages/bulk_public.json`
axios.put(url, {
ids: checkBoxValues
})
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('操作成功')
this.fetchAll()
}
})
.catch(function (error) {
console.log(error);
});
}
onSortTypeChange = (sort_type) => {
this.setState({ sort_type }, () => {
this.fetchAll()
})
}
render(){
const isAdmin = this.props.isAdmin()
const isAdminOrStudent = this.props.isAdminOrStudent()
let { boardName, searchValue, boards, messages, checkBoxValues,
checkAllValue, pagination, sort_type, parent_id } = this.state;
const { coursedata } = this.props;
const bid = this.props.match.params.boardId
const haveMore = pagination.total_count - pagination.page_size * pagination.page > 0
return(
<React.Fragment >
<SendToCourseModal
ref="sendToCourseModal"
{...this.props}
moduleName="帖子"
selectedMessageIds={checkBoxValues}
></SendToCourseModal>
<Titlesearchsection
title={boardName || "帖子列表"}
searchValue={ searchValue }
onInputSearchChange={this.onInputSearchChange}
showSearchInput={messages.length >= 10}
searchPlaceholder={ '请输入帖子名称进行搜索' }
firstRowRight={
<React.Fragment>
{ isAdmin && !parent_id && <WordsBtn style="blue" className="mr30" onClick={()=>this.addDir()}>添加目录</WordsBtn> }
{ isAdmin && !!parent_id && <WordsBtn style="blue" className="mr30" onClick={()=>this.renameDir()}>目录重命名</WordsBtn> }
{ isAdminOrStudent && <WordsBtn style="blue" className="" onClick={()=>this.onToBoardsNew()}>我要发布</WordsBtn> }
</React.Fragment>
}
secondRowLeft={
pagination ? <ColorCountText count={pagination.total_count} name="个帖子"></ColorCountText> : ''
}
onPressEnter={this.onPressEnter}
></Titlesearchsection>
{/* <BoardsListItem></BoardsListItem>
<FilesListItem></FilesListItem> */}
<div className="mt20 edu-back-white padding20-30">
<div className="clearfix">
{isAdmin && <Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue}>已选 {checkBoxValues.length} </Checkbox>}
<div className="studentList_operation_ul">
{ !!isAdmin &&
<React.Fragment>
<li className="li_line"><a href="javascript:void(0)" className="color-grey-9" onClick={this.onDelete}>删除</a></li>
<li className="li_line"><a href="javascript:void(0)" className="color-grey-9" onClick={this.onSendToOtherCourse}>发送</a></li>
{ coursedata && !!coursedata.course_public && <li className="li_line"><a href="javascript:void(0)" className="color-grey-9" onClick={this.onSetToOpen}>设为公开</a></li> }
<li className="li_line drop_down">
移动到...<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu"
style={{"right":"0px","left":"unset", maxHeight: '318px', overflowY: 'auto', minWidth: '200px'}}>
{ boards && boards.length > 10 && <p className="drop_down_search">
<Input placeholder="搜索" value={this.state.dirSearchValue} onChange={(e) => {this.setState({dirSearchValue: e.target.value})}}/>
</p> }
{
boards && boards.filter((item)=> {
return item.id != bid && (!this.state.dirSearchValue || item.name.indexOf(this.state.dirSearchValue) != -1)
}).map( (item) => {
return <li onClick={() => this.moveTo(item)}>{item.name}</li>
})
}
{ isAdmin &&
<p className="drop_down_btn">
<a href="javascript:void(0)" className="color-grey-6"
onClick={()=>this.addDir()}
>添加目录...</a>
</p>
}
{/* <p className="drop_down_btn"><a href="javascript:void(0)" className="color-grey-6">添加分班...</a></p> */}
</ul>
</li>
</React.Fragment>
}
<li className="drop_down">
{sort_type == 'time' ? '时间排序' : '热度排序'}<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_normal">
<li onClick={() => this.onSortTypeChange('time')}>时间排序</li>
<li onClick={() => this.onSortTypeChange('hot')}>热度排序</li>
</ul>
</li>
</div>
</div>
</div>
<style>{`
.panel-inner-fourm {
border-bottom: none;
}
.panel-inner-fourm:hover {
background: #fff;
}
`}</style>
<Spin size="large" spinning={this.state.isSpin}>
<div className="clearfix stu_table">
<Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
{ messages.map((item, index) => {
return (
<div className="mt20 edu-back-white padding02010">
<BoardsListItem
{...this.props}
discussMessage={item}
checkBox={ isAdmin ? <Checkbox value={item.id}></Checkbox> : ''}
onItemClick={this.onItemClick}
onSticky={this.onSticky}
></BoardsListItem>
</div>
)
})
}
</Checkbox.Group>
</div>
</Spin>
{
( !messages || messages.length == 0 ) && <NoneData></NoneData>
}
{/* { haveMore && <p className="edu-txt-center pt30 pb10 clearfix">
<a className={"clickmorebox"} onClick={() => this.fetchAll(null, parseInt(pagination.page) + 1)}>
<Tooltip title="点击查看更多" placement="bottom" arrowPointAtCenter={true}
>
<i className="iconfont icon-xiajiantou color-grey-9 font-16"></i>
</Tooltip>
</a>
</p> } */}
{pagination.total_count > 15 && <Pagination className="coursePagination" showQuickJumper pageSize={15} total={pagination.total_count} onChange={this.onPageChange} />}
</React.Fragment>
)
}
}
export default RouteHOC()(Boards);