All files / ee/app/assets/javascripts/geo_nodes/components/details/secondary_node geo_node_secondary_other_info.vue

100% Statements 16/16
100% Branches 12/12
100% Functions 7/7
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123  4x 4x 4x 4x                                                         15x 9x     6x         15x 5x         5x     10x       15x       15x     15x     15x           67x                                                                                                      
<script>
import { GlCard, GlSprintf } from '@gitlab/ui';
import { parseSeconds, stringifyTime } from '~/lib/utils/datetime_utility';
import { __, s__ } from '~/locale';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
 
export default {
  name: 'GeoNodeSecondaryOtherInfo',
  i18n: {
    otherInfo: __('Other information'),
    dbReplicationLag: s__('Geo|Data replication lag'),
    lastEventId: s__('Geo|Last event ID from primary'),
    lastEventTime: s__('Geo|(%{timeAgo})'),
    lastCursorEventId: s__('Geo|Last event ID processed by cursor'),
    storageConfig: s__('Geo|Storage config'),
    shardsNotMatched: s__('Geo|Does not match the primary storage configuration'),
    unknown: __('Unknown'),
    ok: __('OK'),
  },
  classTimestamp: 'gl-text-gray-500 gl-font-sm gl-font-weight-normal',
  components: {
    GlCard,
    GlSprintf,
    TimeAgo,
  },
  props: {
    node: {
      type: Object,
      required: true,
    },
  },
  computed: {
    storageShardsStatus() {
      if (this.node.storageShardsMatch == null) {
        return this.$options.i18n.unknown;
      }
 
      return this.node.storageShardsMatch
        ? this.$options.i18n.ok
        : this.$options.i18n.shardsNotMatched;
    },
    dbReplicationLag() {
      if (parseInt(this.node.dbReplicationLagSeconds, 10) >= 0) {
        const parsedTime = parseSeconds(this.node.dbReplicationLagSeconds, {
          hoursPerDay: 24,
          daysPerWeek: 7,
        });
 
        return stringifyTime(parsedTime);
      }
 
      return this.$options.i18n.unknown;
    },
    lastEventTimestamp() {
      // Converting timestamp to ms
      return this.node.lastEventTimestamp * 1000;
    },
    lastCursorEventTimestamp() {
      // Converting timestamp to ms
      return this.node.cursorLastEventTimestamp * 1000;
    },
    hasEventInfo() {
      return this.node.lastEventId || this.lastEventTimestamp;
    },
    hasCursorEventInfo() {
      return this.node.cursorLastEventId || this.lastCursorEventTimestamp;
    },
  },
};
</script>
 
<template>
  <gl-card>
    <template #header>
      <h5 class="gl-my-3">{{ $options.i18n.otherInfo }}</h5>
    </template>
    <div class="gl-display-flex gl-flex-direction-column gl-mb-5">
      <span>{{ $options.i18n.dbReplicationLag }}</span>
      <span class="gl-font-weight-bold gl-mt-2" data-testid="replication-lag">{{
        dbReplicationLag
      }}</span>
    </div>
    <div class="gl-display-flex gl-flex-direction-column gl-mb-5">
      <span>{{ $options.i18n.lastEventId }}</span>
      <div class="gl-font-weight-bold gl-mt-2" data-testid="last-event">
        <template v-if="hasEventInfo">
          <span v-if="node.lastEventId">{{ node.lastEventId }}</span>
          <span v-if="lastEventTimestamp" :class="$options.classTimestamp">
            <gl-sprintf :message="$options.i18n.lastEventTime">
              <template #timeAgo>
                <time-ago :time="lastEventTimestamp" />
              </template>
            </gl-sprintf>
          </span>
        </template>
        <span v-else>{{ $options.i18n.unknown }}</span>
      </div>
    </div>
    <div class="gl-display-flex gl-flex-direction-column gl-mb-5">
      <span>{{ $options.i18n.lastCursorEventId }}</span>
      <div class="gl-font-weight-bold gl-mt-2" data-testid="last-cursor-event">
        <template v-if="hasCursorEventInfo">
          <span v-if="node.cursorLastEventId">{{ node.cursorLastEventId }}</span>
          <span v-if="lastCursorEventTimestamp" :class="$options.classTimestamp">
            <gl-sprintf :message="$options.i18n.lastEventTime">
              <template #timeAgo>
                <time-ago :time="lastCursorEventTimestamp" />
              </template>
            </gl-sprintf>
          </span>
        </template>
        <span v-else>{{ $options.i18n.unknown }}</span>
      </div>
    </div>
    <div class="gl-display-flex gl-flex-direction-column gl-mb-5">
      <span>{{ $options.i18n.storageConfig }}</span>
      <span class="gl-font-weight-bold gl-mt-2" data-testid="storage-shards">{{
        storageShardsStatus
      }}</span>
    </div>
  </gl-card>
</template>