Merge branch '35408-group-auto-avatars' into 'master'
Show auto-generated avatars in Groups dashboard tree for Groups without avatars See merge request !13188
This commit is contained in:
commit
489a954942
7 changed files with 141 additions and 2 deletions
45
app/assets/javascripts/groups/components/group_identicon.vue
Normal file
45
app/assets/javascripts/groups/components/group_identicon.vue
Normal file
|
@ -0,0 +1,45 @@
|
|||
<script>
|
||||
export default {
|
||||
props: {
|
||||
entityId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
entityName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
/**
|
||||
* This method is based on app/helpers/application_helper.rb#project_identicon
|
||||
*/
|
||||
identiconStyles() {
|
||||
const allowedColors = [
|
||||
'#FFEBEE',
|
||||
'#F3E5F5',
|
||||
'#E8EAF6',
|
||||
'#E3F2FD',
|
||||
'#E0F2F1',
|
||||
'#FBE9E7',
|
||||
'#EEEEEE',
|
||||
];
|
||||
|
||||
const backgroundColor = allowedColors[this.entityId % 7];
|
||||
|
||||
return `background-color: ${backgroundColor}; color: #555;`;
|
||||
},
|
||||
identiconTitle() {
|
||||
return this.entityName.charAt(0).toUpperCase();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="avatar s40 identicon"
|
||||
:style="identiconStyles">
|
||||
{{identiconTitle}}
|
||||
</div>
|
||||
</template>
|
|
@ -1,7 +1,11 @@
|
|||
<script>
|
||||
import eventHub from '../event_hub';
|
||||
import groupIdenticon from './group_identicon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
groupIdenticon,
|
||||
},
|
||||
props: {
|
||||
group: {
|
||||
type: Object,
|
||||
|
@ -92,6 +96,9 @@ export default {
|
|||
hasGroups() {
|
||||
return Object.keys(this.group.subGroups).length > 0;
|
||||
},
|
||||
hasAvatar() {
|
||||
return this.group.avatarUrl && this.group.avatarUrl.indexOf('/assets/no_group_avatar') === -1;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -194,9 +201,15 @@ export default {
|
|||
<a
|
||||
:href="group.groupPath">
|
||||
<img
|
||||
v-if="hasAvatar"
|
||||
class="avatar s40"
|
||||
:src="group.avatarUrl"
|
||||
/>
|
||||
<group-identicon
|
||||
v-else
|
||||
:entity-id=group.id
|
||||
:entity-name="group.name"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -369,6 +369,10 @@ ul.indent-list {
|
|||
background-color: $row-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.avatar-container > a {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
4
changelogs/unreleased/35408-group-auto-avatars.yml
Normal file
4
changelogs/unreleased/35408-group-auto-avatars.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Show auto-generated avatars for Groups without avatars
|
||||
merge_request: 13188
|
||||
author:
|
60
spec/javascripts/groups/group_identicon_spec.js
Normal file
60
spec/javascripts/groups/group_identicon_spec.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
import Vue from 'vue';
|
||||
import groupIdenticonComponent from '~/groups/components/group_identicon.vue';
|
||||
import GroupsStore from '~/groups/stores/groups_store';
|
||||
import { group1 } from './mock_data';
|
||||
|
||||
const createComponent = () => {
|
||||
const Component = Vue.extend(groupIdenticonComponent);
|
||||
const store = new GroupsStore();
|
||||
const group = store.decorateGroup(group1);
|
||||
|
||||
return new Component({
|
||||
propsData: {
|
||||
entityId: group.id,
|
||||
entityName: group.name,
|
||||
},
|
||||
}).$mount();
|
||||
};
|
||||
|
||||
describe('GroupIdenticonComponent', () => {
|
||||
let vm;
|
||||
|
||||
beforeEach(() => {
|
||||
vm = createComponent();
|
||||
});
|
||||
|
||||
describe('computed', () => {
|
||||
describe('identiconStyles', () => {
|
||||
it('should return styles attribute value with `background-color` property', () => {
|
||||
vm.entityId = 4;
|
||||
|
||||
expect(vm.identiconStyles).toBeDefined();
|
||||
expect(vm.identiconStyles.indexOf('background-color: #E0F2F1;') > -1).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return styles attribute value with `color` property', () => {
|
||||
vm.entityId = 4;
|
||||
|
||||
expect(vm.identiconStyles).toBeDefined();
|
||||
expect(vm.identiconStyles.indexOf('color: #555;') > -1).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('identiconTitle', () => {
|
||||
it('should return first letter of entity title in uppercase', () => {
|
||||
vm.entityName = 'dummy-group';
|
||||
|
||||
expect(vm.identiconTitle).toBeDefined();
|
||||
expect(vm.identiconTitle).toBe('D');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('template', () => {
|
||||
it('should render identicon', () => {
|
||||
expect(vm.$el.nodeName).toBe('DIV');
|
||||
expect(vm.$el.classList.contains('identicon')).toBeTruthy();
|
||||
expect(vm.$el.getAttribute('style').indexOf('background-color') > -1).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -64,6 +64,19 @@ describe('Groups Component', () => {
|
|||
expect(lists[2].querySelector('#group-1120').textContent).toContain(groups.id1119.subGroups.id1120.name);
|
||||
});
|
||||
|
||||
it('should render group identicon when group avatar is not present', () => {
|
||||
const avatar = component.$el.querySelector('#group-12 .avatar-container .avatar');
|
||||
expect(avatar.nodeName).toBe('DIV');
|
||||
expect(avatar.classList.contains('identicon')).toBeTruthy();
|
||||
expect(avatar.getAttribute('style').indexOf('background-color') > -1).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render group avatar when group avatar is present', () => {
|
||||
const avatar = component.$el.querySelector('#group-1120 .avatar-container .avatar');
|
||||
expect(avatar.nodeName).toBe('IMG');
|
||||
expect(avatar.classList.contains('identicon')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should remove prefix of parent group', () => {
|
||||
expect(component.$el.querySelector('#group-12 #group-1128 .title').textContent).toContain('level2 / level3 / level4');
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const group1 = {
|
||||
id: '12',
|
||||
id: 12,
|
||||
name: 'level1',
|
||||
path: 'level1',
|
||||
description: 'foo',
|
||||
|
@ -71,7 +71,7 @@ const group21 = {
|
|||
path: 'chef',
|
||||
description: 'foo',
|
||||
visibility: 'public',
|
||||
avatar_url: null,
|
||||
avatar_url: '/uploads/-/system/group/avatar/2/GitLab.png',
|
||||
web_url: 'http://localhost:3000/groups/devops/chef',
|
||||
group_path: '/devops/chef',
|
||||
full_name: 'devops / chef',
|
||||
|
|
Loading…
Reference in a new issue