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

466 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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(encodeURI(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.clearAllCheck()
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)
this.props.updataleftNavfun()
}
})
.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) => {
clearTimeout(this.timeoutHandler)
this.timeoutHandler = null;
this.fetchAll(this.state.searchValue, 1)
}
onInputSearchChange = (e) => {
this.setState({
searchValue:e.target.value
})
if (this.timeoutHandler) {
clearTimeout(this.timeoutHandler)
this.timeoutHandler = null;
}
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.setState({
checkBoxValues:[]
})
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 isCourseEnd = this.props.isCourseEnd()
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}
allowClearonChange={this.onInputSearchChange}
showSearchInput={messages.length >= 10}
searchPlaceholder={ '请输入帖子名称进行搜索' }
firstRowRight={
<React.Fragment>
{ !isCourseEnd && isAdmin && !parent_id && <WordsBtn style="blue" className="mr30" onClick={()=>this.addDir()}>新建目录</WordsBtn> }
{ isAdmin && !!parent_id && <WordsBtn style="blue" className="mr30" onClick={()=>this.renameDir()}>目录重命名</WordsBtn> }
{ !isCourseEnd && 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> */}
{messages&&messages.length == 0?"": isAdmin && <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, index) => {
return <li key={`i_${index}`} onClick={() => this.moveTo(item)} title={item.name}>{item.name}</li>
})
}
{ isAdmin && !isCourseEnd &&
<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" key={`d_${index}`}>
<BoardsListItem
{...this.props}
discussMessage={item}
checkBox={ isAdmin ? <Checkbox value={item.id} key={item.id}></Checkbox> : ''}
onItemClick={this.onItemClick}
onSticky={this.onSticky}
></BoardsListItem>
</div>
)
})
}
</Checkbox.Group>
</div>
</Spin>
{
( !this.state.isSpin && (!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"
current={pagination.page}
showQuickJumper pageSize={15} total={pagination.total_count} onChange={this.onPageChange} />}
</React.Fragment>
)
}
}
export default RouteHOC()(Boards);