diff --git a/src/lib/containers/download_list/DownloadListTable.tsx b/src/lib/containers/download_list/DownloadListTable.tsx index 70f6ad2626..d114110ae6 100644 --- a/src/lib/containers/download_list/DownloadListTable.tsx +++ b/src/lib/containers/download_list/DownloadListTable.tsx @@ -35,6 +35,11 @@ import AccessRequirementList, { AccessRequirementListProps, } from '../access_requirement_list/AccessRequirementList' +import { + faSortAmountDown, + faSortAmountUp, +} from '@fortawesome/free-solid-svg-icons' + library.add(faTrash) type DownloadListTableData = { @@ -62,6 +67,17 @@ export default function DownloadListTable(props: DownloadListTableProps) { batchFileResult: undefined, downloadList: undefined, }) + + type SortedColumn = { + column: string + isDescending: boolean + } + + const [sortedColumn, setSortedColumn] = useState({ + column: '', + isDescending: false, + }) + const [arPropsFromHasAccess, set_arPropsFromHasAccess] = useState< AccessRequirementListProps | undefined >() @@ -81,11 +97,11 @@ export default function DownloadListTable(props: DownloadListTableProps) { // Get owner ids from download list by filtering to items that have a file handle // then map to ownerIds const ownerIdsFromHeaders = references?.results - .filter((el) => el.createdBy) - .map((el) => el.createdBy) + .filter(el => el.createdBy) + .map(el => el.createdBy) const ownerIdsFromFileHandles = requestedFiles - .filter((el) => el.fileHandle?.createdBy !== undefined) - .map((el) => el.fileHandle!.createdBy) + .filter(el => el.fileHandle?.createdBy !== undefined) + .map(el => el.fileHandle!.createdBy) const ownerIds: string[] = [] if (ownerIdsFromFileHandles) { @@ -131,14 +147,14 @@ export default function DownloadListTable(props: DownloadListTableProps) { // which can be determined by whether the batchFileResult has a failure code for the // corresponding download list item const referenceCall: Reference[] = filesToDownload - .filter((el) => { + .filter(el => { return ( batchFileResult.requestedFiles.find( - (batchFile) => batchFile.fileHandleId === el.fileHandleId, + batchFile => batchFile.fileHandleId === el.fileHandleId, )!.failureCode !== undefined ) }) - .map((el) => { + .map(el => { return { targetId: el.associateObjectId } }) // entity header is used to get the names of the files that the user @@ -189,6 +205,7 @@ export default function DownloadListTable(props: DownloadListTableProps) { }, ] setIsLoading(true) + setFileBeingDeleted(fileHandleId) try { const downloadList = await deleteDownloadListFiles(list, token) @@ -204,6 +221,107 @@ export default function DownloadListTable(props: DownloadListTableProps) { } } + const sortColumn = async (column: string) => { + try { + setIsLoading(true) + + const isDescending = + column === sortedColumn.column ? !sortedColumn.isDescending : false + + setSortedColumn({ + column, + isDescending, + }) + + const filesToDownload = downloadList?.filesToDownload ?? [] + + filesToDownload.sort((itemA, itemB) => { + return sortDownLoadList(itemA, itemB, column, isDescending) + }) + setData({ + ...data, + downloadList, + }) + listUpdatedCallback?.() + } catch (err) { + console.error(err) + } finally { + setIsLoading(false) + } + } + const getFileHandleInfo = (item: FileHandleAssociation) => { + const fileResult = requestedFiles.find( + fileRes => fileRes.fileHandleId === item.fileHandleId, + ) + const fileHandle = fileResult ? fileResult.fileHandle : undefined + + let fileName: string | undefined = '' + let createdBy: string | undefined = '' + let createdOn: string | undefined = '' + let contentSize: number | undefined = undefined + + if (fileHandle && item) { + fileName = fileHandle.fileName + createdBy = fileHandle.createdBy + createdOn = fileHandle.createdOn + contentSize = fileHandle.contentSize + } else { + const requestedFile = results.find( + req => req.id === item.associateObjectId, + ) + if (requestedFiles) { + fileName = requestedFile?.name + createdBy = requestedFile?.createdBy + createdOn = requestedFile?.createdOn + } + } + createdBy = userProfiles.find(el => el.ownerId === createdBy)?.userName + + return { fileName, createdBy, createdOn, contentSize } + } + + const sortDownLoadList = ( + itemA: FileHandleAssociation, + itemB: FileHandleAssociation, + column: string, + isDescending: boolean, + ) => { + const { + fileName: fileName_A, + createdBy: createdBy_A, + createdOn: createdOn_A, + contentSize: contentSize_A, + } = getFileHandleInfo(itemA) + + const { + fileName: fileName_B, + createdBy: createdBy_B, + createdOn: createdOn_B, + contentSize: contentSize_B, + } = getFileHandleInfo(itemB) + + const direction = isDescending ? 1 : -1 + + switch (column) { + case 'file': + return fileName_B?.localeCompare(fileName_A!)! * direction + case 'createdBy': + return createdBy_B?.localeCompare(createdBy_A!)! * direction + case 'createdOn': + return createdOn_B?.localeCompare(createdOn_A!)! * direction + case 'size': + if (contentSize_A && !contentSize_B) { + return -1 + } else if (contentSize_B && !contentSize_A) { + return 1 + } else { + return (contentSize_B! - contentSize_A!) * direction + } + default: + return 1 + } + } + const filesToDownload = downloadList?.filesToDownload ?? [] const results = references?.results ?? [] let numBytes = 0 @@ -227,17 +345,109 @@ export default function DownloadListTable(props: DownloadListTableProps) { - File Name + + File + + Access - Created By - Created On - Size + + Created By + + + + Created On + + + + Size + + {/* th below is made for trash can icon but holds no content */} - {filesToDownload.map((item) => { + {filesToDownload.map(item => { let createdBy: string | undefined = '' let createdOn: string | undefined = '' let fileName: string | undefined = '' @@ -248,7 +458,7 @@ export default function DownloadListTable(props: DownloadListTableProps) { fileBeingDeleted === fileHandleId ? 'SRC-inactive-bg' : '' // See if batch file results has this fileHandleId const fileResult = requestedFiles.find( - (fileRes) => fileRes.fileHandleId === fileHandleId, + fileRes => fileRes.fileHandleId === fileHandleId, ) const fileHandle = fileResult?.fileHandle const canDownload = fileHandle !== undefined @@ -265,7 +475,7 @@ export default function DownloadListTable(props: DownloadListTableProps) { } else { // file is not downloadable, only show its name from entity header info const requestedFile = results.find( - (req) => req.id === item.associateObjectId, + req => req.id === item.associateObjectId, ) fileName = requestedFile?.name createdBy = requestedFile?.createdBy @@ -273,7 +483,7 @@ export default function DownloadListTable(props: DownloadListTableProps) { } createdOn = moment(createdOn).format('L LT') const userProfile = userProfiles.find( - (el) => el.ownerId === createdBy, + el => el.ownerId === createdBy, ) return ( diff --git a/src/lib/style/components/_download-list.scss b/src/lib/style/components/_download-list.scss index 04fc28f33e..8edf266331 100644 --- a/src/lib/style/components/_download-list.scss +++ b/src/lib/style/components/_download-list.scss @@ -40,6 +40,9 @@ } } } +.sort { + padding-left: 5px; +} .create-package-container { display: flex; padding: 8px;