Merge pull request #18707 from nextcloud/enh/pending_shares_overview

A pending shares overview
This commit is contained in:
Roeland Jago Douma 2020-01-07 20:54:58 +01:00 committed by GitHub
commit 4d1f710dc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 176 additions and 1 deletions

View file

@ -129,6 +129,7 @@
}
.nav-icon-sharingin,
.nav-icon-sharingout,
.nav-icon-pendingshares,
.nav-icon-shareoverview {
@include icon-color('share', 'files', $color-black);
}

View file

@ -288,6 +288,13 @@ class ViewControllerTest extends TestCase {
'order' => 19,
'name' => \OC::$server->getL10N('files_sharing')->t('Deleted shares'),
],
[
'id' => 'pendingshares',
'appname' => 'files_sharing',
'script' => 'list.php',
'order' => 19,
'name' => \OC::$server->getL10N('files_sharing')->t('Pending shares'),
],
],
'active' => false,
'icon' => '',
@ -348,6 +355,10 @@ class ViewControllerTest extends TestCase {
'id' => 'deletedshares',
'content' => null,
],
'pendingshares' => [
'id' => 'pendingshares',
'content' => null
],
'shareoverview' => [
'id' => 'shareoverview',
'content' => null,

View file

@ -75,6 +75,11 @@ return [
'url' => '/api/v1/shares',
'verb' => 'POST',
],
[
'name' => 'ShareAPI#pendingShares',
'url' => '/api/v1/shares/pending',
'verb' => 'GET',
],
[
'name' => 'ShareAPI#getShare',
'url' => '/api/v1/shares/{id}',

View file

@ -22,6 +22,7 @@ OCA.Sharing.App = {
_inFileList: null,
_outFileList: null,
_overviewFileList: null,
_pendingFileList: null,
initSharingIn: function($el) {
if (this._inFileList) {
@ -129,6 +130,33 @@ OCA.Sharing.App = {
return this._deletedFileList
},
initSharingPening: function($el) {
if (this._pendingFileList) {
return this._pendingFileList
}
this._pendingFileList = new OCA.Sharing.FileList(
$el,
{
id: 'shares.pending',
showPending: true,
sharedWithUser: true,
fileActions: this._acceptShareAction(),
config: OCA.Files.App.getFilesConfig(),
// The file list is created when a "show" event is handled, so
// it should be marked as "shown" like it would have been done
// if handling the event with the file list already created.
shown: true,
}
)
this._extendFileList(this._pendingFileList)
this._pendingFileList.appName = t('files_sharing', 'Pending shares')
this._pendingFileList.$el.find('#emptycontent').html('<div class="icon-share"></div>'
+ '<h2>' + t('files_sharing', 'No pending shares') + '</h2>'
+ '<p>' + t('files_sharing', 'Shares you have received but not confirmed will show up here') + '</p>')
return this._pendingFileList
},
initShareingOverview: function($el) {
if (this._overviewFileList) {
return this._overviewFileList
@ -178,6 +206,12 @@ OCA.Sharing.App = {
}
},
removeSharingPending: function() {
if (this._pendingFileList) {
this._pendingFileList.$fileList.empty()
}
},
removeSharingOverview: function() {
if (this._overviewFileList) {
this._overviewFileList.$fileList.empty()
@ -249,6 +283,47 @@ OCA.Sharing.App = {
return fileActions
},
_acceptShareAction: function() {
const fileActions = new OCA.Files.FileActions()
fileActions.registerAction({
name: 'Accept share',
displayName: t('files_sharing', 'Accept share'),
mime: 'all',
permissions: OC.PERMISSION_ALL,
iconClass: 'icon-checkmark',
type: OCA.Files.FileActions.TYPE_INLINE,
actionHandler: function(fileName, context) {
const shareId = context.$file.data('shareId')
$.post(OC.linkToOCS('apps/files_sharing/api/v1/shares/pending', 2) + shareId)
.success(function(result) {
context.fileList.remove(context.fileInfoModel.attributes.name)
}).fail(function() {
OC.Notification.showTemporary(t('files_sharing', 'Something happened. Unable to accept the share.'))
})
},
})
fileActions.registerAction({
name: 'Reject share',
displayName: t('files_sharing', 'Reject share'),
mime: 'all',
permissions: OC.PERMISSION_ALL,
iconClass: 'icon-close',
type: OCA.Files.FileActions.TYPE_INLINE,
actionHandler: function(fileName, context) {
const shareId = context.$file.data('shareId')
$.ajax({
url: OC.linkToOCS('apps/files_sharing/api/v1/shares', 2) + shareId,
type: 'DELETE',
}).success(function(result) {
context.fileList.remove(context.fileInfoModel.attributes.name)
}).fail(function() {
OC.Notification.showTemporary(t('files_sharing', 'Something happened. Unable to reject the share.'))
})
},
})
return fileActions
},
_onActionsUpdated: function(ev) {
_.each([this._inFileList, this._outFileList, this._linkFileList], function(list) {
if (!list) {
@ -297,6 +372,12 @@ $(document).ready(function() {
$('#app-content-deletedshares').on('hide', function() {
OCA.Sharing.App.removeSharingDeleted()
})
$('#app-content-pendingshares').on('show', function(e) {
OCA.Sharing.App.initSharingPening($(e.target))
})
$('#app-content-pendingshares').on('hide', function() {
OCA.Sharing.App.removeSharingPending()
})
$('#app-content-shareoverview').on('show', function(e) {
OCA.Sharing.App.initShareingOverview($(e.target))
})

Binary file not shown.

Binary file not shown.

View file

@ -39,6 +39,7 @@
_sharedWithUser: false,
_linksOnly: false,
_showDeleted: false,
_showPending: false,
_clientSideSort: true,
_allowSelection: false,
_isOverview: false,
@ -62,6 +63,9 @@
if (options && options.showDeleted) {
this._showDeleted = true
}
if (options && options.showPending) {
this._showPending = true
}
if (options && options.isOverview) {
this._isOverview = true
}
@ -87,7 +91,7 @@
var permission = parseInt($tr.attr('data-permissions')) | OC.PERMISSION_DELETE
$tr.attr('data-permissions', permission)
}
if (this._showDeleted) {
if (this._showDeleted || this._showPending) {
var permission = fileData.permissions
$tr.attr('data-share-permissions', permission)
}
@ -196,6 +200,18 @@
}
}
var pendingShares = {
url: OC.linkToOCS('apps/files_sharing/api/v1/shares', 2) + 'pending',
/* jshint camelcase: false */
data: {
format: 'json'
},
type: 'GET',
beforeSend: function(xhr) {
xhr.setRequestHeader('OCS-APIREQUEST', 'true')
}
}
var shares = {
url: OC.linkToOCS('apps/files_sharing/api/v1') + 'shares',
/* jshint camelcase: false */
@ -227,6 +243,8 @@
// and make sure we have 2 promises
if (this._showDeleted) {
promises.push($.ajax(deletedShares))
} else if (this._showPending) {
promises.push($.ajax(pendingShares))
} else {
promises.push($.ajax(shares))

View file

@ -278,6 +278,15 @@ class Application extends App {
'name' => $l->t('Deleted shares'),
]);
array_push($sharingSublistArray, [
'id' => 'pendingshares',
'appname' => 'files_sharing',
'script' => 'list.php',
'order' => 19,
'name' => $l->t('Pending shares'),
]);
// show_Quick_Access stored as string
\OCA\Files\App::getNavigationManager()->add([
'id' => 'shareoverview',

View file

@ -1079,6 +1079,56 @@ class ShareAPIController extends OCSController {
return new DataResponse($this->formatShare($share));
}
/**
* @NoAdminRequired
*/
public function pendingShares(): DataResponse {
$pendingShares = [];
$shareTypes = [
IShare::TYPE_USER,
IShare::TYPE_GROUP
];
foreach ($shareTypes as $shareType) {
$shares = $this->shareManager->getSharedWith($this->currentUser, $shareType, null, -1, 0);
foreach ($shares as $share) {
if ($share->getStatus() === IShare::STATUS_PENDING || $share->getStatus() === IShare::STATUS_REJECTED) {
$pendingShares[] = $share;
}
}
}
$result = array_filter(array_map(function (IShare $share) {
$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
$nodes = $userFolder->getById($share->getNodeId());
if (empty($nodes)) {
// fallback to guessing the path
$node = $userFolder->get($share->getTarget());
if ($node === null || $share->getTarget() === '') {
return null;
}
} else {
$node = $nodes[0];
}
try {
$formattedShare = $this->formatShare($share, $node);
$formattedShare['status'] = $share->getStatus();
$formattedShare['path'] = $share->getNode()->getName();
$formattedShare['permissions'] = 0;
return $formattedShare;
} catch (NotFoundException $e) {
return null;
}
}, $pendingShares), function ($entry) {
return $entry !== null;
});
return new DataResponse($result);
}
/**
* @NoAdminRequired
*