From e48a9cad97f27460bcbb948e96294c319caf1a20 Mon Sep 17 00:00:00 2001 From: llj Date: Wed, 15 Jan 2025 22:32:24 +0800 Subject: [PATCH] [system / org admin - departments] improved UI (the tree panel, 'New department', ...) (#7370) --- frontend/src/css/admin-common.css | 236 ------------------ frontend/src/css/system-departments-v2.css | 101 ++++---- .../pages/org-admin/departments/department.js | 10 +- .../departments-node-dropdown-menu.js | 1 - .../departments/departments-tree-panel.js | 10 +- .../org-admin/departments/departments.js | 21 +- .../pages/org-admin/departments/tree-node.js | 12 +- frontend/src/pages/org-admin/index.js | 1 - frontend/src/pages/org-admin/org-info.js | 2 +- .../pages/sys-admin/departments/department.js | 17 +- .../departments-node-dropdown-menu.js | 1 - .../departments/departments-tree-panel.js | 10 +- .../sys-admin/departments/departments.js | 8 +- .../pages/sys-admin/departments/tree-node.js | 12 +- frontend/src/pages/sys-admin/index.js | 1 - 15 files changed, 102 insertions(+), 341 deletions(-) delete mode 100644 frontend/src/css/admin-common.css diff --git a/frontend/src/css/admin-common.css b/frontend/src/css/admin-common.css deleted file mode 100644 index 131e20436c..0000000000 --- a/frontend/src/css/admin-common.css +++ /dev/null @@ -1,236 +0,0 @@ -.org-admin .info-item-heading, -.sys-admin .info-item-heading { - font-size: 15px; - font-weight: normal; - padding-bottom: 0.2em; - border-bottom: 1px solid #eee; - margin: 24px 0 0.7em; - color: inherit; -} - -.org-admin .side-nav-con svg.multicolor-icon, -.sys-admin .side-nav-con svg.multicolor-icon { - font-size: 20px; - width: 2rem; - color: #999; -} - -.org-admin .side-nav-con .active [class^='multicolor-icon'], -.sys-admin .side-nav-con .active [class^='multicolor-icon'] { - color: #fff; -} - -.org-admin .side-nav-title, -.sys-admin .side-nav-title { - color: #666666; - padding: 0 4px; - font-size: 15px; -} - -.org-admin .main-panel .heading, -.sys-admin .main-panel .heading { - height: 40px; - padding: 0 16px; - background: #f9f9f9; - font-size: 1rem; - font-weight: normal; - line-height: 40px; - margin: 0; - border-bottom: 1px solid #eee; -} - -.org-admin .main-panel .nav .nav-item .nav-link, -.sys-admin .main-panel .nav .nav-item .nav-link { - font-size: 16px; - border-bottom: 2px solid transparent; -} - -.org-admin .main-panel .nav .nav-item .nav-link.active, -.sys-admin .main-panel .nav .nav-item .nav-link.active { - color: #ED7109; - text-decoration: none; - border-bottom: 2px solid #ED7109; -} - -.org-admin .main-panel .cur-view-path:after, -.sys-admin .main-panel .cur-view-path:after { - display: none; -} - -.org-admin .text-secondary, -.sys-admin .text-secondary { - color: #999 !important; -} - -.org-admin .side-nav-con .nav .nav-item, -.sys-admin .side-nav-con .nav .nav-item { - font-size: 15px; -} - -.org-admin .side-nav-con .nav .nav-item .nav-link, -.sys-admin .side-nav-con .nav .nav-item .nav-link { - display: flex; - align-items: center; - width: 100%; - height: 36px; -} - -.org-table-icon { - padding-left: 10px; -} - -.org-info-content { - padding: 0rem 1rem; - background-color: #f5f5f5; - flex: 1 1; - overflow: auto; -} - -.org-info-content .info-header-content { - height: 106px; -} - -.info-header-content .info-header-id, -.info-header-content .info-header-name { - width: calc(50% - 5px); - background-color: #fff; - border-radius: 5px; - border: 1px solid #e4e4e4; -} - -.info-header-content .info-header-id img, -.info-header-content .info-header-name img { - width: 46px; - height: 46px; - margin: 30px 0 0 30px; -} - -.info-header-content .id-content, -.info-header-content .name-content { - width: 70%; - height: 50%; - margin: 28px 0 0 15px; -} - -.info-header-content .id-content p, -.info-header-content .name-content p { - font-size: 16px; - font-weight: 500; -} - -.info-header-content .id-content span, -.info-header-content .name-content span { - font-size: 14px; -} - -.org-info-content .info-user-content { - height: 180px; - background: #fff; - border-radius: 5px; - border: 1px solid #e4e4e4; -} - -.info-user-content .user-content-detail { - flex-direction: column; - width: calc(100% / 3); -} - -.info-user-content .user-content-detail p:first-child { - font-size: 16px; - font-weight: 500; - margin-top: 45px; -} - -.info-user-content .user-content-detail p:last-child { - font-size: 36px; - font-weight: 500; -} - -.org-info-content .used-storage-content { - height: 180px; -} - -.used-storage-content .used-space { - width: calc(50% - 5px); - flex-direction: column; - background-color: #fff; - border-radius: 5px; - border: 1px solid #e4e4e4; -} - -.used-storage-content .used-space p:first-child { - font-size: 16px; - font-weight: 500; - margin: 30px 0 0 30px; -} - -.used-storage-content .used-space p:nth-child(2) { - font-size: 30px; - font-weight: 500; - margin: 5px 0 0 30px; -} - -.used-storage-content .used-space span { - font-size: 13px; - font-weight: 400; - color: #aaa; - margin-left: 30px; -} - -/* mobile */ -@media (max-width: 767px) { - .org-info-content .info-header-content { - width: 100%; - height: auto; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .info-header-content .info-header-name, - .info-header-content .info-header-id { - width: 100%; - height: 100%; - display: inline-flex; - background-color: #fff; - border-radius: 5px; - } - - .info-header-content .info-header-id { - margin-top: 10px; - } - - .info-header-content .info-header-id img, - .info-header-content .info-header-name img { - margin: 30px 0 30px 30px; - } - - .org-info-content .used-storage-content { - height: auto; - flex-direction: column; - } - - .used-storage-content .used-space { - width: 100%; - } - - .used-storage-content .used-space span { - margin-bottom: 30px; - } -} - -/* Process bar style */ -.org-info-content .am-progress-outer { - height: 6px !important; - background: #eee; - margin-left: 30px; - width: 86%; - border-radius: 10px; - margin-top: 1.25rem; -} - -.org-info-content .am-progress-bar { - height: 6px !important; - border-radius: 5px; - background-color: #ED7109; -} diff --git a/frontend/src/css/system-departments-v2.css b/frontend/src/css/system-departments-v2.css index 412bc8fc55..eb5f32950c 100644 --- a/frontend/src/css/system-departments-v2.css +++ b/frontend/src/css/system-departments-v2.css @@ -4,102 +4,99 @@ .departments-tree-panel { width: 25%; - padding: 8px; border-right: 1px solid #eee; height: 100%; overflow: auto; } -.departments-tree-panel .departments-v2-hight-light { - color: #fff; - border-radius: 4px; - background-color: #ED7109 !important; -} - -.departments-tree-panel .departments-v2-hight-light i { - color: #fff; -} - .top-department-button-container { display: flex; align-items: center; justify-content: center; } -.departments-v2-tree-item { +.tree-node { position: relative; display: flex; - height: 24px; -} - -.departments-v2-tree-item:hover { - background-color: #ffefb2; - border-radius: 0.25rem; + align-items: center; + height: 28px; + border-radius: 4px; cursor: pointer; } -.departments-v2-tree-item .departments-v2-tree-icon { +.departments-tree-panel .tree-node.active { + border-radius: 4px; + background-color: #f5f5f5 !important; +} + +.departments-tree-panel .tree-node.active::before { + content: ''; + position: absolute; + display: block; + width: 4px; + left: -8px; + top: 2px; + bottom: 2px; + border-radius: 2px; + background-color: #ff9800; + z-index: 0; +} + +.tree-node:hover { + background-color: #f0f0f0; +} + +.tree-node .sf3-font { + color: #666; +} + +.tree-node .departments-v2-tree-icon { width: 24px; - text-align: center; - color: #b0b0b0; display: flex; align-items: center; justify-content: center; } -.departments-v2-tree-item .departments-v2-tree-node-text { +.tree-node .departments-v2-tree-node-text { flex: 1; padding-right: 4px; line-height: 24px; font-size: 14px; } -.departments-v2-tree-item .department-dropdown-menu { - width: 24px; - height: 24px; +.tree-node .right-icon { + width: 20px; + height: 20px; + border-radius: 3px; + cursor: pointer; display: flex; - align-items: center; justify-content: center; - color: #b0b0b0; -} - -.departments-v2-tree-item .department-action-icon { - width: 100%; - height: 100%; - display: flex; align-items: center; - justify-content: center; - color: #666666; } -.departments-v2-tree-item .department-action-icon:hover { - color: #212529; +.tree-node .right-icon:hover { + background-color: #dbdbdb; } -.departments-tree-panel .department-children { +.departments-tree-panel .tree-node-children { padding-left: 1rem; position: relative; } +.departments-tree-panel .new-dept-btn { + padding: 0 6px; +} + +.departments-tree-panel .new-dept-btn-icon { + font-size: 1rem; + color: #666; +} + .department-content-main { flex: 1; height: 100%; } -.department-content-main table td { - line-height: 2rem; -} - -.department-content-main .department-content-main-name { - height: 40px; - padding: 0 16px; - background: #f9f9f9; - font-size: 1rem; - line-height: 40px; - margin: 0; - border-bottom: 1px solid #eee; -} - .department-content-main .create-group-info { display: flex; flex-direction: column; diff --git a/frontend/src/pages/org-admin/departments/department.js b/frontend/src/pages/org-admin/departments/department.js index 6911d52c9f..5d4dfc83ff 100644 --- a/frontend/src/pages/org-admin/departments/department.js +++ b/frontend/src/pages/org-admin/departments/department.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Table, Dropdown, DropdownToggle } from 'reactstrap'; +import { Dropdown, DropdownToggle } from 'reactstrap'; import Loading from '../../../components/loading'; import EmptyTip from '../../../components/empty-tip'; import { gettext } from '../../../utils/constants'; @@ -113,8 +113,8 @@ class Department extends React.Component { return (
-
- {currentDepartment.name} +
+

{currentDepartment.name}

this.dropdownToggle(e)} @@ -156,7 +156,7 @@ class Department extends React.Component { {isMembersListLoading && } {!isMembersListLoading && membersList.length > 0 &&
- +
@@ -181,7 +181,7 @@ class Department extends React.Component { ); })} -
+
} {!isMembersListLoading && membersList.length === 0 && diff --git a/frontend/src/pages/org-admin/departments/departments-node-dropdown-menu.js b/frontend/src/pages/org-admin/departments/departments-node-dropdown-menu.js index 3606a9123b..00a886c8fa 100644 --- a/frontend/src/pages/org-admin/departments/departments-node-dropdown-menu.js +++ b/frontend/src/pages/org-admin/departments/departments-node-dropdown-menu.js @@ -6,7 +6,6 @@ import { gettext } from '../../../utils/constants'; function DepartmentNodeMenu({ node, toggleDelete, toggleRename, toggleAddMembers, toggleAddDepartment, toggleAddLibrary }) { return ( diff --git a/frontend/src/pages/org-admin/departments/departments-tree-panel.js b/frontend/src/pages/org-admin/departments/departments-tree-panel.js index 2bc46ad0b5..060c2ac7a8 100644 --- a/frontend/src/pages/org-admin/departments/departments-tree-panel.js +++ b/frontend/src/pages/org-admin/departments/departments-tree-panel.js @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import { gettext } from '../../../utils/constants'; import TreeNode from './tree-node'; const DepartmentsTreePanelPropTypes = { @@ -18,7 +19,7 @@ class DepartmentsTreePanel extends Component { render() { const { rootNodes, checkedDepartmentId } = this.props; return ( -
+
{rootNodes.map(rootNode => { return ( ); })} +
); } diff --git a/frontend/src/pages/org-admin/departments/departments.js b/frontend/src/pages/org-admin/departments/departments.js index 2ff8b0752f..5dccb308c1 100644 --- a/frontend/src/pages/org-admin/departments/departments.js +++ b/frontend/src/pages/org-admin/departments/departments.js @@ -4,7 +4,6 @@ import { Utils } from '../../../utils/utils'; import { gettext, orgID } from '../../../utils/constants'; import { orgAdminAPI } from '../../../utils/org-admin-api'; import toaster from '../../../components/toast'; -import Account from '../../../components/common/account'; import AddDepartmentDialog from '../../../components/dialog/sysadmin-dialog/add-department-v2-dialog'; import AddDepartMemberDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-add-depart-member-v2-dialog'; import RenameDepartmentDialog from '../../../components/dialog/sysadmin-dialog/rename-department-v2-dialog'; @@ -14,6 +13,7 @@ import Loading from '../../../components/loading'; import DepartmentNode from './department-node'; import DepartmentsTreePanel from './departments-tree-panel'; import Department from './department'; +import MainPanelTopbar from '../main-panel-topbar'; import '../../../css/system-departments-v2.css'; @@ -292,23 +292,12 @@ class Departments extends React.Component { isDeleteDepartmentDialogShow, sortBy, sortOrder } = this.state; return ( - -
-
- -
- -
-
-
- -
-
- +
-

{gettext('Departments')}

+
+

{gettext('Departments')}

+
{isTopDepartmentLoading && } {(!isTopDepartmentLoading && rootNodes.length > 0) && diff --git a/frontend/src/pages/org-admin/departments/tree-node.js b/frontend/src/pages/org-admin/departments/tree-node.js index efa29d16b7..8f81f78d33 100644 --- a/frontend/src/pages/org-admin/departments/tree-node.js +++ b/frontend/src/pages/org-admin/departments/tree-node.js @@ -110,8 +110,8 @@ class DepartmentsV2TreeNode extends Component { const { node, checkedDepartmentId } = this.props; const { isChildrenShow, dropdownOpen, active } = this.state; let nodeInnerClass = classNames({ - 'departments-v2-tree-item': true, - 'departments-v2-hight-light': checkedDepartmentId === node.id + 'tree-node': true, + 'active': checkedDepartmentId === node.id }); return ( @@ -134,17 +134,17 @@ class DepartmentsV2TreeNode extends Component { isOpen={dropdownOpen} toggle={(e) => this.dropdownToggle(e)} direction="down" - className="department-dropdown-menu" + className="mr-2" > - + {this.state.isChildrenShow && -
+
{node.children && this.renderTreeNodes(node.children)}
} diff --git a/frontend/src/pages/org-admin/index.js b/frontend/src/pages/org-admin/index.js index 69d20efae4..c2bb95df1e 100644 --- a/frontend/src/pages/org-admin/index.js +++ b/frontend/src/pages/org-admin/index.js @@ -40,7 +40,6 @@ import OrgSubscription from './org-subscription'; import '../../css/layout.css'; import '../../css/toolbar.css'; -import '../../css/admin-common.css'; class Org extends React.Component { constructor(props) { diff --git a/frontend/src/pages/org-admin/org-info.js b/frontend/src/pages/org-admin/org-info.js index b77d76e448..a4bb1a193f 100644 --- a/frontend/src/pages/org-admin/org-info.js +++ b/frontend/src/pages/org-admin/org-info.js @@ -47,7 +47,7 @@ class OrgInfo extends Component { download_traffic = download_traffic ? download_traffic : 0; return ( - +
diff --git a/frontend/src/pages/sys-admin/departments/department.js b/frontend/src/pages/sys-admin/departments/department.js index e3a8af49fa..7a7c0951e7 100644 --- a/frontend/src/pages/sys-admin/departments/department.js +++ b/frontend/src/pages/sys-admin/departments/department.js @@ -1,16 +1,15 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Table, Dropdown, DropdownToggle } from 'reactstrap'; +import { Dropdown, DropdownToggle } from 'reactstrap'; +import { gettext } from '../../../utils/constants'; import Paginator from '../../../components/paginator'; import Loading from '../../../components/loading'; import EmptyTip from '../../../components/empty-tip'; - -import { gettext } from '../../../utils/constants'; -import MemberItem from './member-item'; -import RepoItem from './repo-item'; import ModalPortal from '../../../components/modal-portal'; import DeleteRepoDialog from '../../../components/dialog/sysadmin-dialog/sysadmin-delete-repo-dialog'; import DepartmentNodeMenu from './departments-node-dropdown-menu'; +import MemberItem from './member-item'; +import RepoItem from './repo-item'; const propTypes = { rootNodes: PropTypes.array, @@ -137,8 +136,8 @@ class Department extends React.Component { return (
-
- {currentDepartment.name} +
+

{currentDepartment.name}

this.dropdownToggle(e)} @@ -183,7 +182,7 @@ class Department extends React.Component { ? : (
- +
@@ -208,7 +207,7 @@ class Department extends React.Component { ); })} -
+ {this.props.currentPageInfo && diff --git a/frontend/src/pages/sys-admin/departments/departments-tree-panel.js b/frontend/src/pages/sys-admin/departments/departments-tree-panel.js index e408e25a36..bd4eb7b275 100644 --- a/frontend/src/pages/sys-admin/departments/departments-tree-panel.js +++ b/frontend/src/pages/sys-admin/departments/departments-tree-panel.js @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import { gettext } from '../../../utils/constants'; import DepartmentTreeNode from './tree-node'; const DepartmentsTreePanelPropTypes = { @@ -18,7 +19,7 @@ class DepartmentsTreePanel extends Component { render() { const { rootNodes, checkedDepartmentId } = this.props; return ( -
+
{rootNodes.map(rootNode => { return ( ); })} +
); } diff --git a/frontend/src/pages/sys-admin/departments/departments.js b/frontend/src/pages/sys-admin/departments/departments.js index 2335514926..ad33581872 100644 --- a/frontend/src/pages/sys-admin/departments/departments.js +++ b/frontend/src/pages/sys-admin/departments/departments.js @@ -325,12 +325,12 @@ class Departments extends React.Component { isDeleteDepartmentDialogShow, sortBy, sortOrder } = this.state; return ( - - - +
-

{gettext('Departments')}

+
+

{gettext('Departments')}

+
{isTopDepartmentLoading && } {(!isTopDepartmentLoading && rootNodes.length > 0) && diff --git a/frontend/src/pages/sys-admin/departments/tree-node.js b/frontend/src/pages/sys-admin/departments/tree-node.js index 9df6f51df0..91d11a2f5a 100644 --- a/frontend/src/pages/sys-admin/departments/tree-node.js +++ b/frontend/src/pages/sys-admin/departments/tree-node.js @@ -110,8 +110,8 @@ class DepartmentsTreeNode extends Component { const { node, checkedDepartmentId } = this.props; const { isChildrenShow, dropdownOpen, active } = this.state; let nodeInnerClass = classNames({ - 'departments-v2-tree-item': true, - 'departments-v2-hight-light': checkedDepartmentId === node.id + 'tree-node': true, + 'active': checkedDepartmentId === node.id }); return ( @@ -134,17 +134,17 @@ class DepartmentsTreeNode extends Component { isOpen={dropdownOpen} toggle={(e) => this.dropdownToggle(e)} direction="down" - className="department-dropdown-menu" + className="mr-2" > - + {this.state.isChildrenShow && -
+
{node.children && this.renderTreeNodes(node.children)}
} diff --git a/frontend/src/pages/sys-admin/index.js b/frontend/src/pages/sys-admin/index.js index c2868a87b4..ce87778d17 100644 --- a/frontend/src/pages/sys-admin/index.js +++ b/frontend/src/pages/sys-admin/index.js @@ -86,7 +86,6 @@ import AbuseReports from './abuse-reports'; import '../../css/layout.css'; import '../../css/toolbar.css'; -import '../../css/admin-common.css'; class SysAdmin extends React.Component { constructor(props) {