File size: 3,603 Bytes
da96562
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
124
125
126
127
128
129
130
<!--
  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="{ card: true, 'card-with-image': !!this.imageUrl }" ref="root">
    <div class="card-content">
      <h2
        v-if="contentTitle && !actualFeature && !helpUrl && !actualHelpText && !editUrl"
        class="card-title"
      >{{ decode(contentTitle) }}</h2>
      <h2
        v-if="contentTitle && (actualFeature || helpUrl || actualHelpText || editUrl)"
        class="card-title"
      >
        <EnrichedHeadline
          :feature-name="actualFeature"
          :help-url="helpUrl"
          :edit-url="editUrl"
          :inline-help="actualHelpText"
        >
          {{ decode(contentTitle) }}
        </EnrichedHeadline>
      </h2>
      <div ref="content">
        <slot />
      </div>
    </div>
    <div class="card-image hide-on-med-and-down" v-if="imageUrl">
      <img :src="imageUrl" :alt="actualImageAltText" />
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import EnrichedHeadline from '../EnrichedHeadline/EnrichedHeadline.vue';
import Matomo from '../Matomo/Matomo';

let adminContent: HTMLElement|null = null;

const { $ } = window;

export default defineComponent({
  props: {
    contentTitle: String,
    feature: String,
    helpUrl: String,
    editUrl: String,
    helpText: String,
    anchor: String,
    imageUrl: String,
    imageAltText: String,
  },
  components: {
    EnrichedHeadline,
  },
  data() {
    return {
      actualFeature: this.feature,
      actualHelpText: this.helpText,
      actualImageAltText: this.imageAltText ? this.imageAltText : this.contentTitle,
    };
  },
  watch: {
    feature(newValue: string) {
      this.actualFeature = newValue;
    },
    helpText(newValue: string) {
      this.actualHelpText = newValue;
    },
  },
  mounted() {
    const root = this.$refs.root as HTMLElement;
    const content = this.$refs.content as HTMLElement;

    if (this.anchor && root && root.parentElement) {
      const anchorElement = document.createElement('a');
      anchorElement.id = this.anchor;
      $(root.parentElement).prepend(anchorElement);
    }

    setTimeout(() => {
      const inlineHelp = content.querySelector('.contentHelp');
      if (inlineHelp) {
        this.actualHelpText = inlineHelp.innerHTML;
        inlineHelp.remove();
      }
    }, 0);

    if (this.actualFeature && this.actualFeature === 'true') {
      this.actualFeature = this.contentTitle;
    }

    if (adminContent === null) {
      // cache admin node for further content blocks
      adminContent = document.querySelector('#content.admin');
    }

    let contentTopPosition: number|null = null;
    if (adminContent) {
      contentTopPosition = adminContent.offsetTop;
    }

    if (contentTopPosition || contentTopPosition === 0) {
      const parents = root.closest('.widgetLoader') as HTMLElement;

      // when shown within the widget loader, we need to get the offset of that element
      // as the widget loader might be still shown. Would otherwise not position correctly
      // the widgets on the admin home page
      const topThis = parents ? parents.offsetTop : root.offsetTop;

      if (topThis - contentTopPosition < 17) {
        // we make sure to display the first card with no margin-top to have it on same as line as
        // navigation
        root.style.marginTop = '0';
      }
    }
  },
  methods: {
    decode(s: string) {
      return Matomo.helper.htmlDecode(s);
    },
  },
});
</script>