summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue
diff options
context:
space:
mode:
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.vue55
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' },