Hide sidebar tab headers conditionally

Added canDisplay() in DetailsTabView that should return false if the tab
header of this tab must be hidden
This commit is contained in:
Vincent Petry 2015-09-25 13:23:39 +02:00
parent d68079f932
commit a8fb0038e9
4 changed files with 135 additions and 17 deletions

View File

@ -140,16 +140,14 @@
}
return orderA - orderB;
});
if (this._tabViews.length > 1) {
// only render headers if there is more than one available
templateVars.tabHeaders = _.map(this._tabViews, function(tabView, i) {
return {
tabId: tabView.id,
tabIndex: i,
label: tabView.getLabel()
};
});
}
templateVars.tabHeaders = _.map(this._tabViews, function(tabView, i) {
return {
tabId: tabView.id,
tabIndex: i,
label: tabView.getLabel()
};
});
this.$el.html(this.template(templateVars));
@ -166,6 +164,8 @@
this.selectTab(this._currentTabId);
this._updateTabVisibilities();
this._dirty = false;
},
@ -224,6 +224,8 @@
if (this._dirty) {
this.render();
} else {
this._updateTabVisibilities();
}
if (this._currentTabId) {
@ -240,6 +242,37 @@
});
},
/**
* Update tab headers based on the current model
*/
_updateTabVisibilities: function() {
// update tab header visibilities
var self = this;
var deselect = false;
var countVisible = 0;
var $tabHeaders = this.$el.find('.tabHeaders li');
_.each(this._tabViews, function(tabView) {
var isVisible = tabView.canDisplay(self.model);
if (isVisible) {
countVisible += 1;
}
if (!isVisible && self._currentTabId === tabView.id) {
deselect = true;
}
$tabHeaders.filterAttr('data-tabid', tabView.id).toggleClass('hidden', !isVisible);
});
// hide the whole container if there is only one tab
this.$el.find('.tabHeaders').toggleClass('hidden', countVisible <= 1);
if (deselect) {
// select the first visible tab instead
var visibleTabId = this.$el.find('.tabHeader:not(.hidden):first').attr('data-tabid');
this.selectTab(visibleTabId);
}
},
/**
* Returns the file info.
*

View File

@ -95,6 +95,17 @@
*/
nextPage: function() {
// load the next page, if applicable
},
/**
* Returns whether the current tab is able to display
* the given file info, for example based on mime type.
*
* @param {OCA.Files.FileInfoModel} fileInfo file info model
* @return {bool} whether to display this tab
*/
canDisplay: function(fileInfo) {
return true;
}
});
DetailTabView._TAB_COUNT = 0;

View File

@ -144,14 +144,76 @@ describe('OCA.Files.DetailsView tests', function() {
expect(detailsView.$el.find('.tab').eq(0).hasClass('hidden')).toEqual(true);
expect(detailsView.$el.find('.tab').eq(1).hasClass('hidden')).toEqual(false);
});
it('does not render tab headers when only one tab exists', function() {
detailsView.remove();
detailsView = new OCA.Files.DetailsView();
testView = new OCA.Files.DetailTabView({id: 'test1'});
detailsView.addTabView(testView);
detailsView.render();
describe('tab visibility', function() {
beforeEach(function() {
detailsView.remove();
detailsView = new OCA.Files.DetailsView();
});
it('does not display tab headers when only one tab exists', function() {
testView = new OCA.Files.DetailTabView({id: 'test1'});
detailsView.addTabView(testView);
detailsView.render();
expect(detailsView.$el.find('.tabHeader').length).toEqual(0);
expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(true);
expect(detailsView.$el.find('.tabHeader').length).toEqual(1);
});
it('does not display tab that do not pass visibility check', function() {
testView = new OCA.Files.DetailTabView({id: 'test1'});
testView.canDisplay = sinon.stub().returns(false);
testView2 = new OCA.Files.DetailTabView({id: 'test2'});
var testView3 = new OCA.Files.DetailTabView({id: 'test3'});
detailsView.addTabView(testView);
detailsView.addTabView(testView2);
detailsView.addTabView(testView3);
var fileInfo = {id: 5, name: 'test.txt'};
detailsView.setFileInfo(fileInfo);
expect(testView.canDisplay.calledOnce).toEqual(true);
expect(testView.canDisplay.calledWith(fileInfo)).toEqual(true);
expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(false);
expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('hidden')).toEqual(true);
expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('hidden')).toEqual(false);
expect(detailsView.$el.find('.tabHeader[data-tabid=test3]').hasClass('hidden')).toEqual(false);
});
it('does not show tab headers if only one header is visible due to visibility check', function() {
testView = new OCA.Files.DetailTabView({id: 'test1'});
testView.canDisplay = sinon.stub().returns(false);
testView2 = new OCA.Files.DetailTabView({id: 'test2'});
detailsView.addTabView(testView);
detailsView.addTabView(testView2);
var fileInfo = {id: 5, name: 'test.txt'};
detailsView.setFileInfo(fileInfo);
expect(testView.canDisplay.calledOnce).toEqual(true);
expect(testView.canDisplay.calledWith(fileInfo)).toEqual(true);
expect(detailsView.$el.find('.tabHeaders').hasClass('hidden')).toEqual(true);
expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('hidden')).toEqual(true);
expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('hidden')).toEqual(false);
});
it('deselects the current tab if a model update does not pass the visibility check', function() {
testView = new OCA.Files.DetailTabView({id: 'test1'});
testView.canDisplay = function(fileInfo) {
return fileInfo.mimetype !== 'httpd/unix-directory';
};
testView2 = new OCA.Files.DetailTabView({id: 'test2'});
detailsView.addTabView(testView);
detailsView.addTabView(testView2);
var fileInfo = {id: 5, name: 'test.txt', mimetype: 'text/plain'};
detailsView.setFileInfo(fileInfo);
expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('selected')).toEqual(true);
expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('selected')).toEqual(false);
detailsView.setFileInfo({id: 10, name: 'folder', mimetype: 'httpd/unix-directory'});
expect(detailsView.$el.find('.tabHeader[data-tabid=test1]').hasClass('selected')).toEqual(false);
expect(detailsView.$el.find('.tabHeader[data-tabid=test2]').hasClass('selected')).toEqual(true);
});
});
it('sorts by order and then label', function() {
detailsView.remove();

View File

@ -189,6 +189,18 @@
this.$el.find('.has-tooltip').tooltip();
this.$versionsContainer = this.$el.find('ul.versions');
this.delegateEvents();
},
/**
* Returns true for files, false for folders.
*
* @return {bool} true for files, false for folders
*/
canDisplay: function(fileInfo) {
if (!fileInfo) {
return false;
}
return !fileInfo.isDirectory();
}
});