mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-25 06:33:48 +00:00
fix nav tabs margin and indicator, animate notification tabs (#8024)
Co-authored-by: zhouwenxuan <aries@Mac.local>
This commit is contained in:
@@ -198,6 +198,10 @@
|
|||||||
color: #ED7109;
|
color: #ED7109;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-container .nav-indicator-container::before {
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.notification-container {
|
.notification-container {
|
||||||
right: -60px;
|
right: -60px;
|
||||||
|
@@ -3,13 +3,20 @@ import PropTypes from 'prop-types';
|
|||||||
import { Popover } from 'reactstrap';
|
import { Popover } from 'reactstrap';
|
||||||
import { gettext } from '../../../utils/constants';
|
import { gettext } from '../../../utils/constants';
|
||||||
import SeahubModalCloseIcon from '../seahub-modal-close';
|
import SeahubModalCloseIcon from '../seahub-modal-close';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
class NotificationPopover extends React.Component {
|
class NotificationPopover extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.itemRefs = [];
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
document.addEventListener('mousedown', this.handleOutsideClick, true);
|
document.addEventListener('mousedown', this.handleOutsideClick, true);
|
||||||
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@@ -39,6 +46,11 @@ class NotificationPopover extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { headerText = '', bodyText = '', footerText = '', currentTab, generalNoticeListUnseen, discussionNoticeListUnseen } = this.props;
|
const { headerText = '', bodyText = '', footerText = '', currentTab, generalNoticeListUnseen, discussionNoticeListUnseen } = this.props;
|
||||||
|
const activeIndex = currentTab === 'general' ? 0 : 1;
|
||||||
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
className="notification-wrapper"
|
className="notification-wrapper"
|
||||||
@@ -55,15 +67,29 @@ class NotificationPopover extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className="notification-body">
|
<div className="notification-body">
|
||||||
<div className="mark-notifications">
|
<div className="mark-notifications">
|
||||||
<ul className="nav">
|
<ul
|
||||||
<li className="nav-item" onClick={() => this.tabItemClick('general')}>
|
className="nav nav-indicator-container position-relative"
|
||||||
<span className={`nav-link ${currentTab === 'general' ? 'active' : ''}`}>
|
style={{
|
||||||
|
'--indicator-width': `${indicatorWidth}px`,
|
||||||
|
'--indicator-offset': `${indicatorOffset}px`
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
className="nav-item mx-3"
|
||||||
|
ref={el => this.itemRefs[0] = el}
|
||||||
|
onClick={() => this.tabItemClick('general')}
|
||||||
|
>
|
||||||
|
<span className={`m-0 nav-link ${currentTab === 'general' ? 'active' : ''}`}>
|
||||||
{gettext('General')}
|
{gettext('General')}
|
||||||
{generalNoticeListUnseen > 0 && <span>({generalNoticeListUnseen})</span>}
|
{generalNoticeListUnseen > 0 && <span>({generalNoticeListUnseen})</span>}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li className="nav-item" onClick={() => this.tabItemClick('discussion')}>
|
<li
|
||||||
<span className={`nav-link ${currentTab === 'discussion' ? 'active' : ''}`}>
|
className="nav-item mx-3"
|
||||||
|
ref={el => this.itemRefs[1] = el}
|
||||||
|
onClick={() => this.tabItemClick('discussion')}
|
||||||
|
>
|
||||||
|
<span className={`m-0 nav-link ${currentTab === 'discussion' ? 'active' : ''}`}>
|
||||||
{gettext('Discussion')}
|
{gettext('Discussion')}
|
||||||
{discussionNoticeListUnseen > 0 && <span>({discussionNoticeListUnseen})</span>}
|
{discussionNoticeListUnseen > 0 && <span>({discussionNoticeListUnseen})</span>}
|
||||||
</span>
|
</span>
|
||||||
|
@@ -75,3 +75,5 @@ export const SEARCH_FILTER_BY_DATE_TYPE_KEY = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const SEARCH_FILTERS_SHOW_KEY = 'search_filters_show';
|
export const SEARCH_FILTERS_SHOW_KEY = 'search_filters_show';
|
||||||
|
|
||||||
|
export const NAV_ITEM_MARGIN = 12;
|
||||||
|
@@ -356,14 +356,19 @@ img[src=""],img:not([src]) { /* for first loading img*/
|
|||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-indicator-container .nav-item {
|
||||||
|
min-width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
.nav-indicator-container .nav-item .nav-link {
|
.nav-indicator-container .nav-item .nav-link {
|
||||||
border: none;
|
border: none;
|
||||||
|
min-width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-indicator-container::before {
|
.nav-indicator-container::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: -2px;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
width: var(--indicator-width);
|
width: var(--indicator-width);
|
||||||
background: #ED7109;
|
background: #ED7109;
|
||||||
|
@@ -13,6 +13,8 @@ import '../../css/files-activities.css';
|
|||||||
|
|
||||||
dayjs.locale(window.app.config.lang);
|
dayjs.locale(window.app.config.lang);
|
||||||
|
|
||||||
|
const NAV_ITEM_MARGIN = 16;
|
||||||
|
|
||||||
class FilesActivities extends Component {
|
class FilesActivities extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -34,7 +36,6 @@ class FilesActivities extends Component {
|
|||||||
this.oldPathList = [];
|
this.oldPathList = [];
|
||||||
this.availableUserEmails = new Set();
|
this.availableUserEmails = new Set();
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -80,24 +81,13 @@ class FilesActivities extends Component {
|
|||||||
this.setState({ onlyMine: isMyActivities });
|
this.setState({ onlyMine: isMyActivities });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.measureItems();
|
this.forceUpdate();
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
|
||||||
if (this.state.onlyMine !== prevState.onlyMine) {
|
|
||||||
this.measureItems();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.unlisten && this.unlisten();
|
this.unlisten && this.unlisten();
|
||||||
}
|
}
|
||||||
|
|
||||||
measureItems = () => {
|
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
|
||||||
this.forceUpdate();
|
|
||||||
};
|
|
||||||
|
|
||||||
mergePublishEvents = (events) => {
|
mergePublishEvents = (events) => {
|
||||||
events.forEach((item) => {
|
events.forEach((item) => {
|
||||||
if (item.op_type === 'publish') {
|
if (item.op_type === 'publish') {
|
||||||
@@ -255,8 +245,9 @@ class FilesActivities extends Component {
|
|||||||
render() {
|
render() {
|
||||||
const { targetUsers, availableUsers, onlyMine } = this.state;
|
const { targetUsers, availableUsers, onlyMine } = this.state;
|
||||||
const activeIndex = onlyMine ? 1 : 0;
|
const activeIndex = onlyMine ? 1 : 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 78;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
return (
|
return (
|
||||||
<div className="main-panel-center">
|
<div className="main-panel-center">
|
||||||
<div className="cur-view-container" id="activities">
|
<div className="cur-view-container" id="activities">
|
||||||
@@ -268,10 +259,10 @@ class FilesActivities extends Component {
|
|||||||
'--indicator-offset': `${indicatorOffset}px`
|
'--indicator-offset': `${indicatorOffset}px`
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<li className="nav-item px-4" ref={el => this.itemRefs[0] = el}>
|
<li className="nav-item mx-4" ref={el => this.itemRefs[0] = el}>
|
||||||
<Link to={`${siteRoot}dashboard/`} className={`nav-link${onlyMine ? '' : ' active'}`}>{gettext('All Activities')}</Link>
|
<Link to={`${siteRoot}dashboard/`} className={`nav-link${onlyMine ? '' : ' active'}`}>{gettext('All Activities')}</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className="nav-item px-4" ref={el => this.itemRefs[1] = el}>
|
<li className="nav-item mx-4" ref={el => this.itemRefs[1] = el}>
|
||||||
<Link to={`${siteRoot}my-activities/`} className={`nav-link${onlyMine ? ' active' : ''}`}>{gettext('My Activities')}</Link>
|
<Link to={`${siteRoot}my-activities/`} className={`nav-link${onlyMine ? ' active' : ''}`}>{gettext('My Activities')}</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext } from '../../../utils/constants';
|
import { siteRoot, gettext } from '../../../utils/constants';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentItem: PropTypes.string.isRequired
|
currentItem: PropTypes.string.isRequired
|
||||||
@@ -16,18 +17,18 @@ class LogsNav extends React.Component {
|
|||||||
{ name: 'login', urlPart: 'admin-logs/login', text: gettext('Admin Login Logs') },
|
{ name: 'login', urlPart: 'admin-logs/login', text: gettext('Admin Login Logs') },
|
||||||
];
|
];
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth || 0);
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentItem } = this.props;
|
const { currentItem } = this.props;
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 167;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((prev, cur) => prev + cur, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((prev, cur) => prev + cur, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
return (
|
return (
|
||||||
<div className="cur-view-path tab-nav-container">
|
<div className="cur-view-path tab-nav-container">
|
||||||
<ul
|
<ul
|
||||||
@@ -40,11 +41,11 @@ class LogsNav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`m-0 nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext, isPro } from '../../../utils/constants';
|
import { siteRoot, gettext, isPro } from '../../../utils/constants';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentItem: PropTypes.string.isRequired
|
currentItem: PropTypes.string.isRequired
|
||||||
@@ -19,22 +20,18 @@ class Nav extends React.Component {
|
|||||||
this.navItems.push({ name: 'errors', urlPart: 'errors', text: gettext('Errors') });
|
this.navItems.push({ name: 'errors', urlPart: 'errors', text: gettext('Errors') });
|
||||||
}
|
}
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.measureItems();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
measureItems = () => {
|
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth || 77);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentItem } = this.props;
|
const { currentItem } = this.props;
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 77;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="cur-view-path tab-nav-container">
|
<div className="cur-view-path tab-nav-container">
|
||||||
@@ -48,11 +45,11 @@ class Nav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/devices/${item.urlPart}/`} className={`nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/devices/${item.urlPart}/`} className={`m-0 nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext } from '../../../utils/constants';
|
import { siteRoot, gettext } from '../../../utils/constants';
|
||||||
import SortMenu from '../../../components/sort-menu';
|
import SortMenu from '../../../components/sort-menu';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentItem: PropTypes.string.isRequired,
|
currentItem: PropTypes.string.isRequired,
|
||||||
@@ -27,11 +28,10 @@ class Nav extends React.Component {
|
|||||||
{ value: 'view_cnt-desc', text: gettext('Descending by visit count') }
|
{ value: 'view_cnt-desc', text: gettext('Descending by visit count') }
|
||||||
];
|
];
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth || 98);
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectSortOption = (item) => {
|
onSelectSortOption = (item) => {
|
||||||
@@ -43,8 +43,9 @@ class Nav extends React.Component {
|
|||||||
const { currentItem, sortBy, sortOrder } = this.props;
|
const { currentItem, sortBy, sortOrder } = this.props;
|
||||||
const showSortIcon = currentItem == 'shareLinks';
|
const showSortIcon = currentItem == 'shareLinks';
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 98;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
return (
|
return (
|
||||||
<div className="cur-view-path tab-nav-container">
|
<div className="cur-view-path tab-nav-container">
|
||||||
<ul
|
<ul
|
||||||
@@ -57,11 +58,11 @@ class Nav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`m-0 nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext } from '../../../utils/constants';
|
import { siteRoot, gettext } from '../../../utils/constants';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentItem: PropTypes.string.isRequired
|
currentItem: PropTypes.string.isRequired
|
||||||
@@ -20,18 +21,18 @@ class Nav extends React.Component {
|
|||||||
{ name: 'groupMember', urlPart: 'logs/group-member-audit', text: gettext('Group Member') },
|
{ name: 'groupMember', urlPart: 'logs/group-member-audit', text: gettext('Group Member') },
|
||||||
];
|
];
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth) || 59;
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentItem } = this.props;
|
const { currentItem } = this.props;
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 59;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const leftOffset = this.itemWidths.slice(0, activeIndex).reduce((prev, cur) => prev + cur, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const leftOffset = itemWidths.slice(0, activeIndex).reduce((prev, cur) => prev + cur, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
return (
|
return (
|
||||||
<div className="cur-view-path tab-nav-container">
|
<div className="cur-view-path tab-nav-container">
|
||||||
<ul
|
<ul
|
||||||
@@ -44,11 +45,11 @@ class Nav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`m-0 nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext } from '../../../utils/constants';
|
import { siteRoot, gettext } from '../../../utils/constants';
|
||||||
import SortMenu from '../../../components/sort-menu';
|
import SortMenu from '../../../components/sort-menu';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentItem: PropTypes.string.isRequired,
|
currentItem: PropTypes.string.isRequired,
|
||||||
@@ -25,17 +26,10 @@ class Nav extends React.Component {
|
|||||||
{ value: 'size-desc', text: gettext('Descending by size') }
|
{ value: 'size-desc', text: gettext('Descending by size') }
|
||||||
];
|
];
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.measureItems();
|
this.forceUpdate();
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
|
||||||
if (this.props.currentItem !== prevProps.currentItem) {
|
|
||||||
this.measureItems();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectSortOption = (item) => {
|
onSelectSortOption = (item) => {
|
||||||
@@ -43,17 +37,13 @@ class Nav extends React.Component {
|
|||||||
this.props.sortItems(sortBy);
|
this.props.sortItems(sortBy);
|
||||||
};
|
};
|
||||||
|
|
||||||
measureItems = () => {
|
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth || 77);
|
|
||||||
this.forceUpdate();
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentItem, sortBy, sortOrder = 'desc' } = this.props;
|
const { currentItem, sortBy, sortOrder = 'desc' } = this.props;
|
||||||
const showSortIcon = currentItem == 'all-libraries' || currentItem == 'all-wikis';
|
const showSortIcon = currentItem == 'all-libraries' || currentItem == 'all-wikis';
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 56;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="cur-view-path tab-nav-container">
|
<div className="cur-view-path tab-nav-container">
|
||||||
@@ -67,11 +57,11 @@ class Nav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`m-0 nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext } from '../../../utils/constants';
|
import { siteRoot, gettext } from '../../../utils/constants';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentItem: PropTypes.string.isRequired
|
currentItem: PropTypes.string.isRequired
|
||||||
@@ -20,22 +21,18 @@ class Nav extends React.Component {
|
|||||||
{ name: 'metricsStatistic', urlPart: 'statistics/metrics', text: gettext('Metrics') },
|
{ name: 'metricsStatistic', urlPart: 'statistics/metrics', text: gettext('Metrics') },
|
||||||
];
|
];
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.measureItems();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
measureItems = () => {
|
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth || 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentItem } = this.props;
|
const { currentItem } = this.props;
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem);
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem);
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 56;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="cur-view-path tab-nav-container">
|
<div className="cur-view-path tab-nav-container">
|
||||||
@@ -49,11 +46,11 @@ class Nav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`m-0 nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext } from '../../../utils/constants';
|
import { siteRoot, gettext } from '../../../utils/constants';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
email: PropTypes.string,
|
email: PropTypes.string,
|
||||||
@@ -21,22 +22,18 @@ class Nav extends React.Component {
|
|||||||
{ name: 'groups', urlPart: 'groups', text: gettext('Groups') }
|
{ name: 'groups', urlPart: 'groups', text: gettext('Groups') }
|
||||||
];
|
];
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.measureItems();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
measureItems = () => {
|
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth || 77);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentItem, email, userName } = this.props;
|
const { currentItem, email, userName } = this.props;
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 56;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-path">
|
||||||
@@ -52,11 +49,11 @@ class Nav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/user/${encodeURIComponent(email)}/${item.urlPart}`} className={`nav-link mx-3 ${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/user/${encodeURIComponent(email)}/${item.urlPart}`} className={`nav-link m-0 ${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext, haveLDAP, isDefaultAdmin } from '../../../utils/constants';
|
import { siteRoot, gettext, haveLDAP, isDefaultAdmin } from '../../../utils/constants';
|
||||||
import SortMenu from '../../../components/sort-menu';
|
import SortMenu from '../../../components/sort-menu';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentItem: PropTypes.string.isRequired,
|
currentItem: PropTypes.string.isRequired,
|
||||||
@@ -35,11 +36,10 @@ class Nav extends React.Component {
|
|||||||
];
|
];
|
||||||
|
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.measureItems();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectSortOption = (item) => {
|
onSelectSortOption = (item) => {
|
||||||
@@ -47,16 +47,13 @@ class Nav extends React.Component {
|
|||||||
this.props.sortItems(sortBy, sortOrder);
|
this.props.sortItems(sortBy, sortOrder);
|
||||||
};
|
};
|
||||||
|
|
||||||
measureItems = () => {
|
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth || 77);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentItem, sortBy, sortOrder } = this.props;
|
const { currentItem, sortBy, sortOrder } = this.props;
|
||||||
const showSortIcon = currentItem == 'database' || currentItem == 'ldap-imported';
|
const showSortIcon = currentItem == 'database' || currentItem == 'ldap-imported';
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 85;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((a, b) => a + b, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="cur-view-path tab-nav-container">
|
<div className="cur-view-path tab-nav-container">
|
||||||
@@ -70,11 +67,11 @@ class Nav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/${item.urlPart}/`} className={`m-0 nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from '@gatsbyjs/reach-router';
|
import { Link } from '@gatsbyjs/reach-router';
|
||||||
import { siteRoot, gettext } from '../../../utils/constants';
|
import { siteRoot, gettext } from '../../../utils/constants';
|
||||||
|
import { NAV_ITEM_MARGIN } from '../../../constants';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentItem: PropTypes.string.isRequired
|
currentItem: PropTypes.string.isRequired
|
||||||
@@ -16,18 +17,18 @@ class Nav extends React.Component {
|
|||||||
{ name: 'unhandled', urlPart: 'unhandled', text: gettext('Unhandled') }
|
{ name: 'unhandled', urlPart: 'unhandled', text: gettext('Unhandled') }
|
||||||
];
|
];
|
||||||
this.itemRefs = [];
|
this.itemRefs = [];
|
||||||
this.itemWidths = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.itemWidths = this.itemRefs.map(ref => ref?.offsetWidth) || 59;
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentItem } = this.props;
|
const { currentItem } = this.props;
|
||||||
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
const activeIndex = this.navItems.findIndex(item => item.name === currentItem) || 0;
|
||||||
const indicatorWidth = this.itemWidths[activeIndex] || 59;
|
const itemWidths = this.itemRefs.map(ref => ref?.offsetWidth);
|
||||||
const indicatorOffset = this.itemWidths.slice(0, activeIndex).reduce((prev, cur) => prev + cur, 0);
|
const indicatorWidth = itemWidths[activeIndex];
|
||||||
|
const indicatorOffset = itemWidths.slice(0, activeIndex).reduce((prev, cur) => prev + cur, 0) + (2 * activeIndex + 1) * NAV_ITEM_MARGIN;
|
||||||
return (
|
return (
|
||||||
<div className="cur-view-path tab-nav-container">
|
<div className="cur-view-path tab-nav-container">
|
||||||
<ul
|
<ul
|
||||||
@@ -40,11 +41,11 @@ class Nav extends React.Component {
|
|||||||
{this.navItems.map((item, index) => {
|
{this.navItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className="nav-item"
|
className="nav-item mx-3"
|
||||||
key={index}
|
key={index}
|
||||||
ref={el => this.itemRefs[index] = el}
|
ref={el => this.itemRefs[index] = el}
|
||||||
>
|
>
|
||||||
<Link to={`${siteRoot}sys/virus-files/${item.urlPart}/`} className={`nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
<Link to={`${siteRoot}sys/virus-files/${item.urlPart}/`} className={`m-0 nav-link${currentItem == item.name ? ' active' : ''}`}>{item.text}</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
Reference in New Issue
Block a user