mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-06 09:21:54 +00:00
change Wiki2 search UI (#7000)
* change Wiki2 search UI * change style when no pages
This commit is contained in:
@@ -22,7 +22,6 @@ const propTypes = {
|
|||||||
onSearchedClick: PropTypes.func.isRequired,
|
onSearchedClick: PropTypes.func.isRequired,
|
||||||
isPublic: PropTypes.bool,
|
isPublic: PropTypes.bool,
|
||||||
isViewFile: PropTypes.bool,
|
isViewFile: PropTypes.bool,
|
||||||
isWiki2: PropTypes.bool,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const PER_PAGE = 20;
|
const PER_PAGE = 20;
|
||||||
@@ -552,23 +551,6 @@ class Search extends Component {
|
|||||||
renderSearchTypes = (inputValue) => {
|
renderSearchTypes = (inputValue) => {
|
||||||
const highlightIndex = this.state.highlightSearchTypesIndex;
|
const highlightIndex = this.state.highlightSearchTypesIndex;
|
||||||
const { resultItems } = this.state;
|
const { resultItems } = this.state;
|
||||||
if (this.props.isWiki2) {
|
|
||||||
return (
|
|
||||||
<div className="search-types">
|
|
||||||
<div
|
|
||||||
className="search-types-wiki search-types-highlight"
|
|
||||||
onClick={this.searchWiki}
|
|
||||||
tabIndex={0}
|
|
||||||
>
|
|
||||||
<i className="search-icon-left input-icon-addon sf3-font sf3-font-search"></i>
|
|
||||||
{inputValue}
|
|
||||||
<span className="search-types-text">{gettext('in this wiki')}</span>
|
|
||||||
<i className="sf3-font sf3-font-enter"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.props.repoID) {
|
if (!this.props.repoID) {
|
||||||
return (
|
return (
|
||||||
<div className="search-result-list-container" ref={this.searchResultListContainerRef}>
|
<div className="search-result-list-container" ref={this.searchResultListContainerRef}>
|
||||||
@@ -687,69 +669,6 @@ class Search extends Component {
|
|||||||
this.getSearchResult(queryData);
|
this.getSearchResult(queryData);
|
||||||
};
|
};
|
||||||
|
|
||||||
getWikiSearchResult = (queryData) => {
|
|
||||||
if (this.source) {
|
|
||||||
this.source.cancel('prev request is cancelled');
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
isLoading: true,
|
|
||||||
isResultGetted: false,
|
|
||||||
resultItems: [],
|
|
||||||
highlightIndex: 0,
|
|
||||||
});
|
|
||||||
this.source = seafileAPI.getSource();
|
|
||||||
|
|
||||||
const query = queryData.q;
|
|
||||||
const search_wiki = this.props.repoID;
|
|
||||||
|
|
||||||
searchAPI.searchWiki(query, search_wiki, this.source.token).then(res => {
|
|
||||||
this.source = null;
|
|
||||||
if (res.data.total > 0) {
|
|
||||||
this.setState({
|
|
||||||
resultItems: this.formatWikiResultItems(res.data.results),
|
|
||||||
isResultGetted: true,
|
|
||||||
isLoading: false,
|
|
||||||
page: 1,
|
|
||||||
hasMore: res.data.has_more,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
highlightIndex: 0,
|
|
||||||
resultItems: [],
|
|
||||||
isLoading: false,
|
|
||||||
isResultGetted: true,
|
|
||||||
hasMore: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
|
||||||
toaster.danger(errMessage);
|
|
||||||
this.setState({ isLoading: false });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
formatWikiResultItems(data) {
|
|
||||||
return data.map((item, index) => ({
|
|
||||||
index: [index],
|
|
||||||
name: item.name,
|
|
||||||
path: item.path,
|
|
||||||
repo_id: item.repo_id,
|
|
||||||
repo_name: item.repo_name,
|
|
||||||
is_dir: false,
|
|
||||||
link_content: item.path,
|
|
||||||
content: item.content_highlight,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
searchWiki = () => {
|
|
||||||
const { value } = this.state;
|
|
||||||
const queryData = {
|
|
||||||
q: value,
|
|
||||||
search_repo: this.props.repoID,
|
|
||||||
};
|
|
||||||
this.getWikiSearchResult(queryData);
|
|
||||||
};
|
|
||||||
|
|
||||||
renderResults = (resultItems, isVisited) => {
|
renderResults = (resultItems, isVisited) => {
|
||||||
const { highlightIndex, hasMore, searchPageUrl } = this.state;
|
const { highlightIndex, hasMore, searchPageUrl } = this.state;
|
||||||
|
|
||||||
|
47
frontend/src/components/search/wiki2-search-result.css
Normal file
47
frontend/src/components/search/wiki2-search-result.css
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
.wiki2-search-result {
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-result-current {
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #757575;
|
||||||
|
background-color: #eaeaea;
|
||||||
|
padding: 0 4px;
|
||||||
|
margin: 0 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-result-top .wiki2-search-result-page-name {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-result-bottom {
|
||||||
|
padding-left: 36px;
|
||||||
|
padding-right: 36px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-result-bottom mark {
|
||||||
|
padding: 0;
|
||||||
|
background: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-result:hover,
|
||||||
|
.wiki2-search-result.wiki2-search-result-highlight {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #F7F7F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-result-enter.sf3-font-enter {
|
||||||
|
opacity: 0;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-result:hover .wiki2-search-result-enter.sf3-font-enter {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
47
frontend/src/components/search/wiki2-search-result.js
Normal file
47
frontend/src/components/search/wiki2-search-result.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import NavItemIcon from '../../pages/wiki2/common/nav-item-icon';
|
||||||
|
import CustomIcon from '../../pages/wiki2/custom-icon';
|
||||||
|
import { gettext } from '../../utils/constants';
|
||||||
|
|
||||||
|
import './wiki2-search-result.css';
|
||||||
|
|
||||||
|
function Wiki2SearchResult({ result, currentPageId, setCurrentPage, resetToDefault, setRef, isHighlight }) {
|
||||||
|
const { content, page } = result;
|
||||||
|
const isCurrentPage = currentPageId === page.id;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames('wiki2-search-result', { 'wiki2-search-result-highlight': isHighlight })}
|
||||||
|
onClick={() => { setCurrentPage(page.id); resetToDefault(); }}
|
||||||
|
ref={ref => setRef(ref)}
|
||||||
|
>
|
||||||
|
<div className='wiki2-search-result-top d-flex align-items-center'>
|
||||||
|
{page.icon ? <CustomIcon icon={page.icon} /> : <NavItemIcon symbol={'file'} disable={true} />}
|
||||||
|
<span className='wiki2-search-result-page-name text-truncate' title={page.name} style={isCurrentPage ? { width: 'auto' } : { width: 700 }}>{page.name}</span>
|
||||||
|
{currentPageId === page.id ?
|
||||||
|
<span className='wiki2-search-result-current'>{gettext('Current page')}</span> :
|
||||||
|
<span className='wiki2-search-result-enter sf3-font sf3-font-enter' style={isHighlight ? { opacity: 1 } : {}}></span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
{content ?
|
||||||
|
<div className='wiki2-search-result-bottom'>
|
||||||
|
<p dangerouslySetInnerHTML={{ __html: content }} ></p>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div className='py-1'></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Wiki2SearchResult.propTypes = {
|
||||||
|
result: PropTypes.object.isRequired,
|
||||||
|
currentPageId: PropTypes.string.isRequired,
|
||||||
|
setCurrentPage: PropTypes.func.isRequired,
|
||||||
|
resetToDefault: PropTypes.func.isRequired,
|
||||||
|
setRef: PropTypes.func.isRequired,
|
||||||
|
isHighlight: PropTypes.bool.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Wiki2SearchResult;
|
50
frontend/src/components/search/wiki2-search.css
Normal file
50
frontend/src/components/search/wiki2-search.css
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
.wiki2-search {
|
||||||
|
margin: 10px 8px 10px;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #EDEDEA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search .sf3-font-search {
|
||||||
|
margin: 0 8px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-input {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-input .sf3-font-search {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
color: #9aa0ac;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 2.5rem;
|
||||||
|
pointer-events: none;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-input .form-control {
|
||||||
|
padding-left: 2.5rem;
|
||||||
|
height: 38px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki2-search-result-container {
|
||||||
|
min-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
margin-right: -16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
|
205
frontend/src/components/search/wiki2-search.js
Normal file
205
frontend/src/components/search/wiki2-search.js
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
import React, { useCallback, useState, useRef, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Modal, ModalBody, Input } from 'reactstrap';
|
||||||
|
import isHotkey from 'is-hotkey';
|
||||||
|
import searchAPI from '../../utils/search-api';
|
||||||
|
import { gettext } from '../../utils/constants';
|
||||||
|
import { Utils } from '../../utils/utils';
|
||||||
|
import toaster from '../toast';
|
||||||
|
import Loading from '../loading';
|
||||||
|
import Wiki2SearchResult from './wiki2-search-result';
|
||||||
|
import { isModF } from '../../metadata/utils/hotkey';
|
||||||
|
|
||||||
|
import './wiki2-search.css';
|
||||||
|
|
||||||
|
const isEnter = isHotkey('enter');
|
||||||
|
const isUp = isHotkey('up');
|
||||||
|
const isDown = isHotkey('down');
|
||||||
|
|
||||||
|
function Wiki2Search({ setCurrentPage, config, currentPageId, wikiId }) {
|
||||||
|
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const [value, setValue] = useState('');
|
||||||
|
const [results, setResults] = useState([]);
|
||||||
|
const [highlightIndex, setHighlightIndex] = useState(-1);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [isResultGetted, setIsResultGetted] = useState(false);
|
||||||
|
let searchResultListContainerRef = useRef(null);
|
||||||
|
let highlightRef = useRef(null);
|
||||||
|
|
||||||
|
const onDocumentKeyDown = useCallback((e) => {
|
||||||
|
if (!isModalOpen && isModF(e)) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsModalOpen(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, [isModalOpen]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('keydown', onDocumentKeyDown);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('keydown', onDocumentKeyDown);
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const resetToDefault = useCallback(() => {
|
||||||
|
setValue('');
|
||||||
|
setHighlightIndex(0);
|
||||||
|
setResults([]);
|
||||||
|
setIsResultGetted(false);
|
||||||
|
setIsModalOpen(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onKeyDown = useCallback((e) => {
|
||||||
|
if (isHotkey('esc', e)) {
|
||||||
|
resetToDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isResultGetted) {
|
||||||
|
if (isEnter(e)) {
|
||||||
|
const hightlightResult = results[highlightIndex];
|
||||||
|
if (hightlightResult && hightlightResult.page.id !== currentPageId) {
|
||||||
|
setCurrentPage(hightlightResult.page.id);
|
||||||
|
resetToDefault();
|
||||||
|
}
|
||||||
|
} else if (isUp(e)) {
|
||||||
|
onUp(e, highlightIndex);
|
||||||
|
} else if (isDown(e)) {
|
||||||
|
onDown(e, results, highlightIndex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isEnter(e)) {
|
||||||
|
getWikiSearchResult(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [isResultGetted, value, results, highlightIndex, currentPageId]);
|
||||||
|
|
||||||
|
const onUp = useCallback((e, highlightIndex) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
if (highlightIndex > 0) {
|
||||||
|
setHighlightIndex(highlightIndex - 1);
|
||||||
|
setTimeout(() => {
|
||||||
|
if (highlightRef.current) {
|
||||||
|
const { top, height } = highlightRef.current.getBoundingClientRect();
|
||||||
|
if (top - height < 0) {
|
||||||
|
searchResultListContainerRef.current.scrollTop -= height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onDown = useCallback((e, results, highlightIndex) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
if (highlightIndex < results.length - 1) {
|
||||||
|
setHighlightIndex(highlightIndex + 1);
|
||||||
|
setTimeout(() => {
|
||||||
|
if (highlightRef.current) {
|
||||||
|
const { top, height } = highlightRef.current.getBoundingClientRect();
|
||||||
|
const outerHeight = 300;
|
||||||
|
if (top > outerHeight) {
|
||||||
|
const newScrollTop = searchResultListContainerRef.current.scrollTop + height;
|
||||||
|
searchResultListContainerRef.current.scrollTop = newScrollTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getWikiSearchResult = useCallback((searchValue) => {
|
||||||
|
if (!searchValue.trim()) return;
|
||||||
|
setIsLoading(true);
|
||||||
|
setHighlightIndex(-1);
|
||||||
|
setIsResultGetted(false);
|
||||||
|
setResults([]);
|
||||||
|
searchAPI.searchWiki(searchValue.trim(), wikiId).then(res => {
|
||||||
|
if (res.data.results) {
|
||||||
|
let newResults = [];
|
||||||
|
res.data.results.forEach(result => {
|
||||||
|
const page = config.pages.find(page => page.docUuid === result.doc_uuid);
|
||||||
|
if (page) {
|
||||||
|
result.page = Object.assign({}, page);
|
||||||
|
newResults.push(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setResults(newResults);
|
||||||
|
setHighlightIndex(0);
|
||||||
|
setIsLoading(false);
|
||||||
|
setIsResultGetted(true);
|
||||||
|
} else {
|
||||||
|
setResults([]);
|
||||||
|
setHighlightIndex(-1);
|
||||||
|
setIsLoading(false);
|
||||||
|
setIsResultGetted(true);
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
|
toaster.danger(errMessage);
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
}, [config, wikiId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="wiki2-search" onClick={() => setIsModalOpen(true)}>
|
||||||
|
<i className="sf3-font sf3-font-search"></i>
|
||||||
|
<span>{gettext('Search')}</span>
|
||||||
|
</div>
|
||||||
|
{isModalOpen &&
|
||||||
|
<Modal className="wiki2-search-modal" isOpen={isModalOpen} toggle={resetToDefault} autoFocus={false} size='lg'>
|
||||||
|
<ModalBody>
|
||||||
|
<div className="wiki2-search-input mb-4">
|
||||||
|
<i className="sf3-font sf3-font-search"></i>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
className="form-control search-input"
|
||||||
|
name="query"
|
||||||
|
placeholder={gettext('Search')}
|
||||||
|
autoComplete="off"
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => { setValue(e.target.value); setIsResultGetted(false); }}
|
||||||
|
onKeyDown={onKeyDown}
|
||||||
|
autoFocus={true}
|
||||||
|
/>
|
||||||
|
<button type="button" className="search-icon-right input-icon-addon sf3-font sf3-font-x-01 border-0 bg-transparent mr-1" onClick={resetToDefault}></button>
|
||||||
|
</div>
|
||||||
|
<div className="wiki2-search-result-container" style={{ maxHeight: (window.innerHeight - 200) + 'px' }} ref={searchResultListContainerRef}>
|
||||||
|
{isLoading && <Loading />}
|
||||||
|
{(value === '' && !isResultGetted) &&
|
||||||
|
<p className='sf-tip-default d-flex justify-content-center'>{gettext('Type characters to start search')}</p>}
|
||||||
|
{(value !== '' && isResultGetted && results.length === 0) &&
|
||||||
|
<p className='sf-tip-default d-flex justify-content-center'>{gettext('No result')}</p>}
|
||||||
|
{results.map((result, index) => {
|
||||||
|
return (
|
||||||
|
<Wiki2SearchResult
|
||||||
|
result={result}
|
||||||
|
key={result._id}
|
||||||
|
currentPageId={currentPageId}
|
||||||
|
setCurrentPage={setCurrentPage}
|
||||||
|
resetToDefault={resetToDefault}
|
||||||
|
isHighlight={highlightIndex === index}
|
||||||
|
setRef={highlightIndex === index ? (ref) => {highlightRef.current = ref;} : () => {}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</ModalBody>
|
||||||
|
</Modal>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Wiki2Search.propTypes = {
|
||||||
|
wikiId: PropTypes.string.isRequired,
|
||||||
|
setCurrentPage: PropTypes.func.isRequired,
|
||||||
|
config: PropTypes.object.isRequired,
|
||||||
|
currentPageId: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Wiki2Search;
|
@@ -14,7 +14,7 @@ import { Utils } from '../../utils/utils';
|
|||||||
import WikiExternalOperations from './wiki-external-operations';
|
import WikiExternalOperations from './wiki-external-operations';
|
||||||
import WikiTrashDialog from './wiki-trash-dialog';
|
import WikiTrashDialog from './wiki-trash-dialog';
|
||||||
import { DEFAULT_PAGE_NAME } from './constant';
|
import { DEFAULT_PAGE_NAME } from './constant';
|
||||||
import Search from '../../components/search/search';
|
import Wiki2Search from '../../components/search/wiki2-search';
|
||||||
|
|
||||||
import './side-panel.css';
|
import './side-panel.css';
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ class SidePanel extends Component {
|
|||||||
isShowTrashDialog: false,
|
isShowTrashDialog: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmDeletePage = (pageId) => {
|
confirmDeletePage = (pageId) => {
|
||||||
const config = deepCopy(this.props.config);
|
const config = deepCopy(this.props.config);
|
||||||
const { pages } = config;
|
const { pages } = config;
|
||||||
@@ -157,7 +158,7 @@ class SidePanel extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isLoading } = this.props;
|
const { isLoading, config, currentPageId } = this.props;
|
||||||
const isDesktop = Utils.isDesktop();
|
const isDesktop = Utils.isDesktop();
|
||||||
return (
|
return (
|
||||||
<div className={`wiki2-side-panel${this.props.closeSideBar ? '' : ' left-zero'}`}>
|
<div className={`wiki2-side-panel${this.props.closeSideBar ? '' : ' left-zero'}`}>
|
||||||
@@ -177,11 +178,11 @@ class SidePanel extends Component {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<Search
|
<Wiki2Search
|
||||||
repoID={wikiId}
|
wikiId={wikiId}
|
||||||
onSearchedClick={this.onSearchedClick}
|
config={config}
|
||||||
placeholder={gettext('Search')}
|
currentPageId={currentPageId}
|
||||||
isWiki2={true}
|
setCurrentPage={this.props.setCurrentPage}
|
||||||
/>
|
/>
|
||||||
<div className="wiki2-side-nav">
|
<div className="wiki2-side-nav">
|
||||||
{isLoading ? <Loading/> : this.renderWikiNav()}
|
{isLoading ? <Loading/> : this.renderWikiNav()}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import classNames from 'classnames';
|
||||||
import { DropTarget, DragLayer } from 'react-dnd';
|
import { DropTarget, DragLayer } from 'react-dnd';
|
||||||
import html5DragDropContext from './html5DragDropContext';
|
import html5DragDropContext from './html5DragDropContext';
|
||||||
import DraggedPageItem from './pages/dragged-page-item';
|
import DraggedPageItem from './pages/dragged-page-item';
|
||||||
@@ -97,10 +98,8 @@ class WikiNav extends Component {
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
renderStructureBody = React.forwardRef((layerDragProps, ref) => {
|
renderStructureBody = React.forwardRef((layerDragProps, ref) => {
|
||||||
const { navigation, pages } = this.props;
|
const { navigation, pages } = this.props;
|
||||||
let isOnlyOnePage = false;
|
const pagesLen = pages.length;
|
||||||
if (pages.length === 1) {
|
const isOnlyOnePage = pagesLen === 1;
|
||||||
isOnlyOnePage = true;
|
|
||||||
}
|
|
||||||
let id_page_map = {};
|
let id_page_map = {};
|
||||||
pages.forEach(page => id_page_map[page.id] = page);
|
pages.forEach(page => id_page_map[page.id] = page);
|
||||||
return (
|
return (
|
||||||
@@ -109,7 +108,7 @@ class WikiNav extends Component {
|
|||||||
return this.renderPage(item, index, pages.length, isOnlyOnePage, id_page_map, layerDragProps);
|
return this.renderPage(item, index, pages.length, isOnlyOnePage, id_page_map, layerDragProps);
|
||||||
})}
|
})}
|
||||||
{wikiPermission !== 'public' &&
|
{wikiPermission !== 'public' &&
|
||||||
<div className='wiki2-trash' onClick={this.props.toggelTrashDialog}>
|
<div className={classNames('wiki2-trash', { 'mt-0': !pagesLen })} onClick={this.props.toggelTrashDialog}>
|
||||||
<span className="sf3-font-trash sf3-font mr-2"></span>
|
<span className="sf3-font-trash sf3-font mr-2"></span>
|
||||||
<span>{gettext('Trash')}</span>
|
<span>{gettext('Trash')}</span>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user