Commit d8361303 authored by Kushal Pandya's avatar Kushal Pandya

GeoNodeDetails Component

parent 80ab0c8c
<script>
import { s__, __ } from '~/locale';
import { parseSeconds, stringifyTime } from '~/lib/utils/pretty_time';
import { bytesToMiB } from '~/lib/utils/number_utils';
import icon from '~/vue_shared/components/icon.vue';
import { VALUE_TYPE, CUSTOM_TYPE } from '../constants';
import geoNodeDetailItem from './geo_node_detail_item.vue';
export default {
props: {
node: {
type: Object,
required: true,
},
nodeDetails: {
type: Object,
required: true,
},
},
data() {
return {
showAdvanceItems: false,
errorMessage: '',
nodeDetailItems: [
{
itemTitle: s__('GeoNodes|Storage config:'),
itemValue: this.storageShardsStatus(),
itemValueType: VALUE_TYPE.PLAIN,
cssClass: this.plainValueCssClass(!this.nodeDetails.storageShardsMatch),
},
{
itemTitle: s__('GeoNodes|Health status:'),
itemValue: this.nodeHealthStatus(),
itemValueType: VALUE_TYPE.CUSTOM,
customType: CUSTOM_TYPE.STATUS,
},
{
itemTitle: s__('GeoNodes|Repositories:'),
itemValue: this.nodeDetails.repositories,
itemValueType: VALUE_TYPE.GRAPH,
},
{
itemTitle: s__('GeoNodes|Wikis:'),
itemValue: this.nodeDetails.wikis,
itemValueType: VALUE_TYPE.GRAPH,
},
{
itemTitle: s__('GeoNodes|LFS objects:'),
itemValue: this.nodeDetails.lfs,
itemValueType: VALUE_TYPE.GRAPH,
},
{
itemTitle: s__('GeoNodes|Attachments:'),
itemValue: this.nodeDetails.attachments,
itemValueType: VALUE_TYPE.GRAPH,
},
{
itemTitle: s__('GeoNodes|Sync settings:'),
itemValue: this.syncSettings(),
itemValueType: VALUE_TYPE.CUSTOM,
customType: CUSTOM_TYPE.SYNC,
},
],
};
},
components: {
icon,
geoNodeDetailItem,
},
computed: {
hasError() {
if (!this.nodeDetails.healthy) {
this.errorMessage = this.nodeDetails.health;
}
return !this.nodeDetails.healthy;
},
hasVersionMismatch() {
if (this.nodeDetails.version !== this.nodeDetails.primaryVersion ||
this.nodeDetails.revision !== this.nodeDetails.primaryRevision) {
this.errorMessage = s__('GeoNodes|GitLab version does not match the primary node version');
return true;
}
return false;
},
versionCssClass() {
return this.plainValueCssClass(this.hasVersionMismatch);
},
advanceButtonIcon() {
return this.showAdvanceItems ? 'angle-up' : 'angle-down';
},
nodeVersion() {
return `${this.nodeDetails.version} (${this.nodeDetails.revision})`;
},
replicationSlotWAL() {
return `${bytesToMiB(this.nodeDetails.replicationSlotWAL)} MB`;
},
dbReplicationLag() {
// Replication lag can be nil if the secondary isn't actually streaming
if (this.nodeDetails.dbReplicationLag !== null &&
this.nodeDetails.dbReplicationLag >= 0) {
const parsedTime = parseSeconds(this.nodeDetails.dbReplicationLag, {
hoursPerDay: 24,
daysPerWeek: 7,
});
return stringifyTime(parsedTime);
}
return 'Unknown';
},
lastEventStatus() {
return {
eventId: this.nodeDetails.lastEvent.id,
eventTimeStamp: this.nodeDetails.lastEvent.timeStamp,
};
},
cursorLastEventStatus() {
return {
eventId: this.nodeDetails.cursorLastEvent.id,
eventTimeStamp: this.nodeDetails.cursorLastEvent.timeStamp,
};
},
valueType() {
return VALUE_TYPE;
},
customType() {
return CUSTOM_TYPE;
},
},
methods: {
nodeHealthStatus() {
return this.nodeDetails.healthy ? this.nodeDetails.health : this.nodeDetails.healthStatus;
},
storageShardsStatus() {
if (this.nodeDetails.storageShardsMatch === null) {
return __('Unknown');
}
return this.nodeDetails.storageShardsMatch ? __('OK') : s__('GeoNodes|Does not match the primary storage configuration');
},
plainValueCssClass(value) {
const cssClass = 'node-detail-value-bold';
return value ? `${cssClass} node-detail-value-error` : cssClass;
},
syncSettings() {
return {
namespaces: this.nodeDetails.namespaces,
lastEvent: this.nodeDetails.lastEvent,
cursorLastEvent: this.nodeDetails.cursorLastEvent,
};
},
onClickShowAdvance() {
this.showAdvanceItems = !this.showAdvanceItems;
},
},
};
</script>
<template>
<div class="row">
<ul class="col-md-8 list-unstyled node-details-list">
<geo-node-detail-item
:item-title="s__('GeoNodes|GitLab version:')"
:css-class="versionCssClass"
:item-value="nodeVersion"
:item-value-type="valueType.PLAIN"
/>
<template v-if="!node.primary">
<geo-node-detail-item
v-for="(nodeDetailItem, index) in nodeDetailItems"
:key="index"
:css-class="nodeDetailItem.cssClass"
:item-title="nodeDetailItem.itemTitle"
:item-value="nodeDetailItem.itemValue"
:item-value-type="nodeDetailItem.itemValueType"
:custom-type="nodeDetailItem.customType"
/>
</template>
<li class="prepend-top-5 node-detail-item">
<button
class="btn-link btn-show-advanced"
type="button"
@click="onClickShowAdvance"
>
<span>{{__('Advanced')}}</span>
<icon
:size=12
:name="advanceButtonIcon"
/>
</button>
</li>
<template v-if="showAdvanceItems">
<template v-if="node.primary">
<geo-node-detail-item
:item-title="s__('GeoNodes|Replication slots:')"
:success-label="s__('GeoNodes|Used slots')"
:neutral-label="s__('GeoNodes|Unused slots')"
:item-value="nodeDetails.replicationSlots"
:item-value-type="valueType.GRAPH"
/>
<geo-node-detail-item
v-if="nodeDetails.replicationSlots.totalCount"
css-class="node-detail-value-bold"
:item-title="s__('GeoNodes|Replication slot WAL:')"
:item-value="replicationSlotWAL"
:item-value-type="valueType.PLAIN"
/>
</template>
<template v-else>
<geo-node-detail-item
css-class="node-detail-value-bold"
:item-title="s__('GeoNodes|Database replication lag:')"
:item-value="dbReplicationLag"
:item-value-type="valueType.PLAIN"
/>
<geo-node-detail-item
:item-title="s__('GeoNodes|Last event ID seen from primary:')"
:item-value="lastEventStatus"
:item-value-type="valueType.CUSTOM"
:custom-type="customType.EVENT"
/>
<geo-node-detail-item
:item-title="s__('GeoNodes|Last event ID processed by cursor:')"
:item-value="cursorLastEventStatus"
:item-value-type="valueType.CUSTOM"
:custom-type="customType.EVENT"
/>
</template>
</template>
</ul>
<div
v-if="hasError || hasVersionMismatch"
class="col-md-12 prepend-top-10"
>
<p class="health-message">
{{errorMessage}}
</p>
</div>
</div>
</template>
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