Commit aaf83607 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'mrincon-add-tooltips-to-badges' into 'master'

Add tooltips to runners badges

See merge request gitlab-org/gitlab!71404
parents c5d581ea 7e0ab139
<script> <script>
import { GlBadge } from '@gitlab/ui'; import { GlTooltipDirective } from '@gitlab/ui';
import RunnerTypeBadge from '../runner_type_badge.vue'; 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 { export default {
components: { components: {
GlBadge,
RunnerTypeBadge, RunnerTypeBadge,
RunnerStateLockedBadge,
RunnerStatePausedBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
}, },
props: { props: {
runner: { runner: {
...@@ -24,19 +31,17 @@ export default { ...@@ -24,19 +31,17 @@ export default {
return !this.runner.active; return !this.runner.active;
}, },
}, },
i18n: {
I18N_LOCKED_RUNNER_DESCRIPTION,
I18N_PAUSED_RUNNER_DESCRIPTION,
},
}; };
</script> </script>
<template> <template>
<div> <div>
<runner-type-badge :type="runnerType" size="sm" /> <runner-type-badge :type="runnerType" size="sm" />
<runner-state-locked-badge v-if="locked" size="sm" />
<gl-badge v-if="locked" variant="warning" size="sm"> <runner-state-paused-badge v-if="paused" size="sm" />
{{ s__('Runners|locked') }}
</gl-badge>
<gl-badge v-if="paused" variant="danger" size="sm">
{{ s__('Runners|paused') }}
</gl-badge>
</div> </div>
</template> </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> <script>
import { GlBadge } from '@gitlab/ui'; import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
import { s__ } from '~/locale'; 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 = { const BADGE_DATA = {
[INSTANCE_TYPE]: { [INSTANCE_TYPE]: {
variant: 'success', variant: 'success',
text: s__('Runners|shared'), text: s__('Runners|shared'),
tooltip: I18N_INSTANCE_RUNNER_DESCRIPTION,
}, },
[GROUP_TYPE]: { [GROUP_TYPE]: {
variant: 'success', variant: 'success',
text: s__('Runners|group'), text: s__('Runners|group'),
tooltip: I18N_GROUP_RUNNER_DESCRIPTION,
}, },
[PROJECT_TYPE]: { [PROJECT_TYPE]: {
variant: 'info', variant: 'info',
text: s__('Runners|specific'), text: s__('Runners|specific'),
tooltip: I18N_PROJECT_RUNNER_DESCRIPTION,
}, },
}; };
...@@ -22,6 +32,9 @@ export default { ...@@ -22,6 +32,9 @@ export default {
components: { components: {
GlBadge, GlBadge,
}, },
directives: {
GlTooltip: GlTooltipDirective,
},
props: { props: {
type: { type: {
type: String, type: String,
...@@ -40,7 +53,7 @@ export default { ...@@ -40,7 +53,7 @@ export default {
}; };
</script> </script>
<template> <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 }} {{ badge.text }}
</gl-badge> </gl-badge>
</template> </template>
<script> <script>
import { GlBadge } from '@gitlab/ui'; import {
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../constants'; 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 RunnerTypeBadge from './runner_type_badge.vue';
import RunnerStateLockedBadge from './runner_state_locked_badge.vue';
import RunnerStatePausedBadge from './runner_state_paused_badge.vue';
export default { export default {
components: { components: {
GlBadge,
RunnerTypeBadge, RunnerTypeBadge,
RunnerStateLockedBadge,
RunnerStatePausedBadge,
}, },
runnerTypes: { runnerTypes: {
INSTANCE_TYPE, INSTANCE_TYPE,
GROUP_TYPE, GROUP_TYPE,
PROJECT_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> </script>
...@@ -32,27 +50,23 @@ export default { ...@@ -32,27 +50,23 @@ export default {
<ul> <ul>
<li> <li>
<runner-type-badge :type="$options.runnerTypes.INSTANCE_TYPE" size="sm" /> <runner-type-badge :type="$options.runnerTypes.INSTANCE_TYPE" size="sm" />
- {{ __('Runs jobs from all unassigned projects.') }} - {{ $options.i18n.I18N_INSTANCE_RUNNER_DESCRIPTION }}
</li> </li>
<li> <li>
<runner-type-badge :type="$options.runnerTypes.GROUP_TYPE" size="sm" /> <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>
<li> <li>
<runner-type-badge :type="$options.runnerTypes.PROJECT_TYPE" size="sm" /> <runner-type-badge :type="$options.runnerTypes.PROJECT_TYPE" size="sm" />
- {{ __('Runs jobs from assigned projects.') }} - {{ $options.i18n.I18N_PROJECT_RUNNER_DESCRIPTION }}
</li> </li>
<li> <li>
<gl-badge variant="warning" size="sm"> <runner-state-locked-badge size="sm" />
{{ s__('Runners|locked') }} - {{ $options.i18n.I18N_LOCKED_RUNNER_DESCRIPTION }}
</gl-badge>
- {{ __('Cannot be assigned to other projects.') }}
</li> </li>
<li> <li>
<gl-badge variant="danger" size="sm"> <runner-state-paused-badge size="sm" />
{{ s__('Runners|paused') }} - {{ $options.i18n.I18N_PAUSED_RUNNER_DESCRIPTION }}
</gl-badge>
- {{ __('Not available to run jobs.') }}
</li> </li>
</ul> </ul>
</div> </div>
......
...@@ -7,6 +7,14 @@ export const GROUP_RUNNER_COUNT_LIMIT = 1000; ...@@ -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_FETCH_ERROR = s__('Runners|Something went wrong while fetching runner data.');
export const I18N_DETAILS_TITLE = s__('Runners|Runner #%{runner_id}'); 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_BADGE_VARIANT = 'info';
export const RUNNER_TAG_BG_CLASS = 'gl-bg-blue-100'; export const RUNNER_TAG_BG_CLASS = 'gl-bg-blue-100';
......
...@@ -6252,9 +6252,6 @@ msgstr "" ...@@ -6252,9 +6252,6 @@ msgstr ""
msgid "Cannot assign a confidential epic to a non-confidential issue. Make the issue confidential and try again" msgid "Cannot assign a confidential epic to a non-confidential issue. Make the issue confidential and try again"
msgstr "" msgstr ""
msgid "Cannot be assigned to other projects."
msgstr ""
msgid "Cannot be merged automatically" msgid "Cannot be merged automatically"
msgstr "" msgstr ""
...@@ -23169,9 +23166,6 @@ msgstr "" ...@@ -23169,9 +23166,6 @@ msgstr ""
msgid "Not available for protected branches" msgid "Not available for protected branches"
msgstr "" msgstr ""
msgid "Not available to run jobs."
msgstr ""
msgid "Not confidential" msgid "Not confidential"
msgstr "" msgstr ""
...@@ -29214,6 +29208,15 @@ msgstr "" ...@@ -29214,6 +29208,15 @@ msgstr ""
msgid "Runners|Are you sure you want to delete this runner?" msgid "Runners|Are you sure you want to delete this runner?"
msgstr "" 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" msgid "Runners|Can run untagged jobs"
msgstr "" msgstr ""
...@@ -29274,6 +29277,9 @@ msgstr "" ...@@ -29274,6 +29277,9 @@ msgstr ""
msgid "Runners|New runner, has not connected yet" msgid "Runners|New runner, has not connected yet"
msgstr "" msgstr ""
msgid "Runners|Not available to run jobs"
msgstr ""
msgid "Runners|Not connected" msgid "Runners|Not connected"
msgstr "" msgstr ""
...@@ -29397,6 +29403,9 @@ msgstr "" ...@@ -29397,6 +29403,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." msgid "Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner."
msgstr "" 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." msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Runners pipeline minutes."
msgstr "" msgstr ""
...@@ -29427,15 +29436,6 @@ msgstr "" ...@@ -29427,15 +29436,6 @@ msgstr ""
msgid "Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects." msgid "Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects."
msgstr "" 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" msgid "SAML"
msgstr "" 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 { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import RunnerTypeBadge from '~/runner/components/runner_type_badge.vue'; 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'; import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '~/runner/constants';
describe('RunnerTypeBadge', () => { describe('RunnerTypeBadge', () => {
let wrapper; let wrapper;
const findBadge = () => wrapper.findComponent(GlBadge); const findBadge = () => wrapper.findComponent(GlBadge);
const getTooltip = () => getBinding(findBadge().element, 'gl-tooltip');
const createComponent = ({ props = {} } = {}) => { const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMount(RunnerTypeBadge, { wrapper = shallowMount(RunnerTypeBadge, {
propsData: { propsData: {
...props, ...props,
}, },
directives: {
GlTooltip: createMockDirective(),
},
}); });
}; };
...@@ -20,18 +25,26 @@ describe('RunnerTypeBadge', () => { ...@@ -20,18 +25,26 @@ describe('RunnerTypeBadge', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it.each` describe.each`
type | text | variant type | text | variant
${INSTANCE_TYPE} | ${'shared'} | ${'success'} ${INSTANCE_TYPE} | ${'shared'} | ${'success'}
${GROUP_TYPE} | ${'group'} | ${'success'} ${GROUP_TYPE} | ${'group'} | ${'success'}
${PROJECT_TYPE} | ${'specific'} | ${'info'} ${PROJECT_TYPE} | ${'specific'} | ${'info'}
`('displays $type runner with as "$text" with a $variant variant ', ({ type, text, variant }) => { `('displays $type runner', ({ type, text, variant }) => {
beforeEach(() => {
createComponent({ props: { type } }); createComponent({ props: { type } });
});
it(`as "${text}" with a ${variant} variant`, () => {
expect(findBadge().text()).toBe(text); expect(findBadge().text()).toBe(text);
expect(findBadge().props('variant')).toBe(variant); expect(findBadge().props('variant')).toBe(variant);
}); });
it('with a tooltip', () => {
expect(getTooltip().value).toBeDefined();
});
});
it('validation fails for an incorrect type', () => { it('validation fails for an incorrect type', () => {
expect(() => { expect(() => {
createComponent({ props: { type: 'AN_UNKNOWN_VALUE' } }); createComponent({ props: { type: 'AN_UNKNOWN_VALUE' } });
......
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