Commit 859ec584 authored by Phil Hughes's avatar Phil Hughes

Merge branch '335522-update-operations-dashboard-project-header' into 'master'

Use GlAvatar in operations dashboard

See merge request gitlab-org/gitlab!81233
parents 56a33152 22b27542
<script>
import { GlButton, GlLink, GlTooltipDirective } from '@gitlab/ui';
import { __ } from '~/locale';
import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue';
import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
export default {
components: {
......@@ -49,26 +49,35 @@ export default {
</script>
<template>
<div :class="headerClasses" class="card-header border-0 py-2 d-flex align-items-center">
<project-avatar :project="project" :size="24" class="flex-shrink-0 border rounded" />
<div class="flex-grow-1 block-truncated">
<div
:class="headerClasses"
class="card-header gl-border-0 gl-py-3 gl-display-flex gl-align-items-center"
>
<project-avatar
:project-name="project.name"
:project-avatar-url="project.avatar_url"
:size="24"
class="gl-mr-3"
/>
<div class="gl-flex-grow-1 block-truncated">
<gl-link
v-gl-tooltip
class="js-project-link cgray"
class="gl-text-black-normal"
:href="project.web_url"
:title="project.name_with_namespace"
data-testid="project-link"
>
<span class="js-project-namespace">{{ project.namespace.name }} /</span>
<span class="js-project-name bold"> {{ project.name }}</span>
<span data-testid="project-namespace">{{ project.namespace.name }} /</span>
<span class="gl-font-weight-bold" data-testid="project-name"> {{ project.name }}</span>
</gl-link>
</div>
<gl-button
v-gl-tooltip
class="js-remove-button"
category="tertiary"
:title="title"
:aria-label="title"
icon="remove"
data-testid="remove-project-button"
@click="onRemove"
/>
</div>
......
......@@ -121,7 +121,7 @@ describe('dashboard component', () => {
mockAxios.onDelete(store.state.projects[0].remove_path).reply(200);
mockAxios.onGet(mockListEndpoint).replyOnce(200, { projects: [] });
wrapper.find('button.js-remove-button').vm.$emit('click');
wrapper.find('[data-testid="remove-project-button"]').vm.$emit('click');
return waitForPromises().then(() => {
expect(store.state.projects.length).toEqual(0);
......
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ProjectHeader from 'ee/operations/components/dashboard/project_header.vue';
import { trimText } from 'helpers/text_helper';
import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue';
import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
import { mockOneProject } from '../../mock_data';
describe('project header component', () => {
let wrapper;
const factory = () => {
wrapper = shallowMount(ProjectHeader, {
wrapper = shallowMountExtended(ProjectHeader, {
propsData: {
project: mockOneProject,
},
});
};
const findRemoveProjectButton = () => wrapper.findByTestId('remove-project-button');
beforeEach(() => {
factory();
});
......@@ -25,8 +27,8 @@ describe('project header component', () => {
});
it('renders project name with namespace', () => {
const namespace = wrapper.find('.js-project-namespace').text();
const name = wrapper.find('.js-project-name').text();
const namespace = wrapper.findByTestId('project-namespace').text();
const name = wrapper.findByTestId('project-name').text();
expect(trimText(namespace).trim()).toBe(`${mockOneProject.namespace.name} /`);
expect(trimText(name).trim()).toBe(mockOneProject.name);
......@@ -35,24 +37,22 @@ describe('project header component', () => {
it('links project name to project', () => {
const path = mockOneProject.web_url;
expect(wrapper.find('.js-project-link').attributes('href')).toBe(path);
expect(wrapper.findByTestId('project-link').attributes('href')).toBe(path);
});
describe('remove button', () => {
it('renders removal button icon', () => {
expect(wrapper.find('.js-remove-button').exists()).toBe(true);
expect(findRemoveProjectButton().props('icon')).toBe('remove');
});
it('renders correct title for removal icon', () => {
const button = wrapper.find('.js-remove-button');
expect(button.attributes('title')).toBe('Remove card');
expect(findRemoveProjectButton().attributes('title')).toBe('Remove card');
});
it('emits project removal link on click', async () => {
wrapper.find('.js-remove-button').vm.$emit('click');
findRemoveProjectButton().vm.$emit('click');
await nextTick();
expect(wrapper.emitted().remove).toStrictEqual([[mockOneProject.remove_path]]);
});
});
......@@ -64,7 +64,10 @@ describe('project header component', () => {
});
it('binds project', () => {
expect(wrapper.findComponent(ProjectAvatar).props('project')).toEqual(mockOneProject);
expect(wrapper.findComponent(ProjectAvatar).props()).toMatchObject({
projectName: mockOneProject.name,
projectAvatarUrl: mockOneProject.avatar_url,
});
});
});
});
......
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