From a06a551ac8e2849813433696c05cf633014909b9 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Thu, 30 May 2019 15:44:48 +0800 Subject: [PATCH 1/2] change button and style --- frontend/src/css/work-weixin-departments.css | 57 +++ .../src/pages/sys-admin/file-scan-records.js | 33 +- frontend/src/pages/sys-admin/main-panel.js | 10 - frontend/src/pages/sys-admin/side-panel.js | 2 +- .../sys-admin/work-weixin-departments.js | 474 +++++------------- .../src/pages/sys-admin/work-weixin/index.js | 5 + .../work-weixin-department-members-list.js | 84 ++++ .../work-weixin-departments-tree-node.js | 81 +++ .../work-weixin-departments-tree-panel.js | 49 ++ media/img/member-list-empty.png | Bin 0 -> 6846 bytes 10 files changed, 428 insertions(+), 367 deletions(-) create mode 100644 frontend/src/css/work-weixin-departments.css create mode 100644 frontend/src/pages/sys-admin/work-weixin/index.js create mode 100644 frontend/src/pages/sys-admin/work-weixin/work-weixin-department-members-list.js create mode 100644 frontend/src/pages/sys-admin/work-weixin/work-weixin-departments-tree-node.js create mode 100644 frontend/src/pages/sys-admin/work-weixin/work-weixin-departments-tree-panel.js create mode 100644 media/img/member-list-empty.png diff --git a/frontend/src/css/work-weixin-departments.css b/frontend/src/css/work-weixin-departments.css new file mode 100644 index 0000000000..aaef1ec5b4 --- /dev/null +++ b/frontend/src/css/work-weixin-departments.css @@ -0,0 +1,57 @@ +.dir-content-main { + width: 75%; + overflow-y: hidden; + padding-right: 1rem; +} +.dir-content-main:hover { + overflow-y: auto; +} +.dir-content-main table td { + line-height: 2rem; +} +.dir-content-nav { + width: 24%; + overflow: hidden; +} +.dir-content-nav:hover { + overflow: auto; +} +.dir-content-resize { + width: 1%; + border-left: 1px solid #eee; +} +.department-children { + padding-left: 1rem; + position: relative; +} +.tree-node-inner { + position: relative; +} +.tree-node-inner i { + position: absolute; + top: 20%; + left: 0.3rem; +} +.tree-node-inner:hover { + background-color: #FFEFB2; + border-radius: 0.25rem; + cursor: pointer; +} +.tree-node-hight-light { + color: #fff; + border-radius: 4px; + background-color: #feac74 !important; +} +.tree-node-text { + padding-left: 1.3rem; + width: calc(100% - 1.3rem); + font-size: 14px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: 24px; +} +.tree-view { + padding: 12px 12px 12px 0; + flex: 1 1; +} \ No newline at end of file diff --git a/frontend/src/pages/sys-admin/file-scan-records.js b/frontend/src/pages/sys-admin/file-scan-records.js index 744697739a..9c9d947aef 100644 --- a/frontend/src/pages/sys-admin/file-scan-records.js +++ b/frontend/src/pages/sys-admin/file-scan-records.js @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { seafileAPI } from '../../utils/seafile-api'; import { gettext, loginUrl } from '../../utils/constants'; +import Account from '../../components/common/account'; const tablePropTypes = { @@ -116,20 +117,30 @@ class FileScanRecords extends Component { render() { return ( -
-
-
-

{gettext('Content Scan Records')}

+ +
+
+
-
- +
+
- +
+
+
+

{gettext('Content Scan Records')}

+
+
+
+ + + + ); } } diff --git a/frontend/src/pages/sys-admin/main-panel.js b/frontend/src/pages/sys-admin/main-panel.js index a83b54728b..2c579ea438 100644 --- a/frontend/src/pages/sys-admin/main-panel.js +++ b/frontend/src/pages/sys-admin/main-panel.js @@ -1,7 +1,5 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import Account from '../../components/common/account'; - const propTypes = { children: PropTypes.array.isRequired, @@ -12,14 +10,6 @@ class MainPanel extends Component { render() { return (
-
-
- -
-
- -
-
{this.props.children}
); diff --git a/frontend/src/pages/sys-admin/side-panel.js b/frontend/src/pages/sys-admin/side-panel.js index 4cc0746c31..f3ac2e2065 100644 --- a/frontend/src/pages/sys-admin/side-panel.js +++ b/frontend/src/pages/sys-admin/side-panel.js @@ -172,7 +172,7 @@ class SidePanel extends React.Component { {isDefaultAdmin && enableWorkWeixinDepartments &&
  • - + {'企业微信集成'}
  • diff --git a/frontend/src/pages/sys-admin/work-weixin-departments.js b/frontend/src/pages/sys-admin/work-weixin-departments.js index 6fa3d4678f..b313a96108 100644 --- a/frontend/src/pages/sys-admin/work-weixin-departments.js +++ b/frontend/src/pages/sys-admin/work-weixin-departments.js @@ -1,225 +1,12 @@ -import React, {Component} from 'react'; -import PropTypes from 'prop-types'; -import {seafileAPI} from '../../utils/seafile-api'; -import {gettext, siteRoot} from '../../utils/constants'; +import React, { Component, Fragment } from 'react'; +import { Button } from 'reactstrap'; +import _ from 'lodash'; +import { seafileAPI } from '../../utils/seafile-api'; +import { gettext, siteRoot } from '../../utils/constants'; import toaster from '../../components/toast'; -import Loading from '../../components/loading'; -import {Button, Table} from 'reactstrap'; - - -class WorkWeixinDepartmentMembersList extends Component { - constructor(props) { - super(props); - this.state = {}; - } - - render() { - const membersList = this.props.membersList.map((member, index) => { - let avatar = member.avatar; - if (member.avatar.length > 0) { - // get smaller avatar - avatar = member.avatar.substring(0, member.avatar.length - 1) + '100'; - } else { - avatar = siteRoot + 'media/avatars/default.png'; - } - const userCheckBox = member.email ? '' : - this.props.onUserChecked(member)} - >; - return ( - - - - - - - - - ); - }); - - const allUsersCheckBox = !this.props.canCheckUserIds.length ? '' : - this.props.onAllUsersChecked()} - >; - - return ( -
    -
    - {this.props.isMembersListLoading && } - - {!this.props.isMembersListLoading && -
    {userCheckBox}{member.name}{member.mobile}{member.contact_email}{member.email ? : ''}
    - - - - - - - - - - - - {membersList} - -
    {allUsersCheckBox}{'名称'}{'手机号'}{'邮箱'}{'已添加'}
    - } - {!this.props.isMembersListLoading && this.props.membersList.length === 0 && -
    -

    {'无成员'}

    -
    - } -
    -
    - ); - } -} - -const WorkWeixinDepartmentMembersListPropTypes = { - isMembersListLoading: PropTypes.bool.isRequired, - membersList: PropTypes.array.isRequired, - newUsersTempObj: PropTypes.object.isRequired, - checkedDepartmentId: PropTypes.number.isRequired, - onUserChecked: PropTypes.func.isRequired, - onAllUsersChecked: PropTypes.func.isRequired, - isCheckedAll: PropTypes.bool.isRequired, - canCheckUserIds: PropTypes.array.isRequired, -}; - -WorkWeixinDepartmentMembersList.propTypes = WorkWeixinDepartmentMembersListPropTypes; - - -class WorkWeixinDepartmentsTreeNode extends Component { - constructor(props) { - super(props); - this.state = { - isChildrenShow: false, - }; - } - - toggleChildren = () => { - this.setState({ - isChildrenShow: !this.state.isChildrenShow, - }); - }; - - renderTreeNodes = (departmentsTree) => { - if (departmentsTree.length > 0) { - return departmentsTree.map((department) => { - return ( - - ); - }); - } - }; - - componentDidMount() { - if (this.props.index === 0) { - this.toggleChildren(); - this.props.onChangeDepartment(this.props.department.id); - } - } - - render() { - let toggleIconClass = ''; - if (this.props.department.children) { - if (this.state.isChildrenShow) { - toggleIconClass = 'folder-toggle-icon fa fa-caret-down'; - } else { - toggleIconClass = 'folder-toggle-icon fa fa-caret-right'; - } - } - let departmentStyle = this.props.checkedDepartmentId === this.props.department.id ? {color: 'blue'} : {}; - - return ( -
    - {this.props.isChildrenShow && -
    - this.toggleChildren()}>{' '} - this.props.onChangeDepartment(this.props.department.id)} - >{this.props.department.name} -
    - } - {this.state.isChildrenShow && -
    - {this.props.department.children && this.renderTreeNodes(this.props.department.children)} -
    - } -
    - ); - } -} - -const WorkWeixinDepartmentsTreeNodePropTypes = { - index: PropTypes.number, - department: PropTypes.object.isRequired, - isChildrenShow: PropTypes.bool.isRequired, - onChangeDepartment: PropTypes.func.isRequired, - checkedDepartmentId: PropTypes.number.isRequired, -}; - -WorkWeixinDepartmentsTreeNode.propTypes = WorkWeixinDepartmentsTreeNodePropTypes; - - -class WorkWeixinDepartmentsTreePanel extends Component { - constructor(props) { - super(props); - this.state = {}; - } - - render() { - const departmentsTree = this.props.departmentsTree.map((department, index) => { - return ( - - ); - }); - - return ( -
    -
    - {this.props.isTreeLoading && } - {!this.props.isTreeLoading && -
    - {this.props.departmentsTree.length > 0 && departmentsTree} -
    - } -
    -
    - ); - } -} - -const WorkWeixinDepartmentsTreePanelPropTypes = { - isTreeLoading: PropTypes.bool.isRequired, - departmentsTree: PropTypes.array.isRequired, - onChangeDepartment: PropTypes.func.isRequired, - checkedDepartmentId: PropTypes.number.isRequired, -}; - -WorkWeixinDepartmentsTreePanel.propTypes = WorkWeixinDepartmentsTreePanelPropTypes; - +import Account from '../../components/common/account'; +import { WorkWeixinDepartmentMembersList, WorkWeixinDepartmentsTreePanel } from './work-weixin'; +import '../../css/work-weixin-departments.css'; class WorkWeixinDepartments extends Component { @@ -255,8 +42,7 @@ class WorkWeixinDepartments extends Component { let rootIds = parentIds.concat(intersection).filter((v) => { return parentIds.indexOf(v) === -1 || intersection.indexOf(v) === -1; }); - - let cloneData = JSON.parse(JSON.stringify(list)); + let cloneData = _.cloneDeep(list); return cloneData.filter(father => { let branchArr = cloneData.filter(child => father.id === child.parentid); branchArr.length > 0 ? father.children = branchArr : ''; @@ -272,16 +58,12 @@ class WorkWeixinDepartments extends Component { departmentsTree: departmentsTree, }); }).catch((error) => { + this.handleError(error); this.setState({ isTreeLoading: false, isMembersListLoading: false, }); - if (error.response) { - toaster.danger(error.response.data.error_msg || error.response.data.detail || gettext('Error'), {duration: 3}); - } else { - toaster.danger(gettext('Please check the network.'), {duration: 3}); - } - if (error.response.status === 403) { + if (error.response && error.response.status === 403) { window.location = siteRoot + 'sys/useradmin/'; } }); @@ -291,7 +73,7 @@ class WorkWeixinDepartments extends Component { this.setState({ isMembersListLoading: true, }); - seafileAPI.adminListWorkWeixinDepartmentMembers(department_id.toString(), {fetch_child: true}).then((res) => { + seafileAPI.adminListWorkWeixinDepartmentMembers(department_id, {fetch_child: true}).then((res) => { let membersTempObj = this.state.membersTempObj; membersTempObj[department_id] = res.data.userlist; let canCheckUserIds = this.getCanCheckUserIds(res.data.userlist); @@ -303,23 +85,16 @@ class WorkWeixinDepartments extends Component { }); }).catch((error) => { this.setState({isMembersListLoading: false}); - if (error.response) { - toaster.danger(error.response.data.error_msg || error.response.data.detail || gettext('Error'), {duration: 3}); - } else { - toaster.danger(gettext('Please check the network.'), {duration: 3}); - } + this.handleError(error); }); }; getCanCheckUserIds = (membersList) => { - let canCheckUserIds = []; - for (let i = 0; i < membersList.length; i++) { - let user = membersList[i]; - if (!user.email) { - canCheckUserIds.push(user.userid); - } - } - return canCheckUserIds; + let userIds = []; + membersList.forEach((member) => { + if (!member.email) userIds.push(member.userid); + }); + return userIds; }; onChangeDepartment = (department_id) => { @@ -345,21 +120,15 @@ class WorkWeixinDepartments extends Component { if (user.userid in newUsersTempObj) { delete newUsersTempObj[user.userid]; if (this.state.isCheckedAll) { - this.setState({ - isCheckedAll: false, - }); + this.setState({ isCheckedAll: false }); } } else { newUsersTempObj[user.userid] = user; if (Object.keys(newUsersTempObj).length === this.state.canCheckUserIds.length) { - this.setState({ - isCheckedAll: true, - }); + this.setState({ isCheckedAll: true }); } } - this.setState({ - newUsersTempObj: newUsersTempObj, - }); + this.setState({ newUsersTempObj: newUsersTempObj }); } }; @@ -372,124 +141,139 @@ class WorkWeixinDepartments extends Component { let newUsersTempList = this.state.membersList.filter(user => { return this.state.canCheckUserIds.indexOf(user.userid) !== -1; }); - for (let i = 0; i < newUsersTempList.length; i++) { newUsersTempObj[newUsersTempList[i].userid] = newUsersTempList[i]; } - this.setState({ - newUsersTempObj: newUsersTempObj, - }); + this.setState({ newUsersTempObj: newUsersTempObj }); } else { - this.setState({ - newUsersTempObj: {}, - }); + this.setState({ newUsersTempObj: {} }); } }); }; onSubmit = () => { + const { newUsersTempObj } = this.state; + if (JSON.stringify(newUsersTempObj) === '{}') return; let userList = []; - for (let i in this.state.newUsersTempObj) { - userList.push(this.state.newUsersTempObj[i]); + for (let i in newUsersTempObj) { + userList.push(newUsersTempObj[i]); } - if (!userList.length) { + if (userList.length === 0) { toaster.danger('未选择成员', {duration: 3}); - } else { - seafileAPI.adminAddWorkWeixinUsersBatch(userList).then((res) => { - this.setState({ - newUsersTempObj: {}, - isCheckedAll: false, - }); - if (res.data.success) { - let membersTempObj = this.state.membersTempObj; - let membersList = this.state.membersList; - let canCheckUserIds = this.state.canCheckUserIds; - for (let i = 0; i < res.data.success.length; i++) { - let userid = res.data.success[i].userid; - let name = res.data.success[i].name; - let email = res.data.success[i].email; - toaster.success(name + ' 成功导入', {duration: 1}); - // refresh all temp - if (canCheckUserIds.indexOf(userid) !== -1) { - canCheckUserIds.splice(canCheckUserIds.indexOf(userid), 1); - } - for (let j = 0; j < membersList.length; j++) { - if (membersList[j].userid === userid) { - membersList[j].email = email; - break; - } - } - for (let departmentId in membersTempObj) { - for (let k = 0; k < membersTempObj[departmentId].length; k++) { - if (membersTempObj[departmentId][k].userid === userid) { - membersTempObj[departmentId][k].email = email; - break; - } - } - } - } - this.setState({ - membersTempObj: membersTempObj, - membersList: membersList, - canCheckUserIds: canCheckUserIds, - }); - } - if (res.data.failed) { - for (let i = 0; i < res.data.failed.length; i++) { - let name = res.data.failed[i].name; - let errorMsg = res.data.failed[i].error_msg; - toaster.danger(name + ' ' + errorMsg, {duration: 3}); - } - } - }).catch((error) => { - if (error.response) { - toaster.danger(error.response.data.error_msg || error.response.data.detail || gettext('Error'), {duration: 3}); - } else { - toaster.danger(gettext('Please check the network.'), {duration: 3}); - } - }); + return; } + seafileAPI.adminAddWorkWeixinUsersBatch(userList).then((res) => { + this.setState({ + newUsersTempObj: {}, + isCheckedAll: false, + }); + if (res.data.success) { + this.handleSubmitSuccess(res.data.success); + } + if (res.data.failed) { + const fails= res.data.failed; + for (let i = 0; i < fails.length; i++) { + toaster.danger(fails[i].name + ' ' + fails[i].error_msg, {duration: 3}); + } + } + }).catch((error) => { + this.handleError(error); + }); }; + handleSubmitSuccess = (success) => { + let { membersTempObj, membersList, canCheckUserIds } = this.state; + for (let i = 0; i < success.length; i++) { + let { userid, name, email } = success[i]; + toaster.success(name + ' 成功导入', {duration: 1}); + // refresh all temp + if (canCheckUserIds.indexOf(userid) !== -1) { + canCheckUserIds.splice(canCheckUserIds.indexOf(userid), 1); + } + for (let j = 0; j < membersList.length; j++) { + if (membersList[j].userid === userid) { + membersList[j].email = email; + break; + } + } + for (let departmentId in membersTempObj) { + for (let k = 0; k < membersTempObj[departmentId].length; k++) { + if (membersTempObj[departmentId][k].userid === userid) { + membersTempObj[departmentId][k].email = email; + break; + } + } + } + } + this.setState({ + membersTempObj: membersTempObj, + membersList: membersList, + canCheckUserIds: canCheckUserIds, + }); + } + + handleError = (e) => { + if (e.response) { + toaster.danger(e.response.data.error_msg || e.response.data.detail || gettext('Error'), {duration: 3}); + } else { + toaster.danger(gettext('Please check the network.'), {duration: 3}); + } + } + componentDidMount() { this.getWorkWeixinDepartmentsList(); } - render() { + renderNav() { + const btnClass = 'btn btn-secondary operation-item '; return ( -
    -
    -
    -

    {'企业微信集成'}

    - {JSON.stringify(this.state.newUsersTempObj) !== '{}' && - - } -
    -
    - -
    - -
    +
    +
    + + + +
    +
    +
    ); } + + render() { + return ( + + {this.renderNav()} +
    +
    +
    +

    {'企业微信集成'}

    +
    +
    + +
    + +
    +
    +
    +
    + ); + } } export default WorkWeixinDepartments; - diff --git a/frontend/src/pages/sys-admin/work-weixin/index.js b/frontend/src/pages/sys-admin/work-weixin/index.js new file mode 100644 index 0000000000..e7fbbddf23 --- /dev/null +++ b/frontend/src/pages/sys-admin/work-weixin/index.js @@ -0,0 +1,5 @@ +import WorkWeixinDepartmentMembersList from './work-weixin-department-members-list'; +import WorkWeixinDepartmentsTreePanel from './work-weixin-departments-tree-panel'; +import WorkWeixinDepartmentsTreeNode from './work-weixin-departments-tree-node'; + +export { WorkWeixinDepartmentMembersList, WorkWeixinDepartmentsTreePanel, WorkWeixinDepartmentsTreeNode }; \ No newline at end of file diff --git a/frontend/src/pages/sys-admin/work-weixin/work-weixin-department-members-list.js b/frontend/src/pages/sys-admin/work-weixin/work-weixin-department-members-list.js new file mode 100644 index 0000000000..8238892ffb --- /dev/null +++ b/frontend/src/pages/sys-admin/work-weixin/work-weixin-department-members-list.js @@ -0,0 +1,84 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { Table } from 'reactstrap'; +import { siteRoot } from '../../../utils/constants'; +import Loading from '../../../components/loading'; + +const WorkWeixinDepartmentMembersListPropTypes = { + isMembersListLoading: PropTypes.bool.isRequired, + membersList: PropTypes.array.isRequired, + newUsersTempObj: PropTypes.object.isRequired, + checkedDepartmentId: PropTypes.number.isRequired, + onUserChecked: PropTypes.func.isRequired, + onAllUsersChecked: PropTypes.func.isRequired, + isCheckedAll: PropTypes.bool.isRequired, + canCheckUserIds: PropTypes.array.isRequired, +}; + +class WorkWeixinDepartmentMembersList extends Component { + + constructor(props) { + super(props); + } + + render() { + const { newUsersTempObj, checkedDepartmentId, isMembersListLoading, canCheckUserIds } = this.props; + const membersList = this.props.membersList.map((member, index) => { + let avatar = member.avatar; + if (member.avatar.length > 0) { + avatar = member.avatar.substring(0, member.avatar.length - 1) + '100';// get smaller avatar + } else { + avatar = siteRoot + 'media/avatars/default.png'; + } + return ( + + + {!member.email && + this.props.onUserChecked(member)} + checked={(member.userid in newUsersTempObj) ? 'checked' : ''}>} + + + {member.name} + {member.mobile} + {member.contact_email} + {member.email && } + + ); + }); + + return ( +
    + {isMembersListLoading && } + {!isMembersListLoading && this.props.membersList.length > 0 && + + + + + + + + + + + + {membersList} +
    + {canCheckUserIds.length > 0 && + this.props.onAllUsersChecked()}>} + {'名称'}{'手机号'}{'邮箱'}{'已添加'}
    + } + {!isMembersListLoading && this.props.membersList.length === 0 && +
    + +

    {'成员列表为空'}

    +
    + } +
    + ); + } +} + +WorkWeixinDepartmentMembersList.propTypes = WorkWeixinDepartmentMembersListPropTypes; + +export default WorkWeixinDepartmentMembersList; diff --git a/frontend/src/pages/sys-admin/work-weixin/work-weixin-departments-tree-node.js b/frontend/src/pages/sys-admin/work-weixin/work-weixin-departments-tree-node.js new file mode 100644 index 0000000000..a8495f415c --- /dev/null +++ b/frontend/src/pages/sys-admin/work-weixin/work-weixin-departments-tree-node.js @@ -0,0 +1,81 @@ +import React, { Component, Fragment } from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +const WorkWeixinDepartmentsTreeNodePropTypes = { + index: PropTypes.number, + department: PropTypes.object.isRequired, + isChildrenShow: PropTypes.bool.isRequired, + onChangeDepartment: PropTypes.func.isRequired, + checkedDepartmentId: PropTypes.number.isRequired, +}; + +class WorkWeixinDepartmentsTreeNode extends Component { + + constructor(props) { + super(props); + this.state = { + isChildrenShow: false, + }; + } + + toggleChildren = () => { + this.setState({ + isChildrenShow: !this.state.isChildrenShow, + }); + }; + + componentDidMount() { + if (this.props.index === 0) { + this.toggleChildren(); + this.props.onChangeDepartment(this.props.department.id); + } + } + + renderTreeNodes = (departmentsTree) => { + if (departmentsTree.length > 0) { + return departmentsTree.map((department) => { + return ( + + ); + }); + } + }; + + render() { + const { isChildrenShow, department, checkedDepartmentId } = this.props; + let toggleClass = classNames({ + 'folder-toggle-icon fa fa-caret-down': department.children && this.state.isChildrenShow, + 'folder-toggle-icon fa fa-caret-right': department.children && !this.state.isChildrenShow, + }) + let nodeInnerClass = classNames({ + 'tree-node-inner': true, + 'tree-node-hight-light': checkedDepartmentId === department.id + }); + return ( + + {isChildrenShow && +
    + this.toggleChildren()}>{' '} + this.props.onChangeDepartment(department.id)}>{department.name} +
    + } + {this.state.isChildrenShow && +
    + {department.children && this.renderTreeNodes(department.children)} +
    + } +
    + ); + } +} + +WorkWeixinDepartmentsTreeNode.propTypes = WorkWeixinDepartmentsTreeNodePropTypes; + +export default WorkWeixinDepartmentsTreeNode; diff --git a/frontend/src/pages/sys-admin/work-weixin/work-weixin-departments-tree-panel.js b/frontend/src/pages/sys-admin/work-weixin/work-weixin-departments-tree-panel.js new file mode 100644 index 0000000000..080d6e39a5 --- /dev/null +++ b/frontend/src/pages/sys-admin/work-weixin/work-weixin-departments-tree-panel.js @@ -0,0 +1,49 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Loading from '../../../components/loading'; +import WorkWeixinDepartmentsTreeNode from './work-weixin-departments-tree-node'; + +const WorkWeixinDepartmentsTreePanelPropTypes = { + isTreeLoading: PropTypes.bool.isRequired, + departmentsTree: PropTypes.array.isRequired, + onChangeDepartment: PropTypes.func.isRequired, + checkedDepartmentId: PropTypes.number.isRequired, +}; + +class WorkWeixinDepartmentsTreePanel extends Component { + + constructor(props) { + super(props); + } + + render() { + const { departmentsTree } = this.props; + return ( +
    +
    + {this.props.isTreeLoading ? + : +
    + {departmentsTree.length > 0 && departmentsTree.map((department, index) => { + return ( + + ); + })} +
    + } +
    +
    + ); + } +} + +WorkWeixinDepartmentsTreePanel.propTypes = WorkWeixinDepartmentsTreePanelPropTypes; + +export default WorkWeixinDepartmentsTreePanel; diff --git a/media/img/member-list-empty.png b/media/img/member-list-empty.png new file mode 100644 index 0000000000000000000000000000000000000000..8731b889f9c9c59590529aee0ba2fe75884fdace GIT binary patch literal 6846 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 literal 0 HcmV?d00001 From e519e57e7b2bbb585af772b5166df919dc2edbd2 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Sat, 1 Jun 2019 18:07:58 +0800 Subject: [PATCH 2/2] delete box shadow --- frontend/src/css/work-weixin-departments.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/css/work-weixin-departments.css b/frontend/src/css/work-weixin-departments.css index aaef1ec5b4..48926b5dbc 100644 --- a/frontend/src/css/work-weixin-departments.css +++ b/frontend/src/css/work-weixin-departments.css @@ -9,6 +9,9 @@ .dir-content-main table td { line-height: 2rem; } +.dir-content-main .empty-tip { + box-shadow: none; +} .dir-content-nav { width: 24%; overflow: hidden;