diff options
Diffstat (limited to 'app/assets/javascripts/clusters_list')
6 files changed, 93 insertions, 24 deletions
diff --git a/app/assets/javascripts/clusters_list/components/ancestor_notice.vue b/app/assets/javascripts/clusters_list/components/ancestor_notice.vue new file mode 100644 index 00000000000..7954fc61785 --- /dev/null +++ b/app/assets/javascripts/clusters_list/components/ancestor_notice.vue @@ -0,0 +1,34 @@ +<script> +import { GlLink, GlSprintf } from '@gitlab/ui'; +import { mapState } from 'vuex'; + +export default { + components: { + GlLink, + GlSprintf, + }, + computed: { + ...mapState(['ancestorHelperPath', 'hasAncestorClusters']), + }, +}; +</script> + +<template> + <div v-if="hasAncestorClusters" class="bs-callout bs-callout-info"> + <p> + <gl-sprintf + :message=" + s__( + 'ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters. %{linkStart}More information%{linkEnd}', + ) + " + > + <template #link="{ content }"> + <gl-link :href="ancestorHelperPath"> + <strong>{{ content }}</strong> + </gl-link> + </template> + </gl-sprintf> + </p> + </div> +</template> diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue index a3104038c17..7e9b720d269 100644 --- a/app/assets/javascripts/clusters_list/components/clusters.vue +++ b/app/assets/javascripts/clusters_list/components/clusters.vue @@ -1,14 +1,15 @@ <script> -import * as Sentry from '@sentry/browser'; import { mapState, mapActions } from 'vuex'; import { GlDeprecatedBadge as GlBadge, GlLink, GlLoadingIcon, GlPagination, + GlSkeletonLoading, GlSprintf, GlTable, } from '@gitlab/ui'; +import AncestorNotice from './ancestor_notice.vue'; import tooltip from '~/vue_shared/directives/tooltip'; import { CLUSTER_TYPES, STATUSES } from '../constants'; import { __, sprintf } from '~/locale'; @@ -17,10 +18,12 @@ export default { nodeMemoryText: __('%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)'), nodeCpuText: __('%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)'), components: { + AncestorNotice, GlBadge, GlLink, GlLoadingIcon, GlPagination, + GlSkeletonLoading, GlSprintf, GlTable, }, @@ -28,7 +31,18 @@ export default { tooltip, }, computed: { - ...mapState(['clusters', 'clustersPerPage', 'loading', 'page', 'providers', 'totalCulsters']), + ...mapState([ + 'clusters', + 'clustersPerPage', + 'loadingClusters', + 'loadingNodes', + 'page', + 'providers', + 'totalCulsters', + ]), + contentAlignClasses() { + return 'gl-display-flex gl-align-items-center gl-justify-content-end gl-justify-content-md-start'; + }, currentPage: { get() { return this.page; @@ -75,7 +89,7 @@ export default { this.fetchClusters(); }, methods: { - ...mapActions(['fetchClusters', 'setPage']), + ...mapActions(['fetchClusters', 'reportSentryError', 'setPage']), k8sQuantityToGb(quantity) { if (!quantity) { return 0; @@ -137,7 +151,7 @@ export default { }; } } catch (error) { - Sentry.captureException(error); + this.reportSentryError({ error, tag: 'totalMemoryAndUsageError' }); } return { totalMemory: null, freeSpacePercentage: null }; @@ -170,7 +184,7 @@ export default { }; } } catch (error) { - Sentry.captureException(error); + this.reportSentryError({ error, tag: 'totalCpuAndUsageError' }); } return { totalCpu: null, freeSpacePercentage: null }; @@ -180,14 +194,14 @@ export default { </script> <template> - <gl-loading-icon v-if="loading" size="md" class="mt-3" /> + <gl-loading-icon v-if="loadingClusters" size="md" class="gl-mt-3" /> <section v-else> + <ancestor-notice /> + <gl-table :items="clusters" :fields="fields" stacked="md" class="qa-clusters-table"> <template #cell(name)="{ item }"> - <div - class="gl-display-flex gl-align-items-center gl-justify-content-end gl-justify-content-md-start js-status" - > + <div :class="[contentAlignClasses, 'js-status']"> <img :src="selectedProvider(item.provider_type).path" :alt="selectedProvider(item.provider_type).text" @@ -214,6 +228,9 @@ export default { <template #cell(node_size)="{ item }"> <span v-if="item.nodes">{{ item.nodes.length }}</span> + + <gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" /> + <small v-else class="gl-font-sm gl-font-style-italic gl-text-gray-400">{{ __('Unknown') }}</small> @@ -231,6 +248,8 @@ export default { > </gl-sprintf> </span> + + <gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" /> </template> <template #cell(total_memory)="{ item }"> @@ -245,6 +264,8 @@ export default { > </gl-sprintf> </span> + + <gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" /> </template> <template #cell(cluster_type)="{value}"> diff --git a/app/assets/javascripts/clusters_list/store/actions.js b/app/assets/javascripts/clusters_list/store/actions.js index 5245c307c8c..dddcfb3d975 100644 --- a/app/assets/javascripts/clusters_list/store/actions.js +++ b/app/assets/javascripts/clusters_list/store/actions.js @@ -16,9 +16,18 @@ const allNodesPresent = (clusters, retryCount) => { return retryCount > MAX_REQUESTS || clusters.every(cluster => cluster.nodes != null); }; -export const fetchClusters = ({ state, commit }) => { +export const reportSentryError = (_store, { error, tag }) => { + Sentry.withScope(scope => { + scope.setTag('javascript_clusters_list', tag); + Sentry.captureException(error); + }); +}; + +export const fetchClusters = ({ state, commit, dispatch }) => { let retryCount = 0; + commit(types.SET_LOADING_NODES, true); + const poll = new Poll({ resource: { fetchClusters: paginatedEndPoint => axios.get(paginatedEndPoint), @@ -34,31 +43,30 @@ export const fetchClusters = ({ state, commit }) => { const paginationInformation = parseIntPagination(normalizedHeaders); commit(types.SET_CLUSTERS_DATA, { data, paginationInformation }); - commit(types.SET_LOADING_STATE, false); + commit(types.SET_LOADING_CLUSTERS, false); if (allNodesPresent(data.clusters, retryCount)) { poll.stop(); + commit(types.SET_LOADING_NODES, false); } } } catch (error) { poll.stop(); - Sentry.withScope(scope => { - scope.setTag('javascript_clusters_list', 'fetchClustersSuccessCallback'); - Sentry.captureException(error); - }); + commit(types.SET_LOADING_CLUSTERS, false); + commit(types.SET_LOADING_NODES, false); + + dispatch('reportSentryError', { error, tag: 'fetchClustersSuccessCallback' }); } }, errorCallback: response => { poll.stop(); - commit(types.SET_LOADING_STATE, false); + commit(types.SET_LOADING_CLUSTERS, false); + commit(types.SET_LOADING_NODES, false); flash(__('Clusters|An error occurred while loading clusters')); - Sentry.withScope(scope => { - scope.setTag('javascript_clusters_list', 'fetchClustersErrorCallback'); - Sentry.captureException(response); - }); + dispatch('reportSentryError', { error: response, tag: 'fetchClustersErrorCallback' }); }, }); diff --git a/app/assets/javascripts/clusters_list/store/mutation_types.js b/app/assets/javascripts/clusters_list/store/mutation_types.js index a5275f28c13..beb4388c93e 100644 --- a/app/assets/javascripts/clusters_list/store/mutation_types.js +++ b/app/assets/javascripts/clusters_list/store/mutation_types.js @@ -1,3 +1,4 @@ export const SET_CLUSTERS_DATA = 'SET_CLUSTERS_DATA'; -export const SET_LOADING_STATE = 'SET_LOADING_STATE'; +export const SET_LOADING_CLUSTERS = 'SET_LOADING_CLUSTERS'; +export const SET_LOADING_NODES = 'SET_LOADING_NODES'; export const SET_PAGE = 'SET_PAGE'; diff --git a/app/assets/javascripts/clusters_list/store/mutations.js b/app/assets/javascripts/clusters_list/store/mutations.js index 2a9df9f38f0..5b462928518 100644 --- a/app/assets/javascripts/clusters_list/store/mutations.js +++ b/app/assets/javascripts/clusters_list/store/mutations.js @@ -1,8 +1,11 @@ import * as types from './mutation_types'; export default { - [types.SET_LOADING_STATE](state, value) { - state.loading = value; + [types.SET_LOADING_CLUSTERS](state, value) { + state.loadingClusters = value; + }, + [types.SET_LOADING_NODES](state, value) { + state.loadingNodes = value; }, [types.SET_CLUSTERS_DATA](state, { data, paginationInformation }) { Object.assign(state, { diff --git a/app/assets/javascripts/clusters_list/store/state.js b/app/assets/javascripts/clusters_list/store/state.js index 0023b43ed92..51fafd49479 100644 --- a/app/assets/javascripts/clusters_list/store/state.js +++ b/app/assets/javascripts/clusters_list/store/state.js @@ -1,9 +1,11 @@ export default (initialState = {}) => ({ + ancestorHelperPath: initialState.ancestorHelpPath, endpoint: initialState.endpoint, hasAncestorClusters: false, - loading: true, clusters: [], clustersPerPage: 0, + loadingClusters: true, + loadingNodes: true, page: 1, providers: { aws: { path: initialState.imgTagsAwsPath, text: initialState.imgTagsAwsText }, |