aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorskjnldsv <skjnldsv@protonmail.com>2024-07-26 09:51:58 +0200
committernextcloud-command <nextcloud-command@users.noreply.github.com>2024-07-30 09:50:46 +0000
commit850cb082a91d6e18e64fdbaafaa3be9ede59123f (patch)
tree47087d35bbc1dd83873e2a4a25485fbc057cc0d3
parent68864ab3945f8e1b2e2209105e0189905ab07003 (diff)
downloadnextcloud-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.ts20
-rw-r--r--apps/files_sharing/src/views/SharingDetailsTab.vue2
-rw-r--r--apps/files_sharing/src/views/SharingInherited.vue2
-rw-r--r--apps/files_sharing/src/views/SharingTab.vue2
-rw-r--r--apps/files_sharing/src/views/shares.spec.ts9
-rw-r--r--apps/files_sharing/src/views/shares.ts31
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: [],