gitlab-org--gitlab-foss/app/assets/javascripts/terms/components/app.vue

117 lines
3.6 KiB
Vue

<script>
import $ from 'jquery';
import { GlButton, GlIntersectionObserver, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
import { FLASH_TYPES, FLASH_CLOSED_EVENT } from '~/flash';
import { isLoggedIn } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
import csrf from '~/lib/utils/csrf';
import '~/behaviors/markdown/render_gfm';
export default {
name: 'TermsApp',
i18n: {
accept: __('Accept terms'),
continue: __('Continue'),
decline: __('Decline and sign out'),
},
flashElements: [],
csrf,
directives: {
SafeHtml,
},
components: { GlButton, GlIntersectionObserver },
inject: ['terms', 'permissions', 'paths'],
data() {
return {
acceptDisabled: true,
};
},
computed: {
isLoggedIn,
},
mounted() {
this.renderGFM();
this.setScrollableViewportHeight();
this.$options.flashElements = [
...document.querySelectorAll(
Object.values(FLASH_TYPES)
.map((flashType) => `.flash-${flashType}`)
.join(','),
),
];
this.$options.flashElements.forEach((flashElement) => {
flashElement.addEventListener(FLASH_CLOSED_EVENT, this.handleFlashClose);
});
},
beforeDestroy() {
this.$options.flashElements.forEach((flashElement) => {
flashElement.removeEventListener(FLASH_CLOSED_EVENT, this.handleFlashClose);
});
},
methods: {
renderGFM() {
$(this.$refs.gfmContainer).renderGFM();
},
handleBottomReached() {
this.acceptDisabled = false;
},
setScrollableViewportHeight() {
// Reset `max-height` inline style
this.$refs.scrollableViewport.style.maxHeight = '';
const { scrollHeight, clientHeight } = document.documentElement;
// Set `max-height` to 100vh minus all elements that are NOT the scrollable viewport (header, footer, alerts, etc)
this.$refs.scrollableViewport.style.maxHeight = `calc(100vh - ${
scrollHeight - clientHeight
}px)`;
},
handleFlashClose(event) {
this.setScrollableViewportHeight();
event.target.removeEventListener(FLASH_CLOSED_EVENT, this.handleFlashClose);
},
},
};
</script>
<template>
<div>
<div class="gl-card-body gl-relative gl-pb-0 gl-px-0" data-qa-selector="terms_content">
<div
class="terms-fade gl-absolute gl-left-5 gl-right-5 gl-bottom-0 gl-h-11 gl-pointer-events-none"
></div>
<div
ref="scrollableViewport"
data-testid="scrollable-viewport"
class="gl-h-100vh gl-overflow-y-auto gl-pb-11 gl-px-5"
>
<div ref="gfmContainer" v-safe-html="terms"></div>
<gl-intersection-observer @appear="handleBottomReached">
<div></div>
</gl-intersection-observer>
</div>
</div>
<div v-if="isLoggedIn" class="gl-card-footer gl-display-flex gl-justify-content-end">
<form v-if="permissions.canDecline" method="post" :action="paths.decline">
<gl-button type="submit">{{ $options.i18n.decline }}</gl-button>
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
</form>
<form v-if="permissions.canAccept" class="gl-ml-3" method="post" :action="paths.accept">
<gl-button
type="submit"
variant="confirm"
:disabled="acceptDisabled"
data-qa-selector="accept_terms_button"
>{{ $options.i18n.accept }}</gl-button
>
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
</form>
<gl-button v-else class="gl-ml-3" :href="paths.root" variant="confirm">{{
$options.i18n.continue
}}</gl-button>
</div>
</div>
</template>