Unverified Commit b7a83942 authored by Robert Knight's avatar Robert Knight Committed by GitHub

Merge pull request #718 from hypothesis/logos-in-groups-menu

Add organization logos to groups menu
parents 24c70160 f775e0d3
......@@ -3,6 +3,8 @@
var { isThirdPartyUser } = require('../util/account-id');
var isThirdPartyService = require('../util/is-third-party-service');
var serviceConfig = require('../service-config');
const memoize = require('../util/memoize');
const groupOrganizations = memoize(require('../util/group-organizations'));
// @ngInject
function GroupListController($window, analytics, groups, settings, serviceUrl) {
......@@ -12,6 +14,18 @@ function GroupListController($window, analytics, groups, settings, serviceUrl) {
$window.open(serviceUrl('groups.new'), '_blank');
};
this.focusedIcon = function() {
const focusedGroup = this.groups.focused();
return focusedGroup && (
focusedGroup.organization.logo || this.thirdPartyGroupIcon
);
};
this.focusedIconClass = function() {
const focusedGroup = this.groups.focused();
return (focusedGroup && focusedGroup.type === 'private') ? 'group' : 'public';
};
this.isThirdPartyUser = function () {
return isThirdPartyUser(this.auth.userid, settings.authDomain);
};
......@@ -26,6 +40,15 @@ function GroupListController($window, analytics, groups, settings, serviceUrl) {
}
};
this.orgName = function (groupId) {
const group = this.groups.get(groupId);
return group && group.organization && group.organization.name;
};
this.groupOrganizations = function () {
return groupOrganizations(this.groups.all());
};
this.viewGroupActivity = function () {
analytics.track(analytics.events.GROUP_VIEW_ACTIVITY);
};
......
......@@ -5,6 +5,8 @@ var angular = require('angular');
var groupList = require('../group-list');
var util = require('../../directive/test/util');
var groupFixtures = require('../../test/group-fixtures');
describe('groupList', function () {
var $window;
......@@ -58,6 +60,7 @@ describe('groupList', function () {
html: OPEN_GROUP_LINK,
},
name: 'Public Group',
organization: groupFixtures.defaultOrganization(),
type: 'open',
},{
id: 'h-devs',
......@@ -65,6 +68,7 @@ describe('groupList', function () {
html: PRIVATE_GROUP_LINK,
},
name: 'Hypothesis Developers',
organization: groupFixtures.defaultOrganization(),
type: 'private',
}, {
id: 'restricto',
......@@ -72,6 +76,7 @@ describe('groupList', function () {
html: RESTRICTED_GROUP_LINK,
},
name: 'Hello Restricted',
organization: groupFixtures.defaultOrganization(),
type: 'restricted',
}];
......@@ -116,6 +121,101 @@ describe('groupList', function () {
assert.include(nameLinks[2].title, 'Show public annotations'); // Restricted
});
it('should render organization logo for focused group', function () {
const org = groupFixtures.organization({ logo: 'http://www.example.com/foobar' });
const group = groupFixtures.expandedGroup({
organization: org,
});
fakeGroups.focused = () => { return group; };
const element = createGroupList();
const imgEl = element.find('.dropdown-toggle > img.group-list-label__icon');
assert.equal(imgEl[0].src, org.logo);
});
it('should render fallback icon for focused group when no logo (private)', function () {
const org = groupFixtures.organization({ logo: null });
const group = groupFixtures.expandedGroup({
organization: org,
type: 'private',
});
fakeGroups.focused = () => { return group; };
const element = createGroupList();
const iconEl = element.find('.dropdown-toggle > i.h-icon-group');
assert.ok(iconEl[0]);
});
it('should render fallback icon for focused group when no logo (restricted)', function () {
const org = groupFixtures.organization({ logo: null });
const group = groupFixtures.expandedGroup({
organization: org,
type: 'restricted',
});
fakeGroups.focused = () => { return group; };
const element = createGroupList();
const iconEl = element.find('.dropdown-toggle > i.h-icon-public');
assert.ok(iconEl[0]);
});
it('should render fallback icon for focused group when no logo (open)', function () {
const org = groupFixtures.organization({ logo: null });
const group = groupFixtures.expandedGroup({
organization: org,
type: 'open',
});
fakeGroups.focused = () => { return group; };
const element = createGroupList();
const iconEl = element.find('.dropdown-toggle > i.h-icon-public');
assert.ok(iconEl[0]);
});
it('should render organization icons for first group in each organization', function () {
const orgs = [
groupFixtures.defaultOrganization(),
groupFixtures.organization(),
];
groups = [
groupFixtures.expandedGroup({ organization: orgs[0] }),
groupFixtures.expandedGroup({ organization: orgs[0] }),
groupFixtures.expandedGroup({ organization: orgs[1] }),
groupFixtures.expandedGroup({ organization: orgs[1] }),
];
const element = createGroupList();
const iconContainers = element.find('.group-menu-icon-container');
const iconImages = element.find('.group-menu-icon-container > img');
assert.lengthOf(iconContainers, groups.length);
assert.lengthOf(iconImages, orgs.length);
});
it('should not render organization icons for menu groups if missing', function () {
const orgs = [
groupFixtures.organization({ logo: null }),
groupFixtures.organization({ logo: null }),
];
groups = [
groupFixtures.expandedGroup({ organization: orgs[0] }),
groupFixtures.expandedGroup({ organization: orgs[0] }),
groupFixtures.expandedGroup({ organization: orgs[1] }),
groupFixtures.expandedGroup({ organization: orgs[1] }),
];
const element = createGroupList();
const iconContainers = element.find('.group-menu-icon-container');
const iconImages = element.find('.group-menu-icon-container > img');
assert.lengthOf(iconContainers, groups.length);
assert.lengthOf(iconImages, 0);
});
it('should render share links', function () {
var element = createGroupList();
var shareLinks = element.find('.share-link-container');
......
......@@ -5,34 +5,28 @@
dropdown-toggle
data-toggle="dropdown"
role="button"
ng-switch on="vm.groups.focused().type == 'open'"
title="Change the selected group">
<img class="group-list-label__icon group-list-label__icon--third-party"
ng-src="{{ vm.thirdPartyGroupIcon }}"
ng-if="vm.thirdPartyGroupIcon"
ng-switch-when="true"><!-- nospace
!--><i class="group-list-label__icon h-icon-public"
ng-switch-when="true"
ng-if="!vm.thirdPartyGroupIcon"></i><!-- nospace
!--><i class="group-list-label__icon h-icon-group"
ng-switch-default></i>
<span class="group-list-label__label">{{vm.groups.focused().name}}</span><!-- nospace
<img class="group-list-label__icon group-list-label__icon--organization"
ng-src="{{ vm.focusedIcon() }}"
alt="{{ vm.orgName(vm.groups.focused().id)}}"
ng-if="vm.focusedIcon()">
<i class="group-list-label__icon h-icon-{{ vm.focusedIconClass() }}"
ng-if="!vm.focusedIcon()"></i><!-- nospace
!--><span class="group-list-label__label">{{vm.groups.focused().name}}</span><!-- nospace
!--><i class="h-icon-arrow-drop-down"></i>
</div>
<div class="dropdown-menu__top-arrow"></div>
<ul class="dropdown-menu pull-none" role="menu">
<li class="dropdown-menu__row dropdown-menu__row--unpadded "
ng-repeat="group in vm.groups.all()">
ng-repeat="group in vm.groupOrganizations() track by group.id">
<div ng-class="{'group-item': true, selected: group.id == vm.groups.focused().id}"
ng-click="vm.focusGroup(group.id)">
<!-- the group icon !-->
<div class="group-icon-container" ng-switch on="group.type == 'open'">
<img class="group-list-label__icon group-list-label__icon--third-party"
ng-src="{{ vm.thirdPartyGroupIcon }}"
ng-if="vm.thirdPartyGroupIcon"
ng-switch-when="true">
<i class="h-icon-public" ng-if="!vm.thirdPartyGroupIcon" ng-switch-when="true"></i>
<i class="h-icon-group" ng-switch-default></i>
<div class="group-menu-icon-container">
<img class="group-list-label__icon group-list-label__icon--organization"
alt="{{ vm.orgName(group.id) }}"
ng-src="{{ group.logo }}"
ng-if="group.logo">
</div>
<!-- the group name and share link !-->
<div class="group-details">
......@@ -69,7 +63,7 @@
<div class="group-icon-container"><i class="h-icon-add"></i></div>
<div class="group-details">
<a href="" class="group-name-link" title="Create a new group to share annotations">
New group
New private group
</a>
</div>
</div>
......
......@@ -47,6 +47,12 @@ $group-list-spacing-below: 50px;
margin-right: 10px;
}
.group-menu-icon-container {
margin-right: 10px;
width: 15px;
height: 15px;
}
.group-cancel-icon-container {
// the 'Leave group' icon is shifted down slightly
// so that it lines up vertically with the 'chat heads' icon on the
......@@ -88,7 +94,7 @@ $group-list-spacing-below: 50px;
transform: translateY(1px);
}
.group-list-label__icon--third-party {
.group-list-label__icon--organization {
height: 15px;
width: 15px;
top: 2px;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment