Commit e3280031 authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '346370-update-tooltips-for-runner-statuses' into 'master'

Update tooltips for runner statuses

See merge request gitlab-org/gitlab!83276
parents 011d95ed 125a7c07
...@@ -3,10 +3,11 @@ import { GlBadge, GlTooltipDirective } from '@gitlab/ui'; ...@@ -3,10 +3,11 @@ import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
import { __, s__, sprintf } from '~/locale'; import { __, s__, sprintf } from '~/locale';
import { getTimeago } from '~/lib/utils/datetime_utility'; import { getTimeago } from '~/lib/utils/datetime_utility';
import { import {
I18N_ONLINE_RUNNER_TIMEAGO_DESCRIPTION, I18N_ONLINE_TIMEAGO_TOOLTIP,
I18N_NEVER_CONTACTED_RUNNER_DESCRIPTION, I18N_NEVER_CONTACTED_TOOLTIP,
I18N_OFFLINE_RUNNER_TIMEAGO_DESCRIPTION, I18N_OFFLINE_TIMEAGO_TOOLTIP,
I18N_STALE_RUNNER_DESCRIPTION, I18N_STALE_TIMEAGO_TOOLTIP,
I18N_STALE_NEVER_CONTACTED_TOOLTIP,
STATUS_ONLINE, STATUS_ONLINE,
STATUS_NEVER_CONTACTED, STATUS_NEVER_CONTACTED,
STATUS_OFFLINE, STATUS_OFFLINE,
...@@ -32,7 +33,7 @@ export default { ...@@ -32,7 +33,7 @@ export default {
return getTimeago().format(this.runner.contactedAt); return getTimeago().format(this.runner.contactedAt);
} }
// Prevent "just now" from being rendered, in case data is missing. // Prevent "just now" from being rendered, in case data is missing.
return __('n/a'); return __('never');
}, },
badge() { badge() {
switch (this.runner?.status) { switch (this.runner?.status) {
...@@ -40,35 +41,39 @@ export default { ...@@ -40,35 +41,39 @@ export default {
return { return {
variant: 'success', variant: 'success',
label: s__('Runners|online'), label: s__('Runners|online'),
tooltip: sprintf(I18N_ONLINE_RUNNER_TIMEAGO_DESCRIPTION, { tooltip: this.timeAgoTooltip(I18N_ONLINE_TIMEAGO_TOOLTIP),
timeAgo: this.contactedAtTimeAgo,
}),
}; };
case STATUS_NEVER_CONTACTED: case STATUS_NEVER_CONTACTED:
return { return {
variant: 'muted', variant: 'muted',
label: s__('Runners|never contacted'), label: s__('Runners|never contacted'),
tooltip: I18N_NEVER_CONTACTED_RUNNER_DESCRIPTION, tooltip: I18N_NEVER_CONTACTED_TOOLTIP,
}; };
case STATUS_OFFLINE: case STATUS_OFFLINE:
return { return {
variant: 'muted', variant: 'muted',
label: s__('Runners|offline'), label: s__('Runners|offline'),
tooltip: sprintf(I18N_OFFLINE_RUNNER_TIMEAGO_DESCRIPTION, { tooltip: this.timeAgoTooltip(I18N_OFFLINE_TIMEAGO_TOOLTIP),
timeAgo: this.contactedAtTimeAgo,
}),
}; };
case STATUS_STALE: case STATUS_STALE:
return { return {
variant: 'warning', variant: 'warning',
label: s__('Runners|stale'), label: s__('Runners|stale'),
tooltip: I18N_STALE_RUNNER_DESCRIPTION, // runner may have contacted (or not) and be stale: consider both cases.
tooltip: this.runner.contactedAt
? this.timeAgoTooltip(I18N_STALE_TIMEAGO_TOOLTIP)
: I18N_STALE_NEVER_CONTACTED_TOOLTIP,
}; };
default: default:
return null; return null;
} }
}, },
}, },
methods: {
timeAgoTooltip(text) {
return sprintf(text, { timeAgo: this.contactedAtTimeAgo });
},
},
}; };
</script> </script>
<template> <template>
......
...@@ -21,18 +21,19 @@ export const I18N_GROUP_RUNNER_DESCRIPTION = s__( ...@@ -21,18 +21,19 @@ export const I18N_GROUP_RUNNER_DESCRIPTION = s__(
); );
export const I18N_PROJECT_RUNNER_DESCRIPTION = s__('Runners|Associated with one or more projects'); export const I18N_PROJECT_RUNNER_DESCRIPTION = s__('Runners|Associated with one or more projects');
// Status // Status tooltips
export const I18N_ONLINE_RUNNER_TIMEAGO_DESCRIPTION = s__( export const I18N_ONLINE_TIMEAGO_TOOLTIP = s__(
'Runners|Runner is online; last contact was %{timeAgo}', 'Runners|Runner is online; last contact was %{timeAgo}',
); );
export const I18N_NEVER_CONTACTED_RUNNER_DESCRIPTION = s__( export const I18N_NEVER_CONTACTED_TOOLTIP = s__('Runners|Runner has never contacted this instance');
'Runners|This runner has never contacted this instance', export const I18N_OFFLINE_TIMEAGO_TOOLTIP = s__(
'Runners|Runner is offline; last contact was %{timeAgo}',
); );
export const I18N_OFFLINE_RUNNER_TIMEAGO_DESCRIPTION = s__( export const I18N_STALE_TIMEAGO_TOOLTIP = s__(
'Runners|No recent contact from this runner; last contact was %{timeAgo}', 'Runners|Runner is stale; last contact was %{timeAgo}',
); );
export const I18N_STALE_RUNNER_DESCRIPTION = s__( export const I18N_STALE_NEVER_CONTACTED_TOOLTIP = s__(
'Runners|No contact from this runner in over 3 months', 'Runners|Runner is stale; it has never contacted this instance',
); );
// Actions // Actions
......
...@@ -6,7 +6,7 @@ module Ci ...@@ -6,7 +6,7 @@ module Ci
def runner_status_icon(runner, size: 16, icon_class: '') def runner_status_icon(runner, size: 16, icon_class: '')
status = runner.status status = runner.status
active = runner.active contacted_at = runner.contacted_at
title = '' title = ''
icon = 'warning-solid' icon = 'warning-solid'
...@@ -14,22 +14,20 @@ module Ci ...@@ -14,22 +14,20 @@ module Ci
case status case status
when :online when :online
if active title = s_("Runners|Runner is online; last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(contacted_at) }
title = s_("Runners|Runner is online, last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(runner.contacted_at) } icon = 'status-active'
icon = 'status-active' span_class = 'gl-text-green-500'
span_class = 'gl-text-green-500'
else
title = s_("Runners|Runner is paused, last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(runner.contacted_at) }
icon = 'status-paused'
span_class = 'gl-text-gray-600'
end
when :not_connected, :never_contacted when :not_connected, :never_contacted
title = s_("Runners|New runner, has not contacted yet") title = s_("Runners|Runner has never contacted this instance")
icon = 'warning-solid' icon = 'warning-solid'
when :offline when :offline
title = s_("Runners|Runner is offline, last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(runner.contacted_at) } title = s_("Runners|Runner is offline; last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(contacted_at) }
icon = 'status-failed' icon = 'status-failed'
span_class = 'gl-text-red-500' span_class = 'gl-text-red-500'
when :stale
# runner may have contacted (or not) and be stale: consider both cases.
title = contacted_at ? s_("Runners|Runner is stale; last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(contacted_at) } : s_("Runners|Runner is stale; it has never contacted this instance")
icon = 'warning-solid'
end end
content_tag(:span, class: span_class, title: title, data: { toggle: 'tooltip', container: 'body', testid: 'runner_status_icon', qa_selector: "runner_status_#{status}_content" }) do content_tag(:span, class: span_class, title: title, data: { toggle: 'tooltip', container: 'body', testid: 'runner_status_icon', qa_selector: "runner_status_#{status}_content" }) do
......
...@@ -32144,15 +32144,6 @@ msgstr "" ...@@ -32144,15 +32144,6 @@ msgstr ""
msgid "Runners|New registration token generated!" msgid "Runners|New registration token generated!"
msgstr "" msgstr ""
msgid "Runners|New runner, has not contacted yet"
msgstr ""
msgid "Runners|No contact from this runner in over 3 months"
msgstr ""
msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
msgid "Runners|No spot. Default choice for Windows Shell executor." msgid "Runners|No spot. Default choice for Windows Shell executor."
msgstr "" msgstr ""
...@@ -32237,16 +32228,28 @@ msgstr "" ...@@ -32237,16 +32228,28 @@ msgstr ""
msgid "Runners|Runner cannot be deleted, please contact your administrator" msgid "Runners|Runner cannot be deleted, please contact your administrator"
msgstr "" msgstr ""
msgid "Runners|Runner is offline, last contact was %{runner_contact} ago" msgid "Runners|Runner has never contacted this instance"
msgstr ""
msgid "Runners|Runner is offline; last contact was %{runner_contact} ago"
msgstr ""
msgid "Runners|Runner is offline; last contact was %{timeAgo}"
msgstr "" msgstr ""
msgid "Runners|Runner is online, last contact was %{runner_contact} ago" msgid "Runners|Runner is online; last contact was %{runner_contact} ago"
msgstr "" msgstr ""
msgid "Runners|Runner is online; last contact was %{timeAgo}" msgid "Runners|Runner is online; last contact was %{timeAgo}"
msgstr "" msgstr ""
msgid "Runners|Runner is paused, last contact was %{runner_contact} ago" msgid "Runners|Runner is stale; it has never contacted this instance"
msgstr ""
msgid "Runners|Runner is stale; last contact was %{runner_contact} ago"
msgstr ""
msgid "Runners|Runner is stale; last contact was %{timeAgo}"
msgstr "" msgstr ""
msgid "Runners|Runner registration" msgid "Runners|Runner registration"
...@@ -32300,9 +32303,6 @@ msgstr "" ...@@ -32300,9 +32303,6 @@ msgstr ""
msgid "Runners|The runner will be permanently deleted and no longer available for projects or groups in the instance. Are you sure you want to continue?" msgid "Runners|The runner will be permanently deleted and no longer available for projects or groups in the instance. Are you sure you want to continue?"
msgstr "" msgstr ""
msgid "Runners|This runner has never contacted this instance"
msgstr ""
msgid "Runners|This runner is associated with specific projects." msgid "Runners|This runner is associated with specific projects."
msgstr "" msgstr ""
...@@ -44826,9 +44826,6 @@ msgstr "" ...@@ -44826,9 +44826,6 @@ msgstr ""
msgid "my-channel" msgid "my-channel"
msgstr "" msgstr ""
msgid "n/a"
msgstr ""
msgid "need attention" msgid "need attention"
msgstr "" msgstr ""
......
...@@ -7,6 +7,8 @@ import { ...@@ -7,6 +7,8 @@ import {
STATUS_OFFLINE, STATUS_OFFLINE,
STATUS_STALE, STATUS_STALE,
STATUS_NEVER_CONTACTED, STATUS_NEVER_CONTACTED,
I18N_NEVER_CONTACTED_TOOLTIP,
I18N_STALE_NEVER_CONTACTED_TOOLTIP,
} from '~/runner/constants'; } from '~/runner/constants';
describe('RunnerTypeBadge', () => { describe('RunnerTypeBadge', () => {
...@@ -59,7 +61,7 @@ describe('RunnerTypeBadge', () => { ...@@ -59,7 +61,7 @@ describe('RunnerTypeBadge', () => {
expect(wrapper.text()).toBe('never contacted'); expect(wrapper.text()).toBe('never contacted');
expect(findBadge().props('variant')).toBe('muted'); expect(findBadge().props('variant')).toBe('muted');
expect(getTooltip().value).toMatch('This runner has never contacted'); expect(getTooltip().value).toBe(I18N_NEVER_CONTACTED_TOOLTIP);
}); });
it('renders offline state', () => { it('renders offline state', () => {
...@@ -72,9 +74,7 @@ describe('RunnerTypeBadge', () => { ...@@ -72,9 +74,7 @@ describe('RunnerTypeBadge', () => {
expect(wrapper.text()).toBe('offline'); expect(wrapper.text()).toBe('offline');
expect(findBadge().props('variant')).toBe('muted'); expect(findBadge().props('variant')).toBe('muted');
expect(getTooltip().value).toBe( expect(getTooltip().value).toBe('Runner is offline; last contact was 1 day ago');
'No recent contact from this runner; last contact was 1 day ago',
);
}); });
it('renders stale state', () => { it('renders stale state', () => {
...@@ -87,7 +87,20 @@ describe('RunnerTypeBadge', () => { ...@@ -87,7 +87,20 @@ describe('RunnerTypeBadge', () => {
expect(wrapper.text()).toBe('stale'); expect(wrapper.text()).toBe('stale');
expect(findBadge().props('variant')).toBe('warning'); expect(findBadge().props('variant')).toBe('warning');
expect(getTooltip().value).toBe('No contact from this runner in over 3 months'); expect(getTooltip().value).toBe('Runner is stale; last contact was 1 year ago');
});
it('renders stale state with no contact time', () => {
createComponent({
runner: {
contactedAt: null,
status: STATUS_STALE,
},
});
expect(wrapper.text()).toBe('stale');
expect(findBadge().props('variant')).toBe('warning');
expect(getTooltip().value).toBe(I18N_STALE_NEVER_CONTACTED_TOOLTIP);
}); });
describe('does not fail when data is missing', () => { describe('does not fail when data is missing', () => {
...@@ -100,7 +113,7 @@ describe('RunnerTypeBadge', () => { ...@@ -100,7 +113,7 @@ describe('RunnerTypeBadge', () => {
}); });
expect(wrapper.text()).toBe('online'); expect(wrapper.text()).toBe('online');
expect(getTooltip().value).toBe('Runner is online; last contact was n/a'); expect(getTooltip().value).toBe('Runner is online; last contact was never');
}); });
it('status is missing', () => { it('status is missing', () => {
......
...@@ -10,24 +10,31 @@ RSpec.describe Ci::RunnersHelper do ...@@ -10,24 +10,31 @@ RSpec.describe Ci::RunnersHelper do
end end
describe '#runner_status_icon', :clean_gitlab_redis_cache do describe '#runner_status_icon', :clean_gitlab_redis_cache do
it "returns - not contacted yet" do it "returns online text" do
runner = create(:ci_runner, contacted_at: 1.second.ago)
expect(helper.runner_status_icon(runner)).to include("is online")
end
it "returns never contacted" do
runner = create(:ci_runner) runner = create(:ci_runner)
expect(helper.runner_status_icon(runner)).to include("not contacted yet") expect(helper.runner_status_icon(runner)).to include("never contacted")
end end
it "returns offline text" do it "returns offline text" do
runner = create(:ci_runner, contacted_at: 1.day.ago, active: true) runner = create(:ci_runner, contacted_at: 1.day.ago)
expect(helper.runner_status_icon(runner)).to include("Runner is offline") expect(helper.runner_status_icon(runner)).to include("is offline")
end end
it "returns online text" do it "returns stale text" do
runner = create(:ci_runner, contacted_at: 1.second.ago, active: true) runner = create(:ci_runner, created_at: 4.months.ago, contacted_at: 4.months.ago)
expect(helper.runner_status_icon(runner)).to include("Runner is online") expect(helper.runner_status_icon(runner)).to include("is stale")
expect(helper.runner_status_icon(runner)).to include("last contact was")
end end
it "returns paused text" do it "returns stale text, when runner never contacted" do
runner = create(:ci_runner, contacted_at: 1.second.ago, active: false) runner = create(:ci_runner, created_at: 4.months.ago)
expect(helper.runner_status_icon(runner)).to include("Runner is paused") expect(helper.runner_status_icon(runner)).to include("is stale")
expect(helper.runner_status_icon(runner)).to include("never contacted")
end end
end end
......
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