From 5cf569b405807ad2e57a3bdd31791f381dba26d0 Mon Sep 17 00:00:00 2001 From: Aries Date: Wed, 21 May 2025 10:37:31 +0800 Subject: [PATCH] tag files table support sort in header (#7830) * tag files table support sort in header * fix ui --------- Co-authored-by: zhouwenxuan --- frontend/src/tag/hooks/tag-view.js | 20 ++++++- frontend/src/tag/views/tag-files/index.js | 58 ++++++++++++++++--- .../src/tag/views/tag-files/sort-setter.js | 9 ++- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/frontend/src/tag/hooks/tag-view.js b/frontend/src/tag/hooks/tag-view.js index c847da2639..08d71b7640 100644 --- a/frontend/src/tag/hooks/tag-view.js +++ b/frontend/src/tag/hooks/tag-view.js @@ -28,6 +28,8 @@ export const TagViewProvider = ({ const [tagFiles, setTagFiles] = useState(null); const [errorMessage, setErrorMessage] = useState(null); const [selectedFileIds, setSelectedFileIds] = useState([]); + const [sortBy, setSortBy] = useState('name'); + const [sortOrder, setSortOrder] = useState('asc'); const { tagsData, updateLocalTags } = useTags(); @@ -165,11 +167,15 @@ export const TagViewProvider = ({ }, [repoID, convertFileCallback]); const sortFiles = useCallback((sort) => { - const sorted = sortTagFiles(tagFiles, sort); + const sorted = sortTagFiles(tagFiles?.rows, sort); setTagFiles({ ...tagFiles, 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]); useEffect(() => { @@ -202,6 +208,9 @@ export const TagViewProvider = ({ ...tagFiles, rows: sorted, }); + setSortBy(sort.sort_by); + setSortOrder(sort.order); + window.sfTagsDataContext?.localStorage?.setItem(TAG_FILES_SORT, JSON.stringify(sort)); }); return () => { @@ -209,6 +218,13 @@ export const TagViewProvider = ({ }; }, [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 ( {children} diff --git a/frontend/src/tag/views/tag-files/index.js b/frontend/src/tag/views/tag-files/index.js index 9c0c66f61c..8eaa14d4b3 100644 --- a/frontend/src/tag/views/tag-files/index.js +++ b/frontend/src/tag/views/tag-files/index.js @@ -1,4 +1,5 @@ import React, { useCallback, useState, useRef, useMemo, useEffect } from 'react'; +import classNames from 'classnames'; import { useTagView, useTags } from '../../hooks'; import { gettext, username } from '../../../utils/constants'; import EmptyTip from '../../../components/empty-tip'; @@ -31,7 +32,7 @@ const TagFiles = () => { const { tagsData } = useTags(); const { 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(); const [isMoveDialogOpen, setIsMoveDialogOpen] = useState(false); @@ -290,6 +291,27 @@ const TagFiles = () => { showMenu(showMenuConfig); }, [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(() => { if (!window.sfTagsDataContext) return; const unsubscribeUnselectFiles = window.sfTagsDataContext.eventBus.subscribe(EVENT_BUS_TYPE.UNSELECT_TAG_FILES, () => updateSelectedFileIds([])); @@ -329,6 +351,7 @@ const TagFiles = () => { return (); } + const sortIcon = ; const headers = [ { isFixed: true, @@ -351,7 +374,11 @@ const TagFiles = () => { }, { isFixed: false, width: 0.5, - children: ({gettext('Name')}), + children: ( + + {gettext('Name')} {sortBy == 'name' && sortIcon} + + ), }, { isFixed: false, width: 0.06, @@ -361,14 +388,29 @@ const TagFiles = () => { }, { isFixed: false, width: 0.11, - children: ({gettext('Size')}), + children: ( + + {gettext('Size')} {sortBy == 'size' && sortIcon} + + ), }, { isFixed: false, width: 0.15, - children: ({gettext('Last Update')}), + children: ( + + {gettext('Last Update')} {sortBy == 'time' && sortIcon} + + ), } ]; + 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 isRepoOwner = repoInfo.owner_email === username; let isVirtual = repoInfo.is_virtual; @@ -381,12 +423,12 @@ const TagFiles = () => { <>
{tagFiles.rows.map(file => { const fileId = getRecordIdFromRecord(file); diff --git a/frontend/src/tag/views/tag-files/sort-setter.js b/frontend/src/tag/views/tag-files/sort-setter.js index e8881f5bd1..399ff16b97 100644 --- a/frontend/src/tag/views/tag-files/sort-setter.js +++ b/frontend/src/tag/views/tag-files/sort-setter.js @@ -21,7 +21,14 @@ const SortSetter = () => { const storedSort = localStorage && localStorage.getItem(TAG_FILES_SORT); const sort = storedSort ? JSON.parse(storedSort) : TAG_FILES_DEFAULT_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 (