Add "Favorite" action to the file actions menu
The new FileAction for the menu is essentially the same as the old inline FileAction, except for the rendering; in this case the FileAction is shown in the menu in a standard way, so there is no need to provide a custom renderer (although the menu entry text and icon change depending on whether the file is currently a favorite or not, but that can be done just with displayName and iconClass functions). Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
parent
a8f1902b02
commit
420d1b91ab
|
@ -502,7 +502,7 @@ table td.filename .uploadtext {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
#fileList tr td.filename .action-favorite {
|
#fileList tr td.filename .action-favorite:not(.menuitem) {
|
||||||
display: block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
var self = this;
|
var self = this;
|
||||||
// register "star" action
|
// register "star" action
|
||||||
fileActions.registerAction({
|
fileActions.registerAction({
|
||||||
name: 'Favorite',
|
name: 'FavoriteInline',
|
||||||
displayName: t('files', 'Favorite'),
|
displayName: t('files', 'Favorite'),
|
||||||
mime: 'all',
|
mime: 'all',
|
||||||
permissions: OC.PERMISSION_READ,
|
permissions: OC.PERMISSION_READ,
|
||||||
|
@ -141,6 +141,79 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fileActions.registerAction({
|
||||||
|
name: 'Favorite',
|
||||||
|
displayName: function(context) {
|
||||||
|
var $file = context.$file;
|
||||||
|
var isFavorite = $file.data('favorite') === true;
|
||||||
|
|
||||||
|
if (isFavorite) {
|
||||||
|
return t('files', 'Remove from favorites');
|
||||||
|
}
|
||||||
|
|
||||||
|
// As it is currently not possible to provide a context for
|
||||||
|
// the i18n strings "Add to favorites" was used instead of
|
||||||
|
// "Favorite" to remove the ambiguity between verb and noun
|
||||||
|
// when it is translated.
|
||||||
|
return t('files', 'Add to favorites');
|
||||||
|
},
|
||||||
|
mime: 'all',
|
||||||
|
order: -23,
|
||||||
|
permissions: OC.PERMISSION_READ,
|
||||||
|
iconClass: function(fileName, context) {
|
||||||
|
var $file = context.$file;
|
||||||
|
var isFavorite = $file.data('favorite') === true;
|
||||||
|
|
||||||
|
if (isFavorite) {
|
||||||
|
return 'icon-starred';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'icon-star';
|
||||||
|
},
|
||||||
|
actionHandler: function(fileName, context) {
|
||||||
|
var $actionEl = context.$file.find('.action-favorite');
|
||||||
|
var $file = context.$file;
|
||||||
|
var fileInfo = context.fileList.files[$file.index()];
|
||||||
|
var dir = context.dir || context.fileList.getCurrentDirectory();
|
||||||
|
var tags = $file.attr('data-tags');
|
||||||
|
if (_.isUndefined(tags)) {
|
||||||
|
tags = '';
|
||||||
|
}
|
||||||
|
tags = tags.split('|');
|
||||||
|
tags = _.without(tags, '');
|
||||||
|
var isFavorite = tags.indexOf(OC.TAG_FAVORITE) >= 0;
|
||||||
|
if (isFavorite) {
|
||||||
|
// remove tag from list
|
||||||
|
tags = _.without(tags, OC.TAG_FAVORITE);
|
||||||
|
} else {
|
||||||
|
tags.push(OC.TAG_FAVORITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pre-toggle the star
|
||||||
|
toggleStar($actionEl, !isFavorite);
|
||||||
|
|
||||||
|
context.fileInfoModel.trigger('busy', context.fileInfoModel, true);
|
||||||
|
|
||||||
|
self.applyFileTags(
|
||||||
|
dir + '/' + fileName,
|
||||||
|
tags,
|
||||||
|
$actionEl,
|
||||||
|
isFavorite
|
||||||
|
).then(function(result) {
|
||||||
|
context.fileInfoModel.trigger('busy', context.fileInfoModel, false);
|
||||||
|
// response from server should contain updated tags
|
||||||
|
var newTags = result.tags;
|
||||||
|
if (_.isUndefined(newTags)) {
|
||||||
|
newTags = tags;
|
||||||
|
}
|
||||||
|
context.fileInfoModel.set({
|
||||||
|
'tags': newTags,
|
||||||
|
'favorite': !isFavorite
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_extendFileList: function(fileList) {
|
_extendFileList: function(fileList) {
|
||||||
|
|
|
@ -117,6 +117,62 @@ describe('OCA.Files.TagsPlugin tests', function() {
|
||||||
$tr = fileList.findFileEl('One.txt');
|
$tr = fileList.findFileEl('One.txt');
|
||||||
$action = $tr.find('.action-favorite');
|
$action = $tr.find('.action-favorite');
|
||||||
|
|
||||||
|
expect($tr.attr('data-favorite')).toBeFalsy();
|
||||||
|
expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', 'tag3']);
|
||||||
|
expect(fileList.files[0].tags).toEqual(['tag1', 'tag2', 'tag3']);
|
||||||
|
expect($action.find('.icon').hasClass('icon-star')).toEqual(true);
|
||||||
|
expect($action.find('.icon').hasClass('icon-starred')).toEqual(false);
|
||||||
|
});
|
||||||
|
it('through FileActionsMenu sends request to server and updates icon', function() {
|
||||||
|
var request;
|
||||||
|
fileList.setFiles(testFiles);
|
||||||
|
var $tr = fileList.findFileEl('One.txt');
|
||||||
|
var $action = $tr.find('.action-favorite');
|
||||||
|
var $showMenuAction = $tr.find('.action-menu');
|
||||||
|
$showMenuAction.click();
|
||||||
|
var $favoriteActionInMenu = $tr.find('.fileActionsMenu .action-favorite');
|
||||||
|
$favoriteActionInMenu.click();
|
||||||
|
|
||||||
|
expect(fakeServer.requests.length).toEqual(1);
|
||||||
|
request = fakeServer.requests[0];
|
||||||
|
expect(JSON.parse(request.requestBody)).toEqual({
|
||||||
|
tags: ['tag1', 'tag2', OC.TAG_FAVORITE]
|
||||||
|
});
|
||||||
|
request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||||
|
tags: ['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE]
|
||||||
|
}));
|
||||||
|
|
||||||
|
// re-read the element as it was re-inserted
|
||||||
|
$tr = fileList.findFileEl('One.txt');
|
||||||
|
$action = $tr.find('.action-favorite');
|
||||||
|
$showMenuAction = $tr.find('.action-menu');
|
||||||
|
|
||||||
|
expect($tr.attr('data-favorite')).toEqual('true');
|
||||||
|
expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE]);
|
||||||
|
expect(fileList.files[0].tags).toEqual(['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE]);
|
||||||
|
expect($action.find('.icon').hasClass('icon-star')).toEqual(false);
|
||||||
|
expect($action.find('.icon').hasClass('icon-starred')).toEqual(true);
|
||||||
|
|
||||||
|
// show again the menu and get the new action, as the menu was
|
||||||
|
// closed and removed (and with it, the previous action) when that
|
||||||
|
// action was clicked
|
||||||
|
$showMenuAction.click();
|
||||||
|
$favoriteActionInMenu = $tr.find('.fileActionsMenu .action-favorite');
|
||||||
|
$favoriteActionInMenu.click();
|
||||||
|
|
||||||
|
expect(fakeServer.requests.length).toEqual(2);
|
||||||
|
request = fakeServer.requests[1];
|
||||||
|
expect(JSON.parse(request.requestBody)).toEqual({
|
||||||
|
tags: ['tag1', 'tag2', 'tag3']
|
||||||
|
});
|
||||||
|
request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||||
|
tags: ['tag1', 'tag2', 'tag3']
|
||||||
|
}));
|
||||||
|
|
||||||
|
// re-read the element as it was re-inserted
|
||||||
|
$tr = fileList.findFileEl('One.txt');
|
||||||
|
$action = $tr.find('.action-favorite');
|
||||||
|
|
||||||
expect($tr.attr('data-favorite')).toBeFalsy();
|
expect($tr.attr('data-favorite')).toBeFalsy();
|
||||||
expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', 'tag3']);
|
expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', 'tag3']);
|
||||||
expect(fileList.files[0].tags).toEqual(['tag1', 'tag2', 'tag3']);
|
expect(fileList.files[0].tags).toEqual(['tag1', 'tag2', 'tag3']);
|
||||||
|
|
Loading…
Reference in New Issue