Geo Primary Verification Details: Checksum Info

Why are we doing this work

This work will be behind feature flag geo_primary_verification_view

This work is focused on taking the UI started in Geo Primary Verification Details: Init Vue App (#538191 - closed) and creating a UI experience based on the data returned from Geo Primary Verification Details: Hookup API to UI (#538199 - closed)

This UI will be similar to the Geo Replicables Details. This issue focused on the Checksum information.

Relevant links

Implementation plan

  1. Create data_management_item_checksum_info.vue
Expand for proposed component
<script>
import { GlSprintf, GlBadge, GlCard } from '@gitlab/ui';
import { VERIFICATION_STATUS_STATES } from 'ee/geo_shared/constants';
import { __, s__ } from '~/locale';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';

export default {
  components: {
    GlSprintf,
    GlBadge,
    GlCard,
    TimeAgo,
    ClipboardButton,
  },
  props: {
    modelDetails: {
      type: Object,
      required: true,
    },
  },
  i18n: {
    copy: __('Copy'),
    checksumInformation: s__('Geo|Checksum information'),
    checksum: s__('Geo|Checksum: %{checksum}'),
    expectedChecksum: s__('Geo|Expected checksum: %{checksum}'),
    lastChecksumAt: s__('Geo|Last checksum: %{timeAgo}'),
    checksumStartedAt: s__('Geo|Checksum started: %{timeAgo}'),
    statusBadge: s__('Geo|Status: %{badge}'),
    checksumRetryAt: s__(
      'Geo|%{noBoldStart}Next checksum retry:%{noBoldEnd} Retry #%{retryCount} scheduled %{timeAgo}',
    ),
    geoFailure: s__('Geo|Error: %{message}'),
    unknown: __('Unknown'),
  },
  computed: {
    checksumStatus() {
      return (
        VERIFICATION_STATUS_STATES[this.modelDetails?.checksumState] ||
        VERIFICATION_STATUS_STATES.UNKNOWN
      );
    },
    showChecksumStartedAt() {
      return [
        VERIFICATION_STATUS_STATES.PENDING.value,
        VERIFICATION_STATUS_STATES.STARTED.value,
      ].includes(this.modelDetails?.checksumState);
    },
    checksumFailure() {
      return this.modelDetails?.checksumState === VERIFICATION_STATUS_STATES.FAILED.value;
    },
  },
};
</script>

<template>
  <gl-card>
    <template #header>
      <h5 class="gl-my-0">{{ $options.i18n.checksumInformation }}</h5>
    </template>

    <div class="gl-flex gl-flex-col gl-gap-4">
      <p class="gl-mb-0">
        <gl-sprintf :message="$options.i18n.statusBadge">
          <template #badge>
            <gl-badge :variant="checksumStatus.variant">{{
              checksumStatus.title
            }}</gl-badge>
          </template>
        </gl-sprintf>
      </p>

      <template v-if="checksumFailure">
        <p class="gl-mb-0">
          <gl-sprintf :message="$options.i18n.geoFailure">
            <template #message>
              <span class="gl-font-bold gl-text-red-700">{{
                modelDetails.checksumFailure || $options.i18n.unknown
              }}</span>
            </template>
          </gl-sprintf>
        </p>

        <p class="gl-mb-0 gl-font-bold">
          <gl-sprintf :message="$options.i18n.checksumRetryAt">
            <template #noBold="{ content }">
              <span class="gl-font-normal">{{ content }}</span>
            </template>
            <template #retryCount>
              <span>{{ modelDetails.checksumRetryCount }}</span>
            </template>
            <template #timeAgo>
              <time-ago
                :time="modelDetails.checksumRetryAt"
                data-testid="checksum-retry-at-time-ago"
              />
            </template>
          </gl-sprintf>
        </p>
      </template>

      <p v-if="showChecksumStartedAt" class="gl-mb-0">
        <gl-sprintf :message="$options.i18n.checksumStartedAt">
          <template #timeAgo>
            <time-ago
              :time="modelDetails.checksumStartedAt"
              class="gl-font-bold"
              data-testid="checksum-started-at-time-ago"
            />
          </template>
        </gl-sprintf>
      </p>

      <p class="gl-mb-0">
        <gl-sprintf :message="$options.i18n.lastChecksumAt">
          <template #timeAgo>
            <time-ago
              :time="modelDetails.verifiedAt"
              class="gl-font-bold"
              data-testid="last-verified-at-time-ago"
            />
          </template>
        </gl-sprintf>
      </p>

      <p class="gl-mb-0" data-testid="local-checksum">
        <gl-sprintf :message="$options.i18n.checksum">
          <template #checksum>
            <span class="gl-font-bold">{{
              modelDetails.checksum || $options.i18n.unknown
            }}</span>
          </template>
        </gl-sprintf>
        <clipboard-button
          v-if="modelDetails.checksum"
          :title="$options.i18n.copy"
          :text="modelDetails.checksum"
          size="small"
          category="tertiary"
        />
      </p>

      <p
        v-if="modelDetails.checksumMismatch"
        class="gl-mb-0"
        data-testid="expected-checksum"
      >
        <gl-sprintf :message="$options.i18n.expectedChecksum">
          <template #checksum>
            <span class="gl-font-bold gl-text-red-700">{{
              modelDetails.checksumMismatch || $options.i18n.unknown
            }}</span>
          </template>
        </gl-sprintf>
        <clipboard-button
          v-if="modelDetails.checksumMismatch"
          :title="$options.i18n.copy"
          :text="modelDetails.checksumMismatch"
          size="small"
          category="tertiary"
        />
      </p>
    </div>
  </gl-card>
</template>
  1. Add the data-management-item-checksum-info.vue component to the app.vue
<template>
  <div class="gl-flex gl-flex-col-reverse gl-gap-4 md:gl-grid md:gl-grid-cols-2">
    <data-management-item-checksum-info :model-details="modelDetails" />
  </div>
</template>
Edited by 🤖 GitLab Bot 🤖