diff options
Diffstat (limited to 'app/assets/javascripts/observability/components/skeleton/index.vue')
-rw-r--r-- | app/assets/javascripts/observability/components/skeleton/index.vue | 128 |
1 files changed, 86 insertions, 42 deletions
diff --git a/app/assets/javascripts/observability/components/skeleton/index.vue b/app/assets/javascripts/observability/components/skeleton/index.vue index 1e2671c8166..c8f196a43f4 100644 --- a/app/assets/javascripts/observability/components/skeleton/index.vue +++ b/app/assets/javascripts/observability/components/skeleton/index.vue @@ -1,17 +1,32 @@ <script> -import { GlSkeletonLoader } from '@gitlab/ui'; -import { SKELETON_VARIANT } from '../../constants'; +import { GlSkeletonLoader, GlAlert } from '@gitlab/ui'; + +import { + SKELETON_VARIANTS_BY_ROUTE, + SKELETON_STATE, + DEFAULT_TIMERS, + OBSERVABILITY_ROUTES, + TIMEOUT_ERROR_LABEL, + TIMEOUT_ERROR_MESSAGE, +} from '../../constants'; import DashboardsSkeleton from './dashboards.vue'; import ExploreSkeleton from './explore.vue'; import ManageSkeleton from './manage.vue'; export default { - SKELETON_VARIANT, components: { GlSkeletonLoader, DashboardsSkeleton, ExploreSkeleton, ManageSkeleton, + GlAlert, + }, + SKELETON_VARIANTS_BY_ROUTE, + SKELETON_STATE, + OBSERVABILITY_ROUTES, + i18n: { + TIMEOUT_ERROR_LABEL, + TIMEOUT_ERROR_MESSAGE, }, props: { variant: { @@ -22,65 +37,94 @@ export default { }, data() { return { - loading: null, - timerId: null, + state: null, + loadingTimeout: null, + errorTimeout: null, }; }, mounted() { - this.timerId = setTimeout(() => { - /** - * If observability UI is not loaded then this.loading would be null - * we will show skeleton in that case - */ - if (this.loading !== false) { - this.showSkeleton(); - } - }, 500); + this.setLoadingTimeout(); + this.setErrorTimeout(); + }, + destroyed() { + clearTimeout(this.loadingTimeout); + clearTimeout(this.errorTimeout); }, methods: { - handleSkeleton() { - if (this.loading === null) { + onContentLoaded() { + clearTimeout(this.errorTimeout); + clearTimeout(this.loadingTimeout); + + this.hideSkeleton(); + }, + setLoadingTimeout() { + this.loadingTimeout = setTimeout(() => { /** - * If observability UI content loads with in 500ms - * do not show skeleton. + * If content is not loaded within CONTENT_WAIT_MS, + * show the skeleton */ - clearTimeout(this.timerId); - return; - } - - /** - * If observability UI content loads after 500ms - * wait for 400ms to hide skeleton. - * This is mostly to avoid the flashing effect If content loads imediately after skeleton - */ - setTimeout(this.hideSkeleton, 400); + if (this.state !== SKELETON_STATE.HIDDEN) { + this.showSkeleton(); + } + }, DEFAULT_TIMERS.CONTENT_WAIT_MS); + }, + setErrorTimeout() { + this.errorTimeout = setTimeout(() => { + /** + * If content is not loaded within TIMEOUT_MS, + * show the error dialog + */ + if (this.state !== SKELETON_STATE.HIDDEN) { + this.showError(); + } + }, DEFAULT_TIMERS.TIMEOUT_MS); }, hideSkeleton() { - this.loading = false; + this.state = SKELETON_STATE.HIDDEN; }, showSkeleton() { - this.loading = true; + this.state = SKELETON_STATE.VISIBLE; + }, + showError() { + this.state = SKELETON_STATE.ERROR; + }, + + isSkeletonShown(route) { + return this.variant === SKELETON_VARIANTS_BY_ROUTE[route]; }, }, }; </script> <template> <div class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column gl-flex-align-items-stretch"> - <div v-show="loading" class="gl-px-5"> - <dashboards-skeleton v-if="variant === $options.SKELETON_VARIANT.DASHBOARDS" /> - <explore-skeleton v-else-if="variant === $options.SKELETON_VARIANT.EXPLORE" /> - <manage-skeleton v-else-if="variant === $options.SKELETON_VARIANT.MANAGE" /> + <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)" /> - <gl-skeleton-loader v-else> - <rect y="2" width="10" height="8" /> - <rect y="2" x="15" width="15" height="8" /> - <rect y="2" x="35" width="15" height="8" /> - <rect y="15" width="400" height="30" /> - </gl-skeleton-loader> - </div> + <gl-skeleton-loader v-else> + <rect y="2" width="10" height="8" /> + <rect y="2" x="15" width="15" height="8" /> + <rect y="2" x="35" width="15" height="8" /> + <rect y="15" width="400" height="30" /> + </gl-skeleton-loader> + </div> + </transition> + + <gl-alert + v-if="state === $options.SKELETON_STATE.ERROR" + :title="$options.i18n.TIMEOUT_ERROR_LABEL" + variant="danger" + :dismissible="false" + class="gl-m-5" + > + {{ $options.i18n.TIMEOUT_ERROR_MESSAGE }} + </gl-alert> <div - v-show="!loading" + v-show="state === $options.SKELETON_STATE.HIDDEN" + data-testid="observability-wrapper" class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column gl-flex-align-items-stretch" > <slot></slot> |