Commit 6b86d2e5 authored by Alex Ives's avatar Alex Ives

Change replication status button to indicator

- Added componenet for replication status
- Add replication status component to node status widget
- Update translations

Relates to https://gitlab.com/gitlab-org/gitlab/issues/35913
parent 16c9f534
......@@ -36,15 +36,6 @@ export default {
},
},
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() {
return !this.node.primary;
},
......@@ -113,18 +104,6 @@ export default {
>
{{ s__('Repair authentication') }}
</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">
{{ __('Edit') }}
</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';
import { __, sprintf } from '~/locale';
import GeoNodeHealthStatus from '../geo_node_health_status.vue';
import GeoNodeReplicationStatus from '../geo_node_replication_status.vue';
import GeoNodeActions from '../geo_node_actions.vue';
export default {
......@@ -11,6 +12,7 @@ export default {
GlIcon,
GeoNodeHealthStatus,
GeoNodeActions,
GeoNodeReplicationStatus,
},
props: {
node: {
......@@ -107,6 +109,9 @@ export default {
:status="nodeHealthStatus"
:status-check-timestamp="nodeDetails.statusCheckTimestamp"
/>
<div v-if="!node.primary">
<geo-node-replication-status :node="node" />
</div>
</div>
</div>
</template>
......@@ -31,6 +31,16 @@ export const HEALTH_STATUS_CLASS = {
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 = {
FIVE_MINS: 300,
HOUR: 3600,
......@@ -44,6 +54,9 @@ export const HELP_INFO_URL =
export const REPLICATION_HELP_URL =
'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 =
'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', () => {
});
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.each`
nodeRemovalAllowed | tooltip
......@@ -87,20 +57,6 @@ describe('GeoNodeActionsComponent', () => {
});
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', () => {
it('emits showNodeActionModal with actionType `remove`, node reference, modalKind, modalMessage, modalActionLabel, and modalTitle', () => {
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);
});
});
});
......@@ -10136,6 +10136,9 @@ msgstr ""
msgid "Geo allows you to replicate your GitLab instance to other geographical locations."
msgstr ""
msgid "Geo nodes are paused using a command run on the node"
msgstr ""
msgid "GeoNodeStatusEvent|%{timeAgoStr} (%{pendingEvents} events)"
msgstr ""
......@@ -10241,6 +10244,9 @@ msgstr ""
msgid "GeoNodes|Replication slots"
msgstr ""
msgid "GeoNodes|Replication status"
msgstr ""
msgid "GeoNodes|Repositories"
msgstr ""
......@@ -18677,6 +18683,12 @@ msgstr ""
msgid "Replication"
msgstr ""
msgid "Replication enabled"
msgstr ""
msgid "Replication paused"
msgstr ""
msgid "Reply by email"
msgstr ""
......@@ -19043,9 +19055,6 @@ msgstr ""
msgid "Resume"
msgstr ""
msgid "Resume replication"
msgstr ""
msgid "Resync"
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