Commit 627da134 authored by Zack Cuddy's avatar Zack Cuddy Committed by Kushal Pandya

Geo Node Status 2.0 - Node Header

This change adds the header info
with placeholder for its details
for the Geo nodes.

This header is also collapsable and
will collapse the full node
details in a future MR.
parent 8e7780e2
<script>
import { s__ } from '~/locale';
import GeoNodeHeader from './header/geo_node_header.vue';
export default {
name: 'GeoNodes',
components: {
GeoNodeHeader,
},
props: {
node: {
type: Object,
required: true,
validator: (value) =>
['id', 'name', 'geoNodeId', 'url', 'healthStatus'].every((prop) => value[prop]),
},
},
data() {
return {
collapsed: false,
};
},
computed: {
siteTitle() {
return this.node.primary ? s__('Geo|Primary site') : s__('Geo|Secondary site');
},
},
methods: {
toggleCollapse() {
this.collapsed = !this.collapsed;
},
},
};
</script>
<template>
<div>
<h4 class="gl-font-lg gl-my-5">{{ siteTitle }}</h4>
<geo-node-header :node="node" :collapsed="collapsed" @collapse="toggleCollapse" />
<p v-if="!collapsed">{{ s__('Geo|Node Details') }}</p>
</div>
</template>
<script>
import { GlButton, GlBadge } from '@gitlab/ui';
export default {
name: 'GeoNodeHeader',
components: {
GlButton,
GlBadge,
},
props: {
node: {
type: Object,
required: true,
},
collapsed: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
chevronIcon() {
return this.collapsed ? 'chevron-right' : 'chevron-down';
},
},
};
</script>
<template>
<div
class="gl-display-grid geo-node-header-grid-columns gl-bg-gray-10 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100 gl-border-t-1 gl-border-t-solid gl-border-t-gray-100 gl-py-3 gl-px-5"
>
<div class="gl-display-flex gl-align-items-center">
<gl-button
class="gl-mr-3 gl-p-0!"
category="tertiary"
variant="confirm"
:icon="chevronIcon"
@click="$emit('collapse')"
/>
<div
class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-md-align-items-center gl-flex-fill-1"
>
<div class="gl-display-flex gl-align-items-center gl-flex-fill-1">
<gl-badge v-if="node.current" variant="info" class="gl-mr-2">{{
__('Current')
}}</gl-badge>
<h4 class="gl-font-lg">{{ node.name }}</h4>
</div>
<div class="gl-display-flex gl-align-items-center gl-flex-fill-2">
<span>{{ s__('Geo|Health Status') }}</span>
<span class="gl-ml-2">{{ __('Last Updated') }}</span>
</div>
</div>
</div>
<div class="gl-display-flex gl-align-items-center gl-justify-content-end">
<span>{{ __('Actions') }}</span>
</div>
</div>
</template>
......@@ -28,3 +28,12 @@
}
}
}
.geo-node-header-grid-columns {
grid-template-columns: 1fr auto;
grid-gap: 1rem;
@include media-breakpoint-up(md) {
grid-template-columns: 3fr 1fr;
}
}
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import GeoNodes from 'ee/geo_nodes_beta/components/geo_nodes.vue';
import GeoNodeHeader from 'ee/geo_nodes_beta/components/header/geo_node_header.vue';
import { MOCK_PRIMARY_VERSION, MOCK_REPLICABLE_TYPES, MOCK_NODES } from '../mock_data';
const localVue = createLocalVue();
......@@ -40,6 +41,8 @@ describe('GeoNodes', () => {
const findGeoNodesContainer = () => wrapper.find('div');
const findGeoSiteTitle = () => wrapper.find('h4');
const findGeoNodeHeader = () => wrapper.find(GeoNodeHeader);
const findGeoNodeDetails = () => wrapper.find('p');
describe('template', () => {
beforeEach(() => {
......@@ -49,6 +52,24 @@ describe('GeoNodes', () => {
it('renders the Geo Nodes Container always', () => {
expect(findGeoNodesContainer().exists()).toBe(true);
});
it('renders the Geo Node Header always', () => {
expect(findGeoNodeHeader().exists()).toBe(true);
});
describe('Node Details', () => {
it('renders by default', () => {
expect(findGeoNodeDetails().exists()).toBe(true);
});
it('is hidden when toggled', () => {
findGeoNodeHeader().vm.$emit('collapse');
return wrapper.vm.$nextTick(() => {
expect(findGeoNodeDetails().exists()).toBe(false);
});
});
});
});
describe.each`
......
import { GlButton, GlBadge } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import GeoNodeHeader from 'ee/geo_nodes_beta/components/header/geo_node_header.vue';
import {
MOCK_PRIMARY_VERSION,
MOCK_REPLICABLE_TYPES,
MOCK_NODES,
} from 'ee_jest/geo_nodes_beta/mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('GeoNodeHeader', () => {
let wrapper;
const defaultProps = {
node: MOCK_NODES[0],
collapsed: false,
};
const createComponent = (initialState, props) => {
const store = new Vuex.Store({
state: {
primaryVersion: MOCK_PRIMARY_VERSION.version,
primaryRevision: MOCK_PRIMARY_VERSION.revision,
replicableTypes: MOCK_REPLICABLE_TYPES,
...initialState,
},
});
wrapper = shallowMount(GeoNodeHeader, {
localVue,
store,
propsData: {
...defaultProps,
...props,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findHeaderCollapseButton = () => wrapper.find(GlButton);
const findCurrentNodeBadge = () => wrapper.find(GlBadge);
describe('template', () => {
describe('always', () => {
beforeEach(() => {
createComponent();
});
});
describe('Header Collapse Icon', () => {
describe('when not collapsed', () => {
beforeEach(() => {
createComponent();
});
it('renders the chevron-down icon', () => {
expect(findHeaderCollapseButton().attributes('icon')).toBe('chevron-down');
});
});
describe('when collapsed', () => {
beforeEach(() => {
createComponent(null, { collapsed: true });
});
it('renders the chevron-right icon', () => {
expect(findHeaderCollapseButton().attributes('icon')).toBe('chevron-right');
});
});
describe('on click', () => {
beforeEach(() => {
createComponent();
findHeaderCollapseButton().vm.$emit('click');
});
it('emits the collapse event', () => {
expect(wrapper.emitted('collapse')).toHaveLength(1);
});
});
});
describe('Current Node Badge', () => {
describe('when current node is true', () => {
beforeEach(() => {
createComponent();
});
it('renders', () => {
expect(findCurrentNodeBadge().exists()).toBe(true);
});
});
describe('when current node is false', () => {
beforeEach(() => {
createComponent(null, { node: MOCK_NODES[1] });
});
it('does not render', () => {
expect(findCurrentNodeBadge().exists()).toBe(false);
});
});
});
});
});
......@@ -13648,6 +13648,9 @@ msgstr ""
msgid "Geo|Go to the primary site"
msgstr ""
msgid "Geo|Health Status"
msgstr ""
msgid "Geo|If you want to make changes, you must visit the primary site."
msgstr ""
......@@ -13681,6 +13684,9 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
msgid "Geo|Node Details"
msgstr ""
msgid "Geo|Node name can't be blank"
msgstr ""
......@@ -17565,6 +17571,9 @@ msgstr ""
msgid "Last Seen"
msgstr ""
msgid "Last Updated"
msgstr ""
msgid "Last Used"
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