diff options
Diffstat (limited to 'app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue')
-rw-r--r-- | app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue b/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue index 3522243e3e7..4af696b8dab 100644 --- a/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue +++ b/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue @@ -1,7 +1,9 @@ <script> -import createFlash from '~/flash'; +import { createAlert } from '~/flash'; +import { __ } from '~/locale'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import { reportMessageToSentry } from '../utils'; import getGroupVariables from '../graphql/queries/group_variables.query.graphql'; import { ADD_MUTATION_ACTION, @@ -25,6 +27,10 @@ export default { data() { return { groupVariables: [], + hasNextPage: false, + isLoadingMoreItems: false, + loadingCounter: 0, + pageInfo: {}, }; }, apollo: { @@ -38,8 +44,28 @@ export default { update(data) { return data?.group?.ciVariables?.nodes || []; }, + result({ data }) { + this.pageInfo = data?.group?.ciVariables?.pageInfo || this.pageInfo; + this.hasNextPage = this.pageInfo?.hasNextPage || false; + // Because graphQL has a limit of 100 items, + // we batch load all the variables by making successive queries + // to keep the same UX. As a safeguard, we make sure that we cannot go over + // 20 consecutive API calls, which means 2000 variables loaded maximum. + if (!this.hasNextPage) { + this.isLoadingMoreItems = false; + } else if (this.loadingCounter < 20) { + this.hasNextPage = false; + this.fetchMoreVariables(); + this.loadingCounter += 1; + } else { + createAlert({ message: this.$options.tooManyCallsError }); + reportMessageToSentry(this.$options.componentName, this.$options.tooManyCallsError, {}); + } + }, error() { - createFlash({ message: variableFetchErrorText }); + this.isLoadingMoreItems = false; + this.hasNextPage = false; + createAlert({ message: variableFetchErrorText }); }, }, }, @@ -48,7 +74,7 @@ export default { return this.glFeatures.groupScopedCiVariables; }, isLoading() { - return this.$apollo.queries.groupVariables.loading; + return this.$apollo.queries.groupVariables.loading || this.isLoadingMoreItems; }, }, methods: { @@ -58,6 +84,16 @@ export default { deleteVariable(variable) { this.variableMutation(DELETE_MUTATION_ACTION, variable); }, + fetchMoreVariables() { + this.isLoadingMoreItems = true; + + this.$apollo.queries.groupVariables.fetchMore({ + variables: { + fullPath: this.groupPath, + after: this.pageInfo.endCursor, + }, + }); + }, updateVariable(variable) { this.variableMutation(UPDATE_MUTATION_ACTION, variable); }, @@ -74,16 +110,19 @@ export default { }, }); - const { errors } = data[currentMutation.name]; - - if (errors.length > 0) { - createFlash({ message: errors[0] }); + if (data[currentMutation.name]?.errors?.length) { + const { errors } = data[currentMutation.name]; + createAlert({ message: errors[0] }); } } catch { - createFlash({ message: genericMutationErrorText }); + createAlert({ message: genericMutationErrorText }); } }, }, + componentName: 'GroupVariables', + i18n: { + tooManyCallsError: __('Maximum number of variables loaded (2000)'), + }, mutationData: { [ADD_MUTATION_ACTION]: { action: addGroupVariable, name: 'addGroupVariable' }, [UPDATE_MUTATION_ACTION]: { action: updateGroupVariable, name: 'updateGroupVariable' }, |