Welcome to mirror list, hosted at ThFree Co, Russian Federation.

markdown_drawer.vue « markdown_drawer « components « vue_shared « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 379f22fdc6fade25f81d46f81789180379650a01 (plain)
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
<script>
import { GlDrawer, GlAlert, GlSkeletonLoader } from '@gitlab/ui';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { s__ } from '~/locale';
import { contentTop } from '~/lib/utils/common_utils';
import { renderGFM } from '~/behaviors/markdown/render_gfm';
import { getRenderedMarkdown } from './utils/fetch';

export const cache = {};

export default {
  name: 'MarkdownDrawer',
  components: {
    GlDrawer,
    GlAlert,
    GlSkeletonLoader,
  },
  directives: {
    SafeHtml,
  },
  i18n: {
    alert: s__('MardownDrawer|Could not fetch help contents.'),
  },
  props: {
    documentPath: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      loading: false,
      hasFetchError: false,
      title: '',
      body: null,
      open: false,
      drawerTop: '0px',
    };
  },
  watch: {
    documentPath: {
      immediate: true,
      handler: 'fetchMarkdown',
    },
    open(open) {
      if (open && this.body) {
        this.renderGLFM();
      }
    },
  },
  methods: {
    async fetchMarkdown() {
      const cached = cache[this.documentPath];
      this.hasFetchError = false;
      this.title = '';
      if (cached) {
        this.title = cached.title;
        this.body = cached.body;
        if (this.open) {
          this.renderGLFM();
        }
      } else {
        this.loading = true;
        const { body, title, hasFetchError } = await getRenderedMarkdown(this.documentPath);
        this.title = title;
        this.body = body;
        this.loading = false;
        this.hasFetchError = hasFetchError;
        if (this.open) {
          this.renderGLFM();
        }
        cache[this.documentPath] = { title, body };
      }
    },
    getDrawerTop() {
      this.drawerTop = `${contentTop()}px`;
    },
    renderGLFM() {
      this.$nextTick(() => {
        renderGFM(this.$refs['content-element']);
      });
    },
    closeDrawer() {
      this.open = false;
    },
    toggleDrawer() {
      this.getDrawerTop();
      this.open = !this.open;
    },
    openDrawer() {
      this.getDrawerTop();
      this.open = true;
    },
  },
  safeHtmlConfig: {
    ADD_TAGS: ['copy-code'],
  },
};
</script>
<template>
  <gl-drawer :header-height="drawerTop" :open="open" header-sticky @close="closeDrawer">
    <template #title>
      <h4 data-testid="title-element" class="gl-m-0">{{ title }}</h4>
    </template>
    <template #default>
      <div v-if="hasFetchError">
        <gl-alert :dismissible="false" variant="danger">{{ $options.i18n.alert }}</gl-alert>
      </div>
      <gl-skeleton-loader v-else-if="loading" />
      <div
        v-else
        ref="content-element"
        v-safe-html:[$options.safeHtmlConfig]="body"
        class="md"
      ></div>
    </template>
  </gl-drawer>
</template>