mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-25 14:50:29 +00:00
tag files table support sort in header (#7830)
* tag files table support sort in header * fix ui --------- Co-authored-by: zhouwenxuan <aries@Mac.local>
This commit is contained in:
@@ -28,6 +28,8 @@ export const TagViewProvider = ({
|
|||||||
const [tagFiles, setTagFiles] = useState(null);
|
const [tagFiles, setTagFiles] = useState(null);
|
||||||
const [errorMessage, setErrorMessage] = useState(null);
|
const [errorMessage, setErrorMessage] = useState(null);
|
||||||
const [selectedFileIds, setSelectedFileIds] = useState([]);
|
const [selectedFileIds, setSelectedFileIds] = useState([]);
|
||||||
|
const [sortBy, setSortBy] = useState('name');
|
||||||
|
const [sortOrder, setSortOrder] = useState('asc');
|
||||||
|
|
||||||
const { tagsData, updateLocalTags } = useTags();
|
const { tagsData, updateLocalTags } = useTags();
|
||||||
|
|
||||||
@@ -165,11 +167,15 @@ export const TagViewProvider = ({
|
|||||||
}, [repoID, convertFileCallback]);
|
}, [repoID, convertFileCallback]);
|
||||||
|
|
||||||
const sortFiles = useCallback((sort) => {
|
const sortFiles = useCallback((sort) => {
|
||||||
const sorted = sortTagFiles(tagFiles, sort);
|
const sorted = sortTagFiles(tagFiles?.rows, sort);
|
||||||
setTagFiles({
|
setTagFiles({
|
||||||
...tagFiles,
|
...tagFiles,
|
||||||
rows: sorted,
|
rows: sorted,
|
||||||
});
|
});
|
||||||
|
setSortBy(sort.sort_by);
|
||||||
|
setSortOrder(sort.order);
|
||||||
|
window.sfTagsDataContext?.localStorage?.setItem(TAG_FILES_SORT, JSON.stringify(sort));
|
||||||
|
window.sfTagsDataContext?.eventBus?.dispatch(EVENT_BUS_TYPE.MODIFY_TAG_FILES_SORT, sort);
|
||||||
}, [tagFiles]);
|
}, [tagFiles]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -202,6 +208,9 @@ export const TagViewProvider = ({
|
|||||||
...tagFiles,
|
...tagFiles,
|
||||||
rows: sorted,
|
rows: sorted,
|
||||||
});
|
});
|
||||||
|
setSortBy(sort.sort_by);
|
||||||
|
setSortOrder(sort.order);
|
||||||
|
window.sfTagsDataContext?.localStorage?.setItem(TAG_FILES_SORT, JSON.stringify(sort));
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
@@ -209,6 +218,13 @@ export const TagViewProvider = ({
|
|||||||
};
|
};
|
||||||
}, [tagFiles]);
|
}, [tagFiles]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const savedSort = window.sfTagsDataContext?.localStorage?.getItem(TAG_FILES_SORT);
|
||||||
|
const sort = savedSort ? JSON.parse(savedSort) : TAG_FILES_DEFAULT_SORT;
|
||||||
|
setSortBy(sort.sort_by);
|
||||||
|
setSortOrder(sort.order);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TagViewContext.Provider value={{
|
<TagViewContext.Provider value={{
|
||||||
isLoading,
|
isLoading,
|
||||||
@@ -229,6 +245,8 @@ export const TagViewProvider = ({
|
|||||||
renameTagFile,
|
renameTagFile,
|
||||||
convertFile,
|
convertFile,
|
||||||
sortFiles,
|
sortFiles,
|
||||||
|
sortBy,
|
||||||
|
sortOrder,
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</TagViewContext.Provider>
|
</TagViewContext.Provider>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import React, { useCallback, useState, useRef, useMemo, useEffect } from 'react';
|
import React, { useCallback, useState, useRef, useMemo, useEffect } from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
import { useTagView, useTags } from '../../hooks';
|
import { useTagView, useTags } from '../../hooks';
|
||||||
import { gettext, username } from '../../../utils/constants';
|
import { gettext, username } from '../../../utils/constants';
|
||||||
import EmptyTip from '../../../components/empty-tip';
|
import EmptyTip from '../../../components/empty-tip';
|
||||||
@@ -31,7 +32,7 @@ const TagFiles = () => {
|
|||||||
const { tagsData } = useTags();
|
const { tagsData } = useTags();
|
||||||
const {
|
const {
|
||||||
tagFiles, repoID, repoInfo, selectedFileIds, updateSelectedFileIds,
|
tagFiles, repoID, repoInfo, selectedFileIds, updateSelectedFileIds,
|
||||||
moveTagFile, copyTagFile, addFolder, deleteTagFiles, renameTagFile, getDownloadTarget, downloadTagFiles, convertFile,
|
moveTagFile, copyTagFile, addFolder, deleteTagFiles, renameTagFile, getDownloadTarget, downloadTagFiles, convertFile, sortBy, sortOrder, sortFiles
|
||||||
} = useTagView();
|
} = useTagView();
|
||||||
|
|
||||||
const [isMoveDialogOpen, setIsMoveDialogOpen] = useState(false);
|
const [isMoveDialogOpen, setIsMoveDialogOpen] = useState(false);
|
||||||
@@ -290,6 +291,27 @@ const TagFiles = () => {
|
|||||||
showMenu(showMenuConfig);
|
showMenu(showMenuConfig);
|
||||||
}, [selectedFileIds, updateSelectedFileIds, getMenuList]);
|
}, [selectedFileIds, updateSelectedFileIds, getMenuList]);
|
||||||
|
|
||||||
|
const onSortName = useCallback((e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const sortBy = 'name';
|
||||||
|
const order = sortOrder == 'asc' ? 'desc' : 'asc';
|
||||||
|
sortFiles({ sort_by: sortBy, order });
|
||||||
|
}, [sortOrder, sortFiles]);
|
||||||
|
|
||||||
|
const onSortSize = useCallback((e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const sortBy = 'size';
|
||||||
|
const order = sortOrder == 'asc' ? 'desc' : 'asc';
|
||||||
|
sortFiles({ sort_by: sortBy, order });
|
||||||
|
}, [sortOrder, sortFiles]);
|
||||||
|
|
||||||
|
const onSortTime = useCallback((e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const sortBy = 'time';
|
||||||
|
const order = sortOrder == 'asc' ? 'desc' : 'asc';
|
||||||
|
sortFiles({ sort_by: sortBy, order });
|
||||||
|
}, [sortOrder, sortFiles]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!window.sfTagsDataContext) return;
|
if (!window.sfTagsDataContext) return;
|
||||||
const unsubscribeUnselectFiles = window.sfTagsDataContext.eventBus.subscribe(EVENT_BUS_TYPE.UNSELECT_TAG_FILES, () => updateSelectedFileIds([]));
|
const unsubscribeUnselectFiles = window.sfTagsDataContext.eventBus.subscribe(EVENT_BUS_TYPE.UNSELECT_TAG_FILES, () => updateSelectedFileIds([]));
|
||||||
@@ -329,6 +351,7 @@ const TagFiles = () => {
|
|||||||
return (<EmptyTip text={gettext('No files')} />);
|
return (<EmptyTip text={gettext('No files')} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sortIcon = <span className={`sf3-font sf3-font-down ${sortOrder == 'asc' ? 'rotate-180 d-inline-block' : ''}`}></span>;
|
||||||
const headers = [
|
const headers = [
|
||||||
{
|
{
|
||||||
isFixed: true,
|
isFixed: true,
|
||||||
@@ -351,7 +374,11 @@ const TagFiles = () => {
|
|||||||
}, {
|
}, {
|
||||||
isFixed: false,
|
isFixed: false,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
children: (<a className="d-block table-sort-op" href="#">{gettext('Name')}</a>),
|
children: (
|
||||||
|
<a className="d-block table-sort-op" href="#" onClick={onSortName}>
|
||||||
|
{gettext('Name')} {sortBy == 'name' && sortIcon}
|
||||||
|
</a>
|
||||||
|
),
|
||||||
}, {
|
}, {
|
||||||
isFixed: false,
|
isFixed: false,
|
||||||
width: 0.06,
|
width: 0.06,
|
||||||
@@ -361,14 +388,29 @@ const TagFiles = () => {
|
|||||||
}, {
|
}, {
|
||||||
isFixed: false,
|
isFixed: false,
|
||||||
width: 0.11,
|
width: 0.11,
|
||||||
children: (<a className="d-block table-sort-op" href="#">{gettext('Size')}</a>),
|
children: (
|
||||||
|
<a className="d-block table-sort-op" href="#" onClick={onSortSize}>
|
||||||
|
{gettext('Size')} {sortBy == 'size' && sortIcon}
|
||||||
|
</a>
|
||||||
|
),
|
||||||
}, {
|
}, {
|
||||||
isFixed: false,
|
isFixed: false,
|
||||||
width: 0.15,
|
width: 0.15,
|
||||||
children: (<a className="d-block table-sort-op" href="#">{gettext('Last Update')}</a>),
|
children: (
|
||||||
|
<a className="d-block table-sort-op" href="#" onClick={onSortTime}>
|
||||||
|
{gettext('Last Update')} {sortBy == 'time' && sortIcon}
|
||||||
|
</a>
|
||||||
|
),
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const mobileHeaders = [
|
||||||
|
{ isFixed: false, width: 0.12 },
|
||||||
|
{ isFixed: false, width: 0.8 },
|
||||||
|
{ isFixed: false, width: 0.08 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const isDesktop = Utils.isDesktop();
|
||||||
let enableDirPrivateShare = false;
|
let enableDirPrivateShare = false;
|
||||||
let isRepoOwner = repoInfo.owner_email === username;
|
let isRepoOwner = repoInfo.owner_email === username;
|
||||||
let isVirtual = repoInfo.is_virtual;
|
let isVirtual = repoInfo.is_virtual;
|
||||||
@@ -381,12 +423,12 @@ const TagFiles = () => {
|
|||||||
<>
|
<>
|
||||||
<div className="table-container" onClick={onContainerClick}>
|
<div className="table-container" onClick={onContainerClick}>
|
||||||
<FixedWidthTable
|
<FixedWidthTable
|
||||||
headers={headers}
|
headers={isDesktop ? headers : mobileHeaders}
|
||||||
className="table-hover"
|
className={classNames('table-hover', { 'table-thead-hidden': !isDesktop })}
|
||||||
theadOptions={{
|
theadOptions={isDesktop ? {
|
||||||
onMouseDown: onThreadMouseDown,
|
onMouseDown: onThreadMouseDown,
|
||||||
onContextMenu: onThreadContextMenu,
|
onContextMenu: onThreadContextMenu,
|
||||||
}}
|
} : {}}
|
||||||
>
|
>
|
||||||
{tagFiles.rows.map(file => {
|
{tagFiles.rows.map(file => {
|
||||||
const fileId = getRecordIdFromRecord(file);
|
const fileId = getRecordIdFromRecord(file);
|
||||||
|
@@ -21,7 +21,14 @@ const SortSetter = () => {
|
|||||||
const storedSort = localStorage && localStorage.getItem(TAG_FILES_SORT);
|
const storedSort = localStorage && localStorage.getItem(TAG_FILES_SORT);
|
||||||
const sort = storedSort ? JSON.parse(storedSort) : TAG_FILES_DEFAULT_SORT;
|
const sort = storedSort ? JSON.parse(storedSort) : TAG_FILES_DEFAULT_SORT;
|
||||||
setSort(sort);
|
setSort(sort);
|
||||||
}, [localStorage]);
|
|
||||||
|
const unsubscribeSort = eventBus && eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_TAG_FILES_SORT, (newSort) => {
|
||||||
|
setSort(newSort);
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
unsubscribeSort && unsubscribeSort();
|
||||||
|
};
|
||||||
|
}, [localStorage, eventBus]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SortMenu sortBy={getSortBy(sort)} sortOrder={getSortOrder(sort)} onSelectSortOption={onSelectSortOption} />
|
<SortMenu sortBy={getSortBy(sort)} sortOrder={getSortOrder(sort)} onSelectSortOption={onSelectSortOption} />
|
||||||
|
Reference in New Issue
Block a user