diff options
author | skjnldsv <skjnldsv@protonmail.com> | 2024-07-26 09:51:58 +0200 |
---|---|---|
committer | nextcloud-command <nextcloud-command@users.noreply.github.com> | 2024-07-30 09:50:46 +0000 |
commit | 850cb082a91d6e18e64fdbaafaa3be9ede59123f (patch) | |
tree | 47087d35bbc1dd83873e2a4a25485fbc057cc0d3 | |
parent | 68864ab3945f8e1b2e2209105e0189905ab07003 (diff) | |
download | nextcloud-server-850cb082a91d6e18e64fdbaafaa3be9ede59123f.tar.gz nextcloud-server-850cb082a91d6e18e64fdbaafaa3be9ede59123f.zip |
feat(files_sharing): show file requests in navigation
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
-rw-r--r-- | apps/files_sharing/src/services/SharingService.ts | 20 | ||||
-rw-r--r-- | apps/files_sharing/src/views/SharingDetailsTab.vue | 2 | ||||
-rw-r--r-- | apps/files_sharing/src/views/SharingInherited.vue | 2 | ||||
-rw-r--r-- | apps/files_sharing/src/views/SharingTab.vue | 2 | ||||
-rw-r--r-- | apps/files_sharing/src/views/shares.spec.ts | 9 | ||||
-rw-r--r-- | apps/files_sharing/src/views/shares.ts | 31 |
6 files changed, 56 insertions, 10 deletions
diff --git a/apps/files_sharing/src/services/SharingService.ts b/apps/files_sharing/src/services/SharingService.ts index b0f5fd2ff9a..4206e4a305a 100644 --- a/apps/files_sharing/src/services/SharingService.ts +++ b/apps/files_sharing/src/services/SharingService.ts @@ -7,6 +7,7 @@ import type { AxiosPromise } from '@nextcloud/axios' import type { OCSResponse } from '@nextcloud/typings/ocs' +import type { ShareAttribute } from '../sharing' import { Folder, File, type ContentsWithRoot, Permission } from '@nextcloud/files' import { generateOcsUrl, generateRemoteUrl } from '@nextcloud/router' @@ -73,6 +74,7 @@ const ocsEntryToNode = async function(ocsEntry: any): Promise<Folder | File | nu 'owner-id': ocsEntry?.uid_owner, 'owner-display-name': ocsEntry?.displayname_owner, 'share-types': ocsEntry?.share_type, + 'share-attributes': ocsEntry?.attributes || '[]', favorite: ocsEntry?.tags?.includes((window.OC as Nextcloud.v28.OC & { TAG_FAVORITE: string }).TAG_FAVORITE) ? 1 : 0, }, }) @@ -142,6 +144,24 @@ const getDeletedShares = function(): AxiosPromise<OCSResponse<any>> { } /** + * Check if a file request is enabled + * @param attributes the share attributes json-encoded array + */ +export const isFileRequest = (attributes = '[]'): boolean => { + const isFileRequest = (attribute) => { + return attribute.scope === 'fileRequest' && attribute.key === 'enabled' && attribute.value === true + } + + try { + const attributesArray = JSON.parse(attributes) as Array<ShareAttribute> + return attributesArray.some(isFileRequest) + } catch (error) { + logger.error('Error while parsing share attributes', { error }) + return false + } +} + +/** * Group an array of objects (here Nodes) by a key * and return an array of arrays of them. * @param nodes diff --git a/apps/files_sharing/src/views/SharingDetailsTab.vue b/apps/files_sharing/src/views/SharingDetailsTab.vue index a0cb71fc392..2c544e12c64 100644 --- a/apps/files_sharing/src/views/SharingDetailsTab.vue +++ b/apps/files_sharing/src/views/SharingDetailsTab.vue @@ -273,7 +273,7 @@ import DotsHorizontalIcon from 'vue-material-design-icons/DotsHorizontal.vue' import ExternalShareAction from '../components/ExternalShareAction.vue' import GeneratePassword from '../utils/GeneratePassword.ts' -import Share from '../models/Share.js' +import Share from '../models/Share.ts' import ShareRequests from '../mixins/ShareRequests.js' import ShareTypes from '../mixins/ShareTypes.js' import SharesMixin from '../mixins/SharesMixin.js' diff --git a/apps/files_sharing/src/views/SharingInherited.vue b/apps/files_sharing/src/views/SharingInherited.vue index a9c034256ff..80beb411a15 100644 --- a/apps/files_sharing/src/views/SharingInherited.vue +++ b/apps/files_sharing/src/views/SharingInherited.vue @@ -33,7 +33,7 @@ import { generateOcsUrl } from '@nextcloud/router' import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' import axios from '@nextcloud/axios' -import Share from '../models/Share.js' +import Share from '../models/Share' import SharingEntryInherited from '../components/SharingEntryInherited.vue' import SharingEntrySimple from '../components/SharingEntrySimple.vue' diff --git a/apps/files_sharing/src/views/SharingTab.vue b/apps/files_sharing/src/views/SharingTab.vue index 98c40a0a933..070c1b508e4 100644 --- a/apps/files_sharing/src/views/SharingTab.vue +++ b/apps/files_sharing/src/views/SharingTab.vue @@ -90,7 +90,7 @@ import { loadState } from '@nextcloud/initial-state' import Config from '../services/ConfigService.ts' import { shareWithTitle } from '../utils/SharedWithMe.js' -import Share from '../models/Share.js' +import Share from '../models/Share.ts' import ShareTypes from '../mixins/ShareTypes.js' import SharingEntryInternal from '../components/SharingEntryInternal.vue' import SharingEntrySimple from '../components/SharingEntrySimple.vue' diff --git a/apps/files_sharing/src/views/shares.spec.ts b/apps/files_sharing/src/views/shares.spec.ts index cba8ffa94d7..13e1f1f97e5 100644 --- a/apps/files_sharing/src/views/shares.spec.ts +++ b/apps/files_sharing/src/views/shares.spec.ts @@ -37,12 +37,12 @@ describe('Sharing views definition', () => { const shareOverviewView = Navigation.views.find(view => view.id === 'shareoverview') as View const sharesChildViews = Navigation.views.filter(view => view.parent === 'shareoverview') as View[] - expect(Navigation.register).toHaveBeenCalledTimes(6) + expect(Navigation.register).toHaveBeenCalledTimes(7) // one main view and no children - expect(Navigation.views.length).toBe(6) + expect(Navigation.views.length).toBe(7) expect(shareOverviewView).toBeDefined() - expect(sharesChildViews.length).toBe(5) + expect(sharesChildViews.length).toBe(6) expect(shareOverviewView?.id).toBe('shareoverview') expect(shareOverviewView?.name).toBe('Shares') @@ -56,6 +56,7 @@ describe('Sharing views definition', () => { { id: 'sharingin', name: 'Shared with you' }, { id: 'sharingout', name: 'Shared with others' }, { id: 'sharinglinks', name: 'Shared by link' }, + { id: 'filerequest', name: 'File requests' }, { id: 'deletedshares', name: 'Deleted shares' }, { id: 'pendingshares', name: 'Pending shares' }, ] @@ -103,7 +104,7 @@ describe('Sharing views contents', () => { }) registerSharingViews() - expect(Navigation.views.length).toBe(6) + expect(Navigation.views.length).toBe(7) Navigation.views.forEach(async (view: View) => { const content = await view.getContents('/') expect(content.contents).toStrictEqual([]) diff --git a/apps/files_sharing/src/views/shares.ts b/apps/files_sharing/src/views/shares.ts index 98b68ee25e2..7aec0dbeafb 100644 --- a/apps/files_sharing/src/views/shares.ts +++ b/apps/files_sharing/src/views/shares.ts @@ -10,9 +10,10 @@ import AccountGroupSvg from '@mdi/svg/svg/account-group.svg?raw' import AccountPlusSvg from '@mdi/svg/svg/account-plus.svg?raw' import AccountSvg from '@mdi/svg/svg/account.svg?raw' import DeleteSvg from '@mdi/svg/svg/delete.svg?raw' +import FileUploadSvg from '@mdi/svg/svg/file-upload.svg?raw' import LinkSvg from '@mdi/svg/svg/link.svg?raw' -import { getContents } from '../services/SharingService' +import { getContents, isFileRequest } from '../services/SharingService' export const sharesViewId = 'shareoverview' export const sharedWithYouViewId = 'sharingin' @@ -20,6 +21,7 @@ export const sharedWithOthersViewId = 'sharingout' export const sharingByLinksViewId = 'sharinglinks' export const deletedSharesViewId = 'deletedshares' export const pendingSharesViewId = 'pendingshares' +export const fileRequestViewId = 'filerequest' export default () => { const Navigation = getNavigation() @@ -91,6 +93,29 @@ export default () => { })) Navigation.register(new View({ + id: fileRequestViewId, + name: t('files_sharing', 'File requests'), + caption: t('files_sharing', 'List of file requests.'), + + emptyTitle: t('files_sharing', 'No file requests'), + emptyCaption: t('files_sharing', 'File requests you have created will show up here'), + + icon: FileUploadSvg, + order: 4, + parent: sharesViewId, + + columns: [], + + getContents: () => getContents(false, true, false, false, [ShareType.Link, ShareType.Email]) + .then(({ folder, contents }) => { + return { + folder, + contents: contents.filter((node) => isFileRequest(node.attributes?.['share-attributes'] || [])), + } + }), + })) + + Navigation.register(new View({ id: deletedSharesViewId, name: t('files_sharing', 'Deleted shares'), caption: t('files_sharing', 'List of shares you left.'), @@ -99,7 +124,7 @@ export default () => { emptyCaption: t('files_sharing', 'Shares you have left will show up here'), icon: DeleteSvg, - order: 4, + order: 5, parent: sharesViewId, columns: [], @@ -116,7 +141,7 @@ export default () => { emptyCaption: t('files_sharing', 'Shares you have received but not approved will show up here'), icon: AccountClockSvg, - order: 5, + order: 6, parent: sharesViewId, columns: [], |