Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ReportCardSection.vue 1.66 KiB
<template>
  <div
    :id="sectionDescription.id"
    ref="sectionContainer"
    class="report-card-section"
  >
    <v-row>
      <v-col cols="12">
        <a
          :href="`#${sectionDescription.id}`"
          class="d-flex section-title-link"
          @mouseover="showLinkIcon = true"
          @mouseout="showLinkIcon = false"
        >
          <h2 class="primary--text">{{ sectionDescription.title }}</h2>
          <v-icon v-show="showLinkIcon">mdi-link</v-icon>
        </a>
      </v-col>
    </v-row>

    <v-row>
      <v-col cols="12">
        <component :is="sectionDescription.component"></component>
      </v-col>
    </v-row>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  props: {
    sectionDescription: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {
      showLinkIcon: false,
      ignoreFirstIntersection: true,
    }
  },
  computed: mapState({
    activeSection: (state) => state.reportCard.activeSection,
  }),
  mounted() {
    const callback = (entries, observer) => {
      const sectionIndex = this.sectionDescription.index

      if (entries[0].isIntersecting) {
        this.$store.dispatch('reportCard/setActiveSection', sectionIndex)
      }
    }
    const options = {
      threshold: 0.5,
    }

    const observer = new IntersectionObserver(callback, options)
    observer.observe(this.$refs.sectionContainer)
  },
}
</script>

<style lang="scss">
.report-card-section {
  .section-title-link {
    text-decoration: none;
  }
  &::before {
    display: block;
    content: ' ';
    margin-top: -68px;
    height: 68px;
    visibility: hidden;
    pointer-events: none;
  }
}
</style>