diff options
author | Christopher Ng <chrng8@gmail.com> | 2024-04-24 11:44:19 -0700 |
---|---|---|
committer | Christopher Ng <chrng8@gmail.com> | 2024-04-30 14:44:29 -0700 |
commit | ce7b2c09453c2430426a31332322f201c151af4d (patch) | |
tree | 98aa870ad72e57782e718cd7097765ec896c247e /apps/files_trashbin | |
parent | fbb4518a0591a2680c3f311d19c4421de0a862fd (diff) | |
download | nextcloud-server-ce7b2c09453c2430426a31332322f201c151af4d.tar.gz nextcloud-server-ce7b2c09453c2430426a31332322f201c151af4d.zip |
feat(trashbin): Show user who deleted a file
Signed-off-by: Christopher Ng <chrng8@gmail.com>
Diffstat (limited to 'apps/files_trashbin')
-rw-r--r-- | apps/files_trashbin/src/main.ts | 59 | ||||
-rw-r--r-- | apps/files_trashbin/src/services/trashbin.ts | 2 |
2 files changed, 61 insertions, 0 deletions
diff --git a/apps/files_trashbin/src/main.ts b/apps/files_trashbin/src/main.ts index d7a8ff48c18..4baa2a352c9 100644 --- a/apps/files_trashbin/src/main.ts +++ b/apps/files_trashbin/src/main.ts @@ -32,6 +32,10 @@ import { getContents } from './services/trashbin' import './actions/restoreAction' import { Column, Node, View, getNavigation } from '@nextcloud/files' import { dirname, joinPaths } from '@nextcloud/paths' +import { getCurrentUser } from '@nextcloud/auth' + +import Vue from 'vue' +import NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js' const parseOriginalLocation = (node: Node): string => { const path = node.attributes?.['trashbin-original-location'] !== undefined ? String(node.attributes?.['trashbin-original-location']) : null @@ -45,6 +49,34 @@ const parseOriginalLocation = (node: Node): string => { return joinPaths(t('files_trashbin', 'All files'), dir) } +interface DeletedBy { + userId: null | string + displayName: null | string + label: null | string +} + +const generateLabel = (userId: null | string, displayName: null | string) => { + const currentUserId = getCurrentUser()?.uid + if (userId === currentUserId) { + return t('files_trashbin', 'You') + } + if (!userId && !displayName) { + return t('files_trashbin', 'Unknown') + } + return null +} + +const parseDeletedBy = (node: Node): DeletedBy => { + const userId = node.attributes?.['trashbin-deleted-by-id'] !== undefined ? String(node.attributes?.['trashbin-deleted-by-id']) : null + const displayName = node.attributes?.['trashbin-deleted-by-display-name'] !== undefined ? String(node.attributes?.['trashbin-deleted-by-display-name']) : null + const label = generateLabel(userId, displayName) + return { + userId, + displayName, + label, + } +} + const Navigation = getNavigation() Navigation.register(new View({ id: 'trashbin', @@ -79,6 +111,33 @@ Navigation.register(new View({ }), new Column({ + id: 'deleted-by', + title: t('files_trashbin', 'Deleted by'), + render(node) { + const { userId, displayName, label } = parseDeletedBy(node) + if (label) { + const span = document.createElement('span') + span.textContent = label + return span + } + + const UserBubble = Vue.extend(NcUserBubble) + const propsData = { + size: 32, + user: userId ?? undefined, + displayName: displayName ?? t('files_trashbin', 'Unknown'), + } + const userBubble = new UserBubble({ propsData }).$mount().$el + return userBubble as HTMLElement + }, + sort(nodeA, nodeB) { + const deletedByA = parseDeletedBy(nodeA).label ?? parseDeletedBy(nodeA).displayName ?? t('files_trashbin', 'Unknown') + const deletedByB = parseDeletedBy(nodeB).label ?? parseDeletedBy(nodeB).displayName ?? t('files_trashbin', 'Unknown') + return deletedByA.localeCompare(deletedByB) + }, + }), + + new Column({ id: 'deleted', title: t('files_trashbin', 'Deleted'), render(node) { diff --git a/apps/files_trashbin/src/services/trashbin.ts b/apps/files_trashbin/src/services/trashbin.ts index 9aef75ef6d5..2ed0038c79c 100644 --- a/apps/files_trashbin/src/services/trashbin.ts +++ b/apps/files_trashbin/src/services/trashbin.ts @@ -35,6 +35,8 @@ const data = `<?xml version="1.0"?> <nc:trashbin-deletion-time /> <nc:trashbin-original-location /> <nc:trashbin-title /> + <nc:trashbin-deleted-by-id /> + <nc:trashbin-deleted-by-display-name /> ${getDavProperties()} </d:prop> </d:propfind>` |