Commit 7e0ab139 authored by Miguel Rincon's avatar Miguel Rincon

Add tooltips to runners badges

This change adds descriptive tooltips to the runner badges to help
describe each badge.

Changelog: changed
parent c77e8c13
<script>
import { GlBadge } from '@gitlab/ui';
import { GlTooltipDirective } from '@gitlab/ui';
import RunnerTypeBadge from '../runner_type_badge.vue';
import RunnerStateLockedBadge from '../runner_state_locked_badge.vue';
import RunnerStatePausedBadge from '../runner_state_paused_badge.vue';
import { I18N_LOCKED_RUNNER_DESCRIPTION, I18N_PAUSED_RUNNER_DESCRIPTION } from '../../constants';
export default {
components: {
GlBadge,
RunnerTypeBadge,
RunnerStateLockedBadge,
RunnerStatePausedBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
runner: {
......@@ -24,19 +31,17 @@ export default {
return !this.runner.active;
},
},
i18n: {
I18N_LOCKED_RUNNER_DESCRIPTION,
I18N_PAUSED_RUNNER_DESCRIPTION,
},
};
</script>
<template>
<div>
<runner-type-badge :type="runnerType" size="sm" />
<gl-badge v-if="locked" variant="warning" size="sm">
{{ s__('Runners|locked') }}
</gl-badge>
<gl-badge v-if="paused" variant="danger" size="sm">
{{ s__('Runners|paused') }}
</gl-badge>
<runner-state-locked-badge v-if="locked" size="sm" />
<runner-state-paused-badge v-if="paused" size="sm" />
</div>
</template>
<script>
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
import { I18N_LOCKED_RUNNER_DESCRIPTION } from '../constants';
export default {
components: {
GlBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
},
i18n: {
I18N_LOCKED_RUNNER_DESCRIPTION,
},
};
</script>
<template>
<gl-badge
v-gl-tooltip="$options.i18n.I18N_LOCKED_RUNNER_DESCRIPTION"
variant="warning"
v-bind="$attrs"
>
{{ s__('Runners|locked') }}
</gl-badge>
</template>
<script>
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
import { I18N_PAUSED_RUNNER_DESCRIPTION } from '../constants';
export default {
components: {
GlBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
},
i18n: {
I18N_PAUSED_RUNNER_DESCRIPTION,
},
};
</script>
<template>
<gl-badge
v-gl-tooltip="$options.i18n.I18N_PAUSED_RUNNER_DESCRIPTION"
variant="danger"
v-bind="$attrs"
>
{{ s__('Runners|paused') }}
</gl-badge>
</template>
<script>
import { GlBadge } from '@gitlab/ui';
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
import { s__ } from '~/locale';
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../constants';
import {
INSTANCE_TYPE,
GROUP_TYPE,
PROJECT_TYPE,
I18N_INSTANCE_RUNNER_DESCRIPTION,
I18N_GROUP_RUNNER_DESCRIPTION,
I18N_PROJECT_RUNNER_DESCRIPTION,
} from '../constants';
const BADGE_DATA = {
[INSTANCE_TYPE]: {
variant: 'success',
text: s__('Runners|shared'),
tooltip: I18N_INSTANCE_RUNNER_DESCRIPTION,
},
[GROUP_TYPE]: {
variant: 'success',
text: s__('Runners|group'),
tooltip: I18N_GROUP_RUNNER_DESCRIPTION,
},
[PROJECT_TYPE]: {
variant: 'info',
text: s__('Runners|specific'),
tooltip: I18N_PROJECT_RUNNER_DESCRIPTION,
},
};
......@@ -22,6 +32,9 @@ export default {
components: {
GlBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
type: {
type: String,
......@@ -40,7 +53,7 @@ export default {
};
</script>
<template>
<gl-badge v-if="badge" :variant="badge.variant" v-bind="$attrs">
<gl-badge v-if="badge" v-gl-tooltip="badge.tooltip" :variant="badge.variant" v-bind="$attrs">
{{ badge.text }}
</gl-badge>
</template>
<script>
import { GlBadge } from '@gitlab/ui';
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../constants';
import {
INSTANCE_TYPE,
GROUP_TYPE,
PROJECT_TYPE,
I18N_INSTANCE_RUNNER_DESCRIPTION,
I18N_GROUP_RUNNER_DESCRIPTION,
I18N_PROJECT_RUNNER_DESCRIPTION,
I18N_LOCKED_RUNNER_DESCRIPTION,
I18N_PAUSED_RUNNER_DESCRIPTION,
} from '../constants';
import RunnerTypeBadge from './runner_type_badge.vue';
import RunnerStateLockedBadge from './runner_state_locked_badge.vue';
import RunnerStatePausedBadge from './runner_state_paused_badge.vue';
export default {
components: {
GlBadge,
RunnerTypeBadge,
RunnerStateLockedBadge,
RunnerStatePausedBadge,
},
runnerTypes: {
INSTANCE_TYPE,
GROUP_TYPE,
PROJECT_TYPE,
},
i18n: {
I18N_INSTANCE_RUNNER_DESCRIPTION,
I18N_GROUP_RUNNER_DESCRIPTION,
I18N_PROJECT_RUNNER_DESCRIPTION,
I18N_LOCKED_RUNNER_DESCRIPTION,
I18N_PAUSED_RUNNER_DESCRIPTION,
},
};
</script>
......@@ -32,27 +50,23 @@ export default {
<ul>
<li>
<runner-type-badge :type="$options.runnerTypes.INSTANCE_TYPE" size="sm" />
- {{ __('Runs jobs from all unassigned projects.') }}
- {{ $options.i18n.I18N_INSTANCE_RUNNER_DESCRIPTION }}
</li>
<li>
<runner-type-badge :type="$options.runnerTypes.GROUP_TYPE" size="sm" />
- {{ __('Runs jobs from all unassigned projects in its group.') }}
- {{ $options.i18n.I18N_GROUP_RUNNER_DESCRIPTION }}
</li>
<li>
<runner-type-badge :type="$options.runnerTypes.PROJECT_TYPE" size="sm" />
- {{ __('Runs jobs from assigned projects.') }}
- {{ $options.i18n.I18N_PROJECT_RUNNER_DESCRIPTION }}
</li>
<li>
<gl-badge variant="warning" size="sm">
{{ s__('Runners|locked') }}
</gl-badge>
- {{ __('Cannot be assigned to other projects.') }}
<runner-state-locked-badge size="sm" />
- {{ $options.i18n.I18N_LOCKED_RUNNER_DESCRIPTION }}
</li>
<li>
<gl-badge variant="danger" size="sm">
{{ s__('Runners|paused') }}
</gl-badge>
- {{ __('Not available to run jobs.') }}
<runner-state-paused-badge size="sm" />
- {{ $options.i18n.I18N_PAUSED_RUNNER_DESCRIPTION }}
</li>
</ul>
</div>
......
......@@ -7,6 +7,14 @@ export const GROUP_RUNNER_COUNT_LIMIT = 1000;
export const I18N_FETCH_ERROR = s__('Runners|Something went wrong while fetching runner data.');
export const I18N_DETAILS_TITLE = s__('Runners|Runner #%{runner_id}');
export const I18N_INSTANCE_RUNNER_DESCRIPTION = s__('Runners|Available to all projects');
export const I18N_GROUP_RUNNER_DESCRIPTION = s__(
'Runners|Available to all projects and subgroups in the group',
);
export const I18N_PROJECT_RUNNER_DESCRIPTION = s__('Runners|Associated with one or more projects');
export const I18N_LOCKED_RUNNER_DESCRIPTION = s__('Runners|You cannot assign to other projects');
export const I18N_PAUSED_RUNNER_DESCRIPTION = s__('Runners|Not available to run jobs');
export const RUNNER_TAG_BADGE_VARIANT = 'info';
export const RUNNER_TAG_BG_CLASS = 'gl-bg-blue-100';
......
......@@ -6249,9 +6249,6 @@ msgstr ""
msgid "Cannot assign a confidential epic to a non-confidential issue. Make the issue confidential and try again"
msgstr ""
msgid "Cannot be assigned to other projects."
msgstr ""
msgid "Cannot be merged automatically"
msgstr ""
......@@ -23190,9 +23187,6 @@ msgstr ""
msgid "Not available for protected branches"
msgstr ""
msgid "Not available to run jobs."
msgstr ""
msgid "Not confidential"
msgstr ""
......@@ -29229,6 +29223,15 @@ msgstr ""
msgid "Runners|Are you sure you want to delete this runner?"
msgstr ""
msgid "Runners|Associated with one or more projects"
msgstr ""
msgid "Runners|Available to all projects"
msgstr ""
msgid "Runners|Available to all projects and subgroups in the group"
msgstr ""
msgid "Runners|Can run untagged jobs"
msgstr ""
......@@ -29289,6 +29292,9 @@ msgstr ""
msgid "Runners|New runner, has not connected yet"
msgstr ""
msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Not connected"
msgstr ""
......@@ -29412,6 +29418,9 @@ msgstr ""
msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr ""
msgid "Runners|You cannot assign to other projects"
msgstr ""
msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Runners pipeline minutes."
msgstr ""
......@@ -29442,15 +29451,6 @@ msgstr ""
msgid "Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects."
msgstr ""
msgid "Runs jobs from all unassigned projects in its group."
msgstr ""
msgid "Runs jobs from all unassigned projects."
msgstr ""
msgid "Runs jobs from assigned projects."
msgstr ""
msgid "SAML"
msgstr ""
......
import { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import RunnerStateLockedBadge from '~/runner/components/runner_state_locked_badge.vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
describe('RunnerTypeBadge', () => {
let wrapper;
const findBadge = () => wrapper.findComponent(GlBadge);
const getTooltip = () => getBinding(findBadge().element, 'gl-tooltip');
const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMount(RunnerStateLockedBadge, {
propsData: {
...props,
},
directives: {
GlTooltip: createMockDirective(),
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('renders locked state', () => {
expect(wrapper.text()).toBe('locked');
expect(findBadge().props('variant')).toBe('warning');
});
it('renders tooltip', () => {
expect(getTooltip().value).toBeDefined();
});
it('passes arbitrary attributes to the badge', () => {
createComponent({ props: { size: 'sm' } });
expect(findBadge().props('size')).toBe('sm');
});
});
import { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import RunnerStatePausedBadge from '~/runner/components/runner_state_paused_badge.vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
describe('RunnerTypeBadge', () => {
let wrapper;
const findBadge = () => wrapper.findComponent(GlBadge);
const getTooltip = () => getBinding(findBadge().element, 'gl-tooltip');
const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMount(RunnerStatePausedBadge, {
propsData: {
...props,
},
directives: {
GlTooltip: createMockDirective(),
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('renders paused state', () => {
expect(wrapper.text()).toBe('paused');
expect(findBadge().props('variant')).toBe('danger');
});
it('renders tooltip', () => {
expect(getTooltip().value).toBeDefined();
});
it('passes arbitrary attributes to the badge', () => {
createComponent({ props: { size: 'sm' } });
expect(findBadge().props('size')).toBe('sm');
});
});
import { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import RunnerTypeBadge from '~/runner/components/runner_type_badge.vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '~/runner/constants';
describe('RunnerTypeBadge', () => {
let wrapper;
const findBadge = () => wrapper.findComponent(GlBadge);
const getTooltip = () => getBinding(findBadge().element, 'gl-tooltip');
const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMount(RunnerTypeBadge, {
propsData: {
...props,
},
directives: {
GlTooltip: createMockDirective(),
},
});
};
......@@ -20,16 +25,24 @@ describe('RunnerTypeBadge', () => {
wrapper.destroy();
});
it.each`
describe.each`
type | text | variant
${INSTANCE_TYPE} | ${'shared'} | ${'success'}
${GROUP_TYPE} | ${'group'} | ${'success'}
${PROJECT_TYPE} | ${'specific'} | ${'info'}
`('displays $type runner with as "$text" with a $variant variant ', ({ type, text, variant }) => {
createComponent({ props: { type } });
`('displays $type runner', ({ type, text, variant }) => {
beforeEach(() => {
createComponent({ props: { type } });
});
expect(findBadge().text()).toBe(text);
expect(findBadge().props('variant')).toBe(variant);
it(`as "${text}" with a ${variant} variant`, () => {
expect(findBadge().text()).toBe(text);
expect(findBadge().props('variant')).toBe(variant);
});
it('with a tooltip', () => {
expect(getTooltip().value).toBeDefined();
});
});
it('validation fails for an incorrect type', () => {
......
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