File size: 3,618 Bytes
76a7a50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
<!--
  Matomo - free/libre analytics platform

  @link    https://matomo.org
  @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-->

<template>
  <div class="noComparison">
    <MetricValue
      :title="title"
      :value="primaryValue"
      :secondary-value="secondaryValue"
      :secondary-label="secondaryLabel"
      :documentation="documentation"
    >
      <template
        v-if="sparkline.evolution"
        #evolution
      >
        <EvolutionBadge
          :percent="sparkline.evolution.percent"
          :trend="sparkline.evolution.trend"
          :is-lower-value-better="sparkline.evolution.isLowerValueBetter"
          :tooltip="sparkline.evolution.tooltip || ''"
        />
      </template>
    </MetricValue>
    <div class="sparklineSlot">
      <Sparkline :width="380" :height="40"
        :params="sparkline.url"
        :series-indices="sparkline.seriesIndices"
      />
    </div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType } from 'vue';
import { Sparkline, NumberFormatter } from 'CoreHome';
import MetricValue from '../MetricValue/MetricValue.vue';
import EvolutionBadge from '../EvolutionBadge/EvolutionBadge.vue';
import { SparklineEntry, SparklineMetric } from './types';

/**
 * No-comparison body for a sparkline card. Composes the MetricValue + EvolutionBadge
 * atoms and the reused Sparkline. In no-comparison mode the metrics live under the ''
 * group key: the first is the primary value, an optional second is the "unique" line.
 */
export default defineComponent({
  name: 'NoComparison',
  components: {
    MetricValue,
    EvolutionBadge,
    Sparkline,
  },
  props: {
    sparkline: {
      type: Object as PropType<SparklineEntry>,
      required: true,
    },
    // Backend map of metric column -> documentation string (from Sparklines.php).
    allMetricsDocumentation: {
      type: Object as PropType<Record<string, string>>,
      default: () => ({}),
    },
  },
  setup(props) {
    const primaryMetric = computed<SparklineMetric | undefined>(
      () => props.sparkline.metrics?.['']?.[0],
    );

    // Optional secondary metric (eg "9,527 unique"), shown only when the report adds a
    // second metric to the same sparkline. MetricValue hides the line when it is absent.
    const secondaryMetric = computed<SparklineMetric | undefined>(
      () => props.sparkline.metrics?.['']?.[1],
    );

    // Prefer the metric's column name (eg "Bounce Rate"), falling back to the label.
    const title = computed(
      () => primaryMetric.value?.title || primaryMetric.value?.description || '',
    );

    // Documentation for the primary metric, looked up by its column. Empty for sparklines added
    // without a column (column === '') or metrics with no registered documentation.
    const documentation = computed(
      () => props.allMetricsDocumentation[primaryMetric.value?.column ?? ''] || undefined,
    );

    // Format raw numbers (plain metrics) but leave already-formatted strings (eg "50%") untouched.
    const formatValue = (
      value?: string | number,
    ): string | number | undefined => (
      typeof value === 'number' ? NumberFormatter.formatNumber(value, 2) : value
    );
    const primaryValue = computed(() => formatValue(primaryMetric.value?.value) ?? '');
    const secondaryValue = computed(() => formatValue(secondaryMetric.value?.value));
    const secondaryLabel = computed(() => secondaryMetric.value?.description);

    return {
      title,
      documentation,
      primaryValue,
      secondaryValue,
      secondaryLabel,
    };
  },
});
</script>