diff options
Diffstat (limited to 'app/assets/javascripts/observability/components')
-rw-r--r-- | app/assets/javascripts/observability/components/observability_container.vue | 92 | ||||
-rw-r--r-- | app/assets/javascripts/observability/components/skeleton/index.vue | 59 |
2 files changed, 139 insertions, 12 deletions
diff --git a/app/assets/javascripts/observability/components/observability_container.vue b/app/assets/javascripts/observability/components/observability_container.vue new file mode 100644 index 00000000000..4306f531ab5 --- /dev/null +++ b/app/assets/javascripts/observability/components/observability_container.vue @@ -0,0 +1,92 @@ +<script> +import { buildClient } from '../client'; +import { SKELETON_SPINNER_VARIANT } from '../constants'; +import ObservabilitySkeleton from './skeleton/index.vue'; + +export default { + SKELETON_SPINNER_VARIANT, + components: { + ObservabilitySkeleton, + }, + props: { + oauthUrl: { + type: String, + required: true, + }, + tracingUrl: { + type: String, + required: true, + }, + provisioningUrl: { + type: String, + required: true, + }, + }, + data() { + return { + observabilityClient: null, + authCompleted: false, + }; + }, + mounted() { + window.addEventListener('message', this.messageHandler); + + // TODO Remove once backend work done - just for testing + // https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2270 + // setTimeout(() => { + // this.messageHandler({ + // data: { type: 'AUTH_COMPLETION', status: 'success' }, + // origin: new URL(this.oauthUrl).origin, + // }); + // }, 2000); + }, + destroyed() { + window.removeEventListener('message', this.messageHandler); + }, + methods: { + messageHandler(e) { + const isExpectedOrigin = e.origin === new URL(this.oauthUrl).origin; + if (!isExpectedOrigin) return; + + const { data } = e; + + if (data.type === 'AUTH_COMPLETION') { + if (this.authCompleted) return; + + const { status, message, statusCode } = data; + if (status === 'success') { + this.observabilityClient = buildClient({ + provisioningUrl: this.provisioningUrl, + tracingUrl: this.tracingUrl, + }); + this.$refs.observabilitySkeleton?.onContentLoaded(); + } else if (status === 'error') { + // eslint-disable-next-line @gitlab/require-i18n-strings,no-console + console.error('GOB auth failed with error:', message, statusCode); + this.$refs.observabilitySkeleton?.onError(); + } + this.authCompleted = true; + } + }, + }, +}; +</script> + +<template> + <div> + <iframe + v-if="!authCompleted" + sandbox="allow-same-origin allow-forms allow-scripts" + hidden + :src="oauthUrl" + data-testid="observability-oauth-iframe" + ></iframe> + + <observability-skeleton + ref="observabilitySkeleton" + :variant="$options.SKELETON_SPINNER_VARIANT" + > + <slot v-if="observabilityClient" :observability-client="observabilityClient"></slot> + </observability-skeleton> + </div> +</template> diff --git a/app/assets/javascripts/observability/components/skeleton/index.vue b/app/assets/javascripts/observability/components/skeleton/index.vue index d91f2874943..4df0f86be1f 100644 --- a/app/assets/javascripts/observability/components/skeleton/index.vue +++ b/app/assets/javascripts/observability/components/skeleton/index.vue @@ -1,5 +1,5 @@ <script> -import { GlSkeletonLoader, GlAlert } from '@gitlab/ui'; +import { GlSkeletonLoader, GlAlert, GlLoadingIcon } from '@gitlab/ui'; import { SKELETON_VARIANTS_BY_ROUTE, @@ -9,6 +9,7 @@ import { TIMEOUT_ERROR_LABEL, TIMEOUT_ERROR_MESSAGE, SKELETON_VARIANT_EMBED, + SKELETON_SPINNER_VARIANT, } from '../../constants'; import DashboardsSkeleton from './dashboards.vue'; import ExploreSkeleton from './explore.vue'; @@ -23,6 +24,7 @@ export default { ManageSkeleton, EmbedSkeleton, GlAlert, + GlLoadingIcon, }, SKELETON_VARIANTS_BY_ROUTE, SKELETON_STATE, @@ -46,6 +48,23 @@ export default { errorTimeout: null, }; }, + computed: { + skeletonVisible() { + return this.state === SKELETON_STATE.VISIBLE; + }, + skeletonHidden() { + return this.state === SKELETON_STATE.HIDDEN; + }, + errorVisible() { + return this.state === SKELETON_STATE.ERROR; + }, + spinnerVariant() { + return this.variant === SKELETON_SPINNER_VARIANT; + }, + embedVariant() { + return this.variant === SKELETON_VARIANT_EMBED; + }, + }, mounted() { this.setLoadingTimeout(); this.setErrorTimeout(); @@ -61,6 +80,12 @@ export default { this.hideSkeleton(); }, + onError() { + clearTimeout(this.errorTimeout); + clearTimeout(this.loadingTimeout); + + this.showError(); + }, setLoadingTimeout() { this.loadingTimeout = setTimeout(() => { /** @@ -92,8 +117,7 @@ export default { showError() { this.state = SKELETON_STATE.ERROR; }, - - isSkeletonShown(route) { + isVariantByRoute(route) { return this.variant === SKELETON_VARIANTS_BY_ROUTE[route]; }, }, @@ -102,11 +126,12 @@ export default { <template> <div class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column gl-flex-align-items-stretch"> <transition name="fade"> - <div v-if="state === $options.SKELETON_STATE.VISIBLE" class="gl-px-5"> - <dashboards-skeleton v-if="isSkeletonShown($options.OBSERVABILITY_ROUTES.DASHBOARDS)" /> - <explore-skeleton v-else-if="isSkeletonShown($options.OBSERVABILITY_ROUTES.EXPLORE)" /> - <manage-skeleton v-else-if="isSkeletonShown($options.OBSERVABILITY_ROUTES.MANAGE)" /> - <embed-skeleton v-else-if="variant === $options.SKELETON_VARIANT_EMBED" /> + <div v-if="skeletonVisible" class="gl-px-5 gl-my-5"> + <dashboards-skeleton v-if="isVariantByRoute($options.OBSERVABILITY_ROUTES.DASHBOARDS)" /> + <explore-skeleton v-else-if="isVariantByRoute($options.OBSERVABILITY_ROUTES.EXPLORE)" /> + <manage-skeleton v-else-if="isVariantByRoute($options.OBSERVABILITY_ROUTES.MANAGE)" /> + <embed-skeleton v-else-if="embedVariant" /> + <gl-loading-icon v-else-if="spinnerVariant" size="lg" /> <gl-skeleton-loader v-else> <rect y="2" width="10" height="8" /> @@ -115,10 +140,19 @@ export default { <rect y="15" width="400" height="30" /> </gl-skeleton-loader> </div> + + <!-- The double condition is only here temporarily for back-compatibility reasons. Will be removed in next iteration https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2275 --> + <div + v-else-if="spinnerVariant && skeletonHidden" + data-testid="content-wrapper" + class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column gl-flex-align-items-stretch" + > + <slot></slot> + </div> </transition> <gl-alert - v-if="state === $options.SKELETON_STATE.ERROR" + v-if="errorVisible" :title="$options.i18n.TIMEOUT_ERROR_LABEL" variant="danger" :dismissible="false" @@ -127,10 +161,11 @@ export default { {{ $options.i18n.TIMEOUT_ERROR_MESSAGE }} </gl-alert> - <transition> + <!-- This is only kept temporarily for back-compatibility reasons. Will be removed in next iteration https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2275 --> + <transition v-if="!spinnerVariant"> <div - v-show="state === $options.SKELETON_STATE.HIDDEN" - data-testid="observability-wrapper" + v-show="skeletonHidden" + data-testid="content-wrapper" class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column gl-flex-align-items-stretch" > <slot></slot> |