Merge pull request #18707 from nextcloud/enh/pending_shares_overview
A pending shares overview
This commit is contained in:
commit
4d1f710dc9
|
@ -129,6 +129,7 @@
|
|||
}
|
||||
.nav-icon-sharingin,
|
||||
.nav-icon-sharingout,
|
||||
.nav-icon-pendingshares,
|
||||
.nav-icon-shareoverview {
|
||||
@include icon-color('share', 'files', $color-black);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}',
|
||||
|
|
|
@ -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))
|
||||
})
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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))
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue