Commit 7bd6df0e authored by Tim Zallmann's avatar Tim Zallmann

Merge branch 'alexives/35913/update_ui_remove_pause_button' into 'master'

Change replication status button to indicator with tooltip

Closes #223905

See merge request gitlab-org/gitlab!34571
parents 51b9f0ae 6b86d2e5
...@@ -36,15 +36,6 @@ export default { ...@@ -36,15 +36,6 @@ export default {
}, },
}, },
computed: { computed: {
isToggleAllowed() {
return !this.node.primary && this.nodeEditAllowed;
},
nodeToggleLabel() {
return this.node.enabled ? __('Pause replication') : __('Resume replication');
},
nodeToggleIcon() {
return this.node.enabled ? 'pause' : 'play';
},
isSecondaryNode() { isSecondaryNode() {
return !this.node.primary; return !this.node.primary;
}, },
...@@ -113,18 +104,6 @@ export default { ...@@ -113,18 +104,6 @@ export default {
> >
{{ s__('Repair authentication') }} {{ s__('Repair authentication') }}
</gl-deprecated-button> </gl-deprecated-button>
<gl-deprecated-button
v-if="isToggleAllowed"
:class="{
'btn-warning': node.enabled,
'btn-success': !node.enabled,
}"
class="btn btn-sm mx-1 sm-column-spacing"
@click="onToggleNode"
>
<icon :name="nodeToggleIcon" />
{{ nodeToggleLabel }}
</gl-deprecated-button>
<a v-if="nodeEditAllowed" :href="node.editPath" class="btn btn-sm mx-1 sm-column-spacing"> <a v-if="nodeEditAllowed" :href="node.editPath" class="btn btn-sm mx-1 sm-column-spacing">
{{ __('Edit') }} {{ __('Edit') }}
</a> </a>
......
<script>
import { GlPopover, GlLink, GlIcon } from '@gitlab/ui';
import { __ } from '~/locale';
import {
REPLICATION_STATUS_CLASS,
REPLICATION_STATUS_ICON,
REPLICATION_PAUSE_URL,
} from '../constants';
export default {
components: {
GlIcon,
GlPopover,
GlLink,
},
props: {
node: {
type: Object,
required: true,
},
},
computed: {
replicationStatusCssClass() {
return this.node.enabled
? REPLICATION_STATUS_CLASS.enabled
: REPLICATION_STATUS_CLASS.disabled;
},
nodeReplicationStatusIcon() {
return this.node.enabled ? REPLICATION_STATUS_ICON.enabled : REPLICATION_STATUS_ICON.disabled;
},
nodeReplicationStatusText() {
return this.node.enabled ? __('Replication enabled') : __('Replication paused');
},
},
REPLICATION_PAUSE_URL,
};
</script>
<template>
<div class="mt-2 detail-section-item">
<div class="gl-text-gray-700 node-detail-title">{{ s__('GeoNodes|Replication status') }}</div>
<div class="gl-display-flex gl-align-items-center">
<div
:class="replicationStatusCssClass"
class="rounded-pill gl-display-inline-flex gl-align-items-center px-2 gl-py-2 gl-my-2"
>
<gl-icon :name="nodeReplicationStatusIcon" />
<strong class="status-text gl-ml-2"> {{ nodeReplicationStatusText }} </strong>
</div>
<gl-icon
ref="replicationStatusHelp"
tabindex="0"
name="question"
class="gl-text-blue-600 gl-ml-2 gl-cursor-pointer"
/>
<gl-popover
:target="() => $refs.replicationStatusHelp.$el"
placement="top"
triggers="hover focus"
>
<p>{{ __('Geo nodes are paused using a command run on the node') }}</p>
<gl-link
class="gl-mt-5 gl-font-sm"
:href="$options.REPLICATION_PAUSE_URL"
target="_blank"
>{{ __('More Information') }}</gl-link
>
</gl-popover>
</div>
</div>
</template>
...@@ -3,6 +3,7 @@ import { GlLink, GlIcon } from '@gitlab/ui'; ...@@ -3,6 +3,7 @@ import { GlLink, GlIcon } from '@gitlab/ui';
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
import GeoNodeHealthStatus from '../geo_node_health_status.vue'; import GeoNodeHealthStatus from '../geo_node_health_status.vue';
import GeoNodeReplicationStatus from '../geo_node_replication_status.vue';
import GeoNodeActions from '../geo_node_actions.vue'; import GeoNodeActions from '../geo_node_actions.vue';
export default { export default {
...@@ -11,6 +12,7 @@ export default { ...@@ -11,6 +12,7 @@ export default {
GlIcon, GlIcon,
GeoNodeHealthStatus, GeoNodeHealthStatus,
GeoNodeActions, GeoNodeActions,
GeoNodeReplicationStatus,
}, },
props: { props: {
node: { node: {
...@@ -107,6 +109,9 @@ export default { ...@@ -107,6 +109,9 @@ export default {
:status="nodeHealthStatus" :status="nodeHealthStatus"
:status-check-timestamp="nodeDetails.statusCheckTimestamp" :status-check-timestamp="nodeDetails.statusCheckTimestamp"
/> />
<div v-if="!node.primary">
<geo-node-replication-status :node="node" />
</div>
</div> </div>
</div> </div>
</template> </template>
...@@ -31,6 +31,16 @@ export const HEALTH_STATUS_CLASS = { ...@@ -31,6 +31,16 @@ export const HEALTH_STATUS_CLASS = {
offline: 'text-secondary-800 bg-secondary-100', offline: 'text-secondary-800 bg-secondary-100',
}; };
export const REPLICATION_STATUS_CLASS = {
enabled: 'gl-text-green-600 gl-bg-green-100',
disabled: 'gl-text-orange-600 gl-bg-orange-100',
};
export const REPLICATION_STATUS_ICON = {
enabled: 'play',
disabled: 'pause',
};
export const TIME_DIFF = { export const TIME_DIFF = {
FIVE_MINS: 300, FIVE_MINS: 300,
HOUR: 3600, HOUR: 3600,
...@@ -44,6 +54,9 @@ export const HELP_INFO_URL = ...@@ -44,6 +54,9 @@ export const HELP_INFO_URL =
export const REPLICATION_HELP_URL = export const REPLICATION_HELP_URL =
'https://docs.gitlab.com/ee/administration/geo/replication/datatypes.html#limitations-on-replicationverification'; 'https://docs.gitlab.com/ee/administration/geo/replication/datatypes.html#limitations-on-replicationverification';
export const REPLICATION_PAUSE_URL =
'https://docs.gitlab.com/ee/administration/geo/replication/#pausing-and-resuming-replication';
export const HELP_NODE_HEALTH_URL = export const HELP_NODE_HEALTH_URL =
'https://docs.gitlab.com/ee/administration/geo/replication/troubleshooting.html#check-the-health-of-the-secondary-node'; 'https://docs.gitlab.com/ee/administration/geo/replication/troubleshooting.html#check-the-health-of-the-secondary-node';
......
---
title: Update node ui to have status indicator instead of button for replication
merge_request: 34571
author:
type: added
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`GeoNodeReplicationStatusComponent computed properties renders Icon correctly 1`] = `"<gl-icon-stub name=\\"play\\" size=\\"16\\"></gl-icon-stub>"`;
exports[`GeoNodeReplicationStatusComponent computed properties renders Icon correctly 2`] = `"<gl-icon-stub name=\\"pause\\" size=\\"16\\"></gl-icon-stub>"`;
exports[`GeoNodeReplicationStatusComponent computed properties renders StatusPill correctly 1`] = `
"<div class=\\"rounded-pill gl-display-inline-flex gl-align-items-center px-2 gl-py-2 gl-my-2 gl-text-green-600 gl-bg-green-100\\">
<gl-icon-stub name=\\"play\\" size=\\"16\\"></gl-icon-stub> <strong class=\\"status-text gl-ml-2\\"> Replication enabled </strong>
</div>"
`;
exports[`GeoNodeReplicationStatusComponent computed properties renders StatusPill correctly 2`] = `
"<div class=\\"rounded-pill gl-display-inline-flex gl-align-items-center px-2 gl-py-2 gl-my-2 gl-text-orange-600 gl-bg-orange-100\\">
<gl-icon-stub name=\\"pause\\" size=\\"16\\"></gl-icon-stub> <strong class=\\"status-text gl-ml-2\\"> Replication paused </strong>
</div>"
`;
...@@ -38,36 +38,6 @@ describe('GeoNodeActionsComponent', () => { ...@@ -38,36 +38,6 @@ describe('GeoNodeActionsComponent', () => {
}); });
describe('computed', () => { describe('computed', () => {
describe('isToggleAllowed', () => {
it('returns boolean value representing if toggle on node can be allowed', () => {
let vmX = createComponent(mockNodes[0], true, false);
expect(vmX.isToggleAllowed).toBeFalsy();
vmX.$destroy();
vmX = createComponent(mockNodes[1]);
expect(vmX.isToggleAllowed).toBeTruthy();
vmX.$destroy();
});
});
describe('nodeToggleLabel', () => {
it('returns label for toggle button for a node', () => {
let mockNode = { ...mockNodes[1] };
let vmX = createComponent(mockNode);
expect(vmX.nodeToggleLabel).toBe('Pause replication');
vmX.$destroy();
mockNode = { ...mockNodes[1], enabled: false };
vmX = createComponent(mockNode);
expect(vmX.nodeToggleLabel).toBe('Resume replication');
vmX.$destroy();
});
});
describe('disabledRemovalTooltip', () => { describe('disabledRemovalTooltip', () => {
describe.each` describe.each`
nodeRemovalAllowed | tooltip nodeRemovalAllowed | tooltip
...@@ -87,20 +57,6 @@ describe('GeoNodeActionsComponent', () => { ...@@ -87,20 +57,6 @@ describe('GeoNodeActionsComponent', () => {
}); });
describe('methods', () => { describe('methods', () => {
describe('onToggleNode', () => {
it('emits showNodeActionModal with actionType `toggle`, node reference, modalMessage, modalActionLabel, and modalTitle', () => {
vm.onToggleNode();
expect(eventHub.$emit).toHaveBeenCalledWith('showNodeActionModal', {
actionType: NODE_ACTIONS.TOGGLE,
node: vm.node,
modalMessage: 'Pausing replication stops the sync process. Are you sure?',
modalActionLabel: vm.nodeToggleLabel,
modalTitle: 'Pause replication',
});
});
});
describe('onRemovePrimaryNode', () => { describe('onRemovePrimaryNode', () => {
it('emits showNodeActionModal with actionType `remove`, node reference, modalKind, modalMessage, modalActionLabel, and modalTitle', () => { it('emits showNodeActionModal with actionType `remove`, node reference, modalKind, modalMessage, modalActionLabel, and modalTitle', () => {
vm.onRemovePrimaryNode(); vm.onRemovePrimaryNode();
......
import { shallowMount } from '@vue/test-utils';
import { GlIcon, GlPopover, GlLink } from '@gitlab/ui';
import geoNodeReplicationStatusComponent from 'ee/geo_nodes/components/geo_node_replication_status.vue';
import {
REPLICATION_STATUS_CLASS,
REPLICATION_STATUS_ICON,
REPLICATION_PAUSE_URL,
} from 'ee/geo_nodes/constants';
import { mockNode } from '../mock_data';
describe('GeoNodeReplicationStatusComponent', () => {
let wrapper;
const defaultProps = {
node: mockNode,
};
const createComponent = (props = {}) => {
wrapper = shallowMount(geoNodeReplicationStatusComponent, {
propsData: {
...defaultProps,
...props,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findStatusPill = () => wrapper.find('.rounded-pill');
const findStatusIcon = () => findStatusPill().find(GlIcon);
const findStatusText = () => findStatusPill().find('.status-text');
const findHelpIcon = () => wrapper.find({ ref: 'replicationStatusHelp' });
const findGlPopover = () => wrapper.find(GlPopover);
const findPopoverText = () => findGlPopover().find('p');
const findPopoverLink = () => findGlPopover().find(GlLink);
describe.each`
enabled | replicationStatusCssClass | nodeReplicationStatusIcon | nodeReplicationStatusText
${true} | ${REPLICATION_STATUS_CLASS.enabled} | ${REPLICATION_STATUS_ICON.enabled} | ${'Replication enabled'}
${false} | ${REPLICATION_STATUS_CLASS.disabled} | ${REPLICATION_STATUS_ICON.disabled} | ${'Replication paused'}
`(
`computed properties`,
({
enabled,
replicationStatusCssClass,
nodeReplicationStatusIcon,
nodeReplicationStatusText,
}) => {
beforeEach(() => {
createComponent({
node: { ...defaultProps.node, enabled },
});
});
it(`sets background of StatusPill to ${replicationStatusCssClass} when enabled is ${enabled}`, () => {
expect(
findStatusPill()
.classes()
.join(' '),
).toContain(replicationStatusCssClass);
});
it('renders StatusPill correctly', () => {
expect(findStatusPill().html()).toMatchSnapshot();
});
it(`sets StatusIcon to ${nodeReplicationStatusIcon} when enabled is ${enabled}`, () => {
expect(findStatusIcon().attributes('name')).toBe(nodeReplicationStatusIcon);
});
it('renders Icon correctly', () => {
expect(findStatusIcon().html()).toMatchSnapshot();
});
it(`sets replication status text to ${nodeReplicationStatusText} when enabled is ${enabled}`, () => {
expect(findStatusText().text()).toBe(nodeReplicationStatusText);
});
},
);
describe('Helper Popover', () => {
beforeEach(() => {
createComponent();
});
it('always renders the help icon', () => {
expect(findHelpIcon().exists()).toBeTruthy();
});
it('sets to question icon', () => {
expect(findHelpIcon().attributes('name')).toBe('question');
});
it('renders popover always', () => {
expect(findGlPopover().exists()).toBeTruthy();
});
it('always renders popover text', () => {
expect(findPopoverText().exists()).toBeTruthy();
});
it('should display hint about pausing replication', () => {
expect(findPopoverText().text()).toBe('Geo nodes are paused using a command run on the node');
});
it('renders popover link always', () => {
expect(findPopoverLink().exists()).toBeTruthy();
});
it('link should be to HELP_NODE_HEALTH_URL', () => {
expect(findPopoverLink().attributes('href')).toBe(REPLICATION_PAUSE_URL);
});
});
});
...@@ -10295,6 +10295,9 @@ msgstr "" ...@@ -10295,6 +10295,9 @@ msgstr ""
msgid "Geo allows you to replicate your GitLab instance to other geographical locations." msgid "Geo allows you to replicate your GitLab instance to other geographical locations."
msgstr "" msgstr ""
msgid "Geo nodes are paused using a command run on the node"
msgstr ""
msgid "GeoNodeStatusEvent|%{timeAgoStr} (%{pendingEvents} events)" msgid "GeoNodeStatusEvent|%{timeAgoStr} (%{pendingEvents} events)"
msgstr "" msgstr ""
...@@ -10400,6 +10403,9 @@ msgstr "" ...@@ -10400,6 +10403,9 @@ msgstr ""
msgid "GeoNodes|Replication slots" msgid "GeoNodes|Replication slots"
msgstr "" msgstr ""
msgid "GeoNodes|Replication status"
msgstr ""
msgid "GeoNodes|Repositories" msgid "GeoNodes|Repositories"
msgstr "" msgstr ""
...@@ -19049,6 +19055,12 @@ msgstr "" ...@@ -19049,6 +19055,12 @@ msgstr ""
msgid "Replication" msgid "Replication"
msgstr "" msgstr ""
msgid "Replication enabled"
msgstr ""
msgid "Replication paused"
msgstr ""
msgid "Reply by email" msgid "Reply by email"
msgstr "" msgstr ""
...@@ -19424,9 +19436,6 @@ msgstr "" ...@@ -19424,9 +19436,6 @@ msgstr ""
msgid "Resume" msgid "Resume"
msgstr "" msgstr ""
msgid "Resume replication"
msgstr ""
msgid "Resync" msgid "Resync"
msgstr "" msgstr ""
......
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