mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-10 03:11:07 +00:00
improve/add-empty-tip-when-no-file (#6760)
This commit is contained in:
@@ -11,6 +11,8 @@ import ModalPortal from '../../components/modal-portal';
|
|||||||
import toaster from '../../components/toast';
|
import toaster from '../../components/toast';
|
||||||
import CleanTrash from '../../components/dialog/clean-trash';
|
import CleanTrash from '../../components/dialog/clean-trash';
|
||||||
import Paginator from '../paginator';
|
import Paginator from '../paginator';
|
||||||
|
import Loading from '../../components/loading';
|
||||||
|
import EmptyTip from '../../components/empty-tip';
|
||||||
|
|
||||||
import '../../css/toolbar.css';
|
import '../../css/toolbar.css';
|
||||||
import '../../css/search.css';
|
import '../../css/search.css';
|
||||||
@@ -141,7 +143,7 @@ class TrashDialog extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { showTrashDialog, toggleTrashDialog } = this.props;
|
const { showTrashDialog, toggleTrashDialog } = this.props;
|
||||||
const { isCleanTrashDialogOpen, showFolder } = this.state;
|
const { isCleanTrashDialogOpen, showFolder, isLoading, items } = this.state;
|
||||||
const isRepoAdmin = this.props.currentRepoInfo.owner_email === username || this.props.currentRepoInfo.is_admin;
|
const isRepoAdmin = this.props.currentRepoInfo.owner_email === username || this.props.currentRepoInfo.is_admin;
|
||||||
const repoFolderName = this.props.currentRepoInfo.repo_name;
|
const repoFolderName = this.props.currentRepoInfo.repo_name;
|
||||||
const oldTrashUrl = siteRoot + 'repo/' + this.props.repoID + '/trash/';
|
const oldTrashUrl = siteRoot + 'repo/' + this.props.repoID + '/trash/';
|
||||||
@@ -164,6 +166,11 @@ class TrashDialog extends React.Component {
|
|||||||
<div dangerouslySetInnerHTML={{ __html: title }}></div>
|
<div dangerouslySetInnerHTML={{ __html: title }}></div>
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
|
{isLoading && <Loading />}
|
||||||
|
{!isLoading && items.length === 0 &&
|
||||||
|
<EmptyTip text={gettext('No file')} className="m-0" />
|
||||||
|
}
|
||||||
|
{!isLoading && items.length > 0 &&
|
||||||
<Content
|
<Content
|
||||||
data={this.state}
|
data={this.state}
|
||||||
repoID={this.props.repoID}
|
repoID={this.props.repoID}
|
||||||
@@ -175,6 +182,7 @@ class TrashDialog extends React.Component {
|
|||||||
getListByPage={this.getItems2}
|
getListByPage={this.getItems2}
|
||||||
resetPerPage={this.resetPerPage}
|
resetPerPage={this.resetPerPage}
|
||||||
/>
|
/>
|
||||||
|
}
|
||||||
{isCleanTrashDialogOpen &&
|
{isCleanTrashDialogOpen &&
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<CleanTrash
|
<CleanTrash
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { siteRoot, username, enableSeadoc, thumbnailDefaultSize, thumbnailSizeForOriginal } from '../../utils/constants';
|
import { siteRoot, username, enableSeadoc, thumbnailDefaultSize, thumbnailSizeForOriginal, gettext } from '../../utils/constants';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import URLDecorator from '../../utils/url-decorator';
|
import URLDecorator from '../../utils/url-decorator';
|
||||||
@@ -24,6 +24,7 @@ import toaster from '../toast';
|
|||||||
import imageAPI from '../../utils/image-api';
|
import imageAPI from '../../utils/image-api';
|
||||||
import FileAccessLog from '../dialog/file-access-log';
|
import FileAccessLog from '../dialog/file-access-log';
|
||||||
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
|
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
|
||||||
|
import EmptyTip from '../empty-tip';
|
||||||
|
|
||||||
import '../../css/grid-view.css';
|
import '../../css/grid-view.css';
|
||||||
|
|
||||||
@@ -826,16 +827,16 @@ class DirentGridView extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<ul
|
{direntList.length > 0 ?
|
||||||
className="grid-view"
|
<ul
|
||||||
onClick={this.gridContainerClick}
|
className="grid-view"
|
||||||
onContextMenu={this.onGridContainerContextMenu}
|
onClick={this.gridContainerClick}
|
||||||
onMouseDown={this.onGridContainerMouseDown}
|
onContextMenu={this.onGridContainerContextMenu}
|
||||||
onMouseMove={this.onSelectMouseMove}
|
onMouseDown={this.onGridContainerMouseDown}
|
||||||
ref={this.containerRef}
|
onMouseMove={this.onSelectMouseMove}
|
||||||
>
|
ref={this.containerRef}
|
||||||
{
|
>
|
||||||
direntList.length !== 0 && direntList.map((dirent, index) => {
|
{direntList.map((dirent, index) => {
|
||||||
return (
|
return (
|
||||||
<DirentGridItem
|
<DirentGridItem
|
||||||
key={index}
|
key={index}
|
||||||
@@ -854,10 +855,21 @@ class DirentGridView extends React.Component {
|
|||||||
selectedDirentList={selectedDirentList}
|
selectedDirentList={selectedDirentList}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})
|
})}
|
||||||
}
|
{this.renderSelectionBox()}
|
||||||
{this.renderSelectionBox()}
|
</ul>
|
||||||
</ul>
|
:
|
||||||
|
<ul
|
||||||
|
className="grid-view"
|
||||||
|
onClick={this.gridContainerClick}
|
||||||
|
onContextMenu={this.onGridContainerContextMenu}
|
||||||
|
onMouseDown={this.onGridContainerMouseDown}
|
||||||
|
onMouseMove={this.onSelectMouseMove}
|
||||||
|
ref={this.containerRef}
|
||||||
|
>
|
||||||
|
<EmptyTip text={gettext('No file')} className='w-100' />
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
id={GRID_ITEM_CONTEXTMENU_ID}
|
id={GRID_ITEM_CONTEXTMENU_ID}
|
||||||
onMenuItemClick={this.onMenuItemClick}
|
onMenuItemClick={this.onMenuItemClick}
|
||||||
|
@@ -18,6 +18,7 @@ import ContextMenu from '../context-menu/context-menu';
|
|||||||
import { hideMenu, showMenu } from '../context-menu/actions';
|
import { hideMenu, showMenu } from '../context-menu/actions';
|
||||||
import DirentsDraggedPreview from '../draggable/dirents-dragged-preview';
|
import DirentsDraggedPreview from '../draggable/dirents-dragged-preview';
|
||||||
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
|
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
|
||||||
|
import EmptyTip from '../empty-tip';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
@@ -651,6 +652,7 @@ class DirentListView extends React.Component {
|
|||||||
onDragLeave={this.onTableDragLeave}
|
onDragLeave={this.onTableDragLeave}
|
||||||
onDrop={this.tableDrop}
|
onDrop={this.tableDrop}
|
||||||
>
|
>
|
||||||
|
{direntList.length > 0 &&
|
||||||
<table className={`table-hover ${isDesktop ? '' : 'table-thead-hidden'}`}>
|
<table className={`table-hover ${isDesktop ? '' : 'table-thead-hidden'}`}>
|
||||||
{isDesktop ? (
|
{isDesktop ? (
|
||||||
<thead onMouseDown={this.onThreadMouseDown} onContextMenu={this.onThreadContextMenu}>
|
<thead onMouseDown={this.onThreadMouseDown} onContextMenu={this.onThreadContextMenu}>
|
||||||
@@ -729,6 +731,10 @@ class DirentListView extends React.Component {
|
|||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
}
|
||||||
|
{direntList.length === 0 &&
|
||||||
|
<EmptyTip text={gettext('No file')}/>
|
||||||
|
}
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
id={'dirent-container-menu'}
|
id={'dirent-container-menu'}
|
||||||
|
@@ -14,7 +14,7 @@ const propTypes = {
|
|||||||
onAddFile: PropTypes.func.isRequired
|
onAddFile: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirentNodeView extends React.Component {
|
class DirentNoneView extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -88,6 +88,6 @@ class DirentNodeView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DirentNodeView.propTypes = propTypes;
|
DirentNoneView.propTypes = propTypes;
|
||||||
|
|
||||||
export default DirentNodeView;
|
export default DirentNoneView;
|
||||||
|
@@ -3,9 +3,9 @@ import PropTypes from 'prop-types';
|
|||||||
import { mediaUrl } from '../utils/constants';
|
import { mediaUrl } from '../utils/constants';
|
||||||
import '../css/empty-tip.css';
|
import '../css/empty-tip.css';
|
||||||
|
|
||||||
function EmptyTip({ className, title, text, children }) {
|
function EmptyTip({ className = '', title, text, children }) {
|
||||||
return (
|
return (
|
||||||
<div className='empty-tip'>
|
<div className={`empty-tip ${className}`}>
|
||||||
<img src={`${mediaUrl}img/no-items-tip.png`} alt="" width="100" height="100" className="no-items-img-tip" />
|
<img src={`${mediaUrl}img/no-items-tip.png`} alt="" width="100" height="100" className="no-items-img-tip" />
|
||||||
{title && <span className="empty-tip-title">{title}</span>}
|
{title && <span className="empty-tip-title">{title}</span>}
|
||||||
{text && <span className="empty-tip-text">{text}</span>}
|
{text && <span className="empty-tip-text">{text}</span>}
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import EmptyTip from '../../../../../components/empty-tip';
|
||||||
|
import { gettext } from '../../../utils';
|
||||||
|
|
||||||
const Main = ({ groups, overScan, columns, size, gap }) => {
|
const GalleryMain = ({ groups, overScan, columns, size, gap }) => {
|
||||||
const imageHeight = useMemo(() => size + gap, [size, gap]);
|
const imageHeight = useMemo(() => size + gap, [size, gap]);
|
||||||
|
|
||||||
const renderDisplayGroup = useCallback((group) => {
|
const renderDisplayGroup = useCallback((group) => {
|
||||||
@@ -47,17 +49,20 @@ const Main = ({ groups, overScan, columns, size, gap }) => {
|
|||||||
);
|
);
|
||||||
}, [overScan, columns, size, imageHeight]);
|
}, [overScan, columns, size, imageHeight]);
|
||||||
|
|
||||||
if (!Array.isArray(groups) || groups.length === 0) return null;
|
if (!Array.isArray(groups) || groups.length === 0) {
|
||||||
|
return <EmptyTip text={gettext('No record')}/>;
|
||||||
|
}
|
||||||
|
|
||||||
return groups.map((group, index) => {
|
return groups.map((group, index) => {
|
||||||
return renderDisplayGroup(group, index);
|
return renderDisplayGroup(group, index);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Main.propTypes = {
|
GalleryMain.propTypes = {
|
||||||
groups: PropTypes.array,
|
groups: PropTypes.array,
|
||||||
overScan: PropTypes.object,
|
overScan: PropTypes.object,
|
||||||
columns: PropTypes.number,
|
columns: PropTypes.number,
|
||||||
size: PropTypes.number,
|
size: PropTypes.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Main;
|
export default GalleryMain;
|
@@ -5,7 +5,7 @@ import { Utils } from '../../../../../utils/utils';
|
|||||||
import { getDateDisplayString, PRIVATE_COLUMN_KEY } from '../../../_basic';
|
import { getDateDisplayString, PRIVATE_COLUMN_KEY } from '../../../_basic';
|
||||||
import { siteRoot, thumbnailSizeForGrid } from '../../../../../utils/constants';
|
import { siteRoot, thumbnailSizeForGrid } from '../../../../../utils/constants';
|
||||||
import { EVENT_BUS_TYPE, PER_LOAD_NUMBER } from '../../../constants';
|
import { EVENT_BUS_TYPE, PER_LOAD_NUMBER } from '../../../constants';
|
||||||
import Main from './main';
|
import GalleryMain from './gallery-main';
|
||||||
import toaster from '../../../../../components/toast';
|
import toaster from '../../../../../components/toast';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
@@ -167,8 +167,12 @@ const Gallery = () => {
|
|||||||
<div className="sf-metadata-gallery-container" ref={containerRef} onScroll={handleScroll} >
|
<div className="sf-metadata-gallery-container" ref={containerRef} onScroll={handleScroll} >
|
||||||
{!isFirstLoading && (
|
{!isFirstLoading && (
|
||||||
<>
|
<>
|
||||||
<Main groups={groups} size={imageSize} columns={columns} overScan={overScan} gap={IMAGE_GAP} />
|
<GalleryMain groups={groups} size={imageSize} columns={columns} overScan={overScan} gap={IMAGE_GAP} />
|
||||||
{isLoadingMore && (<div className="sf-metadata-gallery-loading-more"><CenteredLoading /></div>)}
|
{isLoadingMore &&
|
||||||
|
<div className="sf-metadata-gallery-loading-more">
|
||||||
|
<CenteredLoading />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import RecordsHeader from './records-header';
|
import RecordsHeader from './records-header';
|
||||||
import Body from './body';
|
import Body from './body';
|
||||||
@@ -9,8 +9,9 @@ import { recalculate } from '../../../../../utils/column-utils';
|
|||||||
import { SEQUENCE_COLUMN_WIDTH, CANVAS_RIGHT_INTERVAL, GROUP_ROW_TYPE, EVENT_BUS_TYPE } from '../../../../../constants';
|
import { SEQUENCE_COLUMN_WIDTH, CANVAS_RIGHT_INTERVAL, GROUP_ROW_TYPE, EVENT_BUS_TYPE } from '../../../../../constants';
|
||||||
import {
|
import {
|
||||||
isWindowsBrowser, isWebkitBrowser, isMobile, getEventClassName,
|
isWindowsBrowser, isWebkitBrowser, isMobile, getEventClassName,
|
||||||
addClassName, removeClassName,
|
addClassName, removeClassName, gettext,
|
||||||
} from '../../../../../utils';
|
} from '../../../../../utils';
|
||||||
|
import EmptyTip from '../../../../../../../components/empty-tip';
|
||||||
import RecordMetrics from '../../../../../utils/record-metrics';
|
import RecordMetrics from '../../../../../utils/record-metrics';
|
||||||
import { isShiftKeyDown } from '../../../../../utils/keyboard-utils';
|
import { isShiftKeyDown } from '../../../../../utils/keyboard-utils';
|
||||||
import { getVisibleBoundaries } from '../../../../../utils/viewport';
|
import { getVisibleBoundaries } from '../../../../../utils/viewport';
|
||||||
@@ -665,8 +666,12 @@ class Records extends Component {
|
|||||||
const hasSelectedRecord = this.hasSelectedRecord();
|
const hasSelectedRecord = this.hasSelectedRecord();
|
||||||
const isSelectedAll = RecordMetrics.isSelectedAll(recordIds, recordMetrics);
|
const isSelectedAll = RecordMetrics.isSelectedAll(recordIds, recordMetrics);
|
||||||
|
|
||||||
|
if (recordsCount === 0) {
|
||||||
|
return (<EmptyTip text={gettext('No record')} />);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`sf-metadata-result-container ${this.isWindows ? 'windows-browser' : ''}`}
|
className={`sf-metadata-result-container ${this.isWindows ? 'windows-browser' : ''}`}
|
||||||
ref={this.setResultContainerRef}
|
ref={this.setResultContainerRef}
|
||||||
@@ -721,7 +726,7 @@ class Records extends Component {
|
|||||||
getRecordsSummaries={() => {}}
|
getRecordsSummaries={() => {}}
|
||||||
loadAll={this.props.loadAll}
|
loadAll={this.props.loadAll}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -118,7 +118,7 @@ class RecordsFooter extends React.Component {
|
|||||||
return gettext('xxx cells selected').replace('xxx', selectedCellsCount);
|
return gettext('xxx cells selected').replace('xxx', selectedCellsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
let recordsCountText = gettext('No record');
|
let recordsCountText;
|
||||||
if (recordsCount > 1) {
|
if (recordsCount > 1) {
|
||||||
recordsCountText = gettext('xxx records').replace('xxx', recordsCount);
|
recordsCountText = gettext('xxx records').replace('xxx', recordsCount);
|
||||||
} else if (recordsCount === 1) {
|
} else if (recordsCount === 1) {
|
||||||
|
Reference in New Issue
Block a user