summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/attention_requests/components/navigation_popover.vue
blob: 804eda8f321b13553d6e9e7ace101c0f642e4c92 (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
119
120
121
122
<script>
import { GlPopover, GlSprintf, GlButton, GlLink, GlIcon } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import { helpPagePath } from '~/helpers/help_page_helper';
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';

export default {
  components: {
    GlPopover,
    GlSprintf,
    GlButton,
    GlLink,
    GlIcon,
    UserCalloutDismisser,
  },
  inject: {
    message: {
      default: '',
    },
    observerElSelector: {
      default: '',
    },
    observerElToggledClass: {
      default: '',
    },
    featureName: {
      default: '',
    },
    popoverTarget: {
      default: '',
    },
    showAttentionIcon: {
      default: false,
    },
    delay: {
      default: 0,
    },
    popoverCssClass: {
      default: '',
    },
  },
  data() {
    return {
      showPopover: false,
      popoverPlacement: this.popoverPosition(),
    };
  },
  mounted() {
    this.observeEl = document.querySelector(this.observerElSelector);
    this.observer = new MutationObserver(this.callback);
    this.observer.observe(this.observeEl, {
      attributes: true,
    });
    this.callback();

    window.addEventListener('resize', () => {
      this.popoverPlacement = this.popoverPosition();
    });
  },
  beforeDestroy() {
    this.observer.disconnect();
  },
  methods: {
    callback() {
      if (this.showPopover) {
        this.$root.$emit('bv::hide::popover');
      }

      setTimeout(() => this.toggleShowPopover(), this.delay);
    },
    toggleShowPopover() {
      this.showPopover = this.observeEl.classList.contains(this.observerElToggledClass);
    },
    getPopoverTarget() {
      return document.querySelector(this.popoverTarget);
    },
    popoverPosition() {
      if (bp.isDesktop()) {
        return 'left';
      }

      return 'bottom';
    },
  },
  docsPage: helpPagePath('user/project/merge_requests/index.md', {
    anchor: 'request-attention-to-a-merge-request',
  }),
};
</script>

<template>
  <user-callout-dismisser :feature-name="featureName">
    <template #default="{ shouldShowCallout, dismiss }">
      <gl-popover
        v-if="shouldShowCallout"
        :show-close-button="false"
        :target="() => getPopoverTarget()"
        :show="showPopover"
        :delay="0"
        triggers="manual"
        :placement="popoverPlacement"
        boundary="window"
        no-fade
        :css-classes="[popoverCssClass]"
      >
        <p v-for="(m, index) in message" :key="index" class="gl-mb-5">
          <gl-sprintf :message="m">
            <template #strong="{ content }">
              <strong><gl-icon v-if="showAttentionIcon" name="attention" /> {{ content }}</strong>
            </template>
          </gl-sprintf>
        </p>
        <div class="gl-display-flex gl-align-items-center">
          <gl-button size="small" variant="confirm" class="gl-mr-5" @click.prevent.stop="dismiss">
            {{ __('Got it!') }}
          </gl-button>
          <gl-link :href="$options.docsPage" target="_blank">{{ __('Learn more') }}</gl-link>
        </div>
      </gl-popover>
    </template>
  </user-callout-dismisser>
</template>