Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-08 18:15:55 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-08 18:15:55 +0300
commitcce7638874731ceee921881393c319feda6dc418 (patch)
treea847cf76042f69d90d9d0fd4bdd856daa68893e1 /app/assets/javascripts/security_configuration
parent6728ed6fe203d0613ee63c89a08a70fffb93405c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/security_configuration')
-rw-r--r--app/assets/javascripts/security_configuration/components/training_provider_list.vue80
-rw-r--r--app/assets/javascripts/security_configuration/graphql/cache_utils.js40
-rw-r--r--app/assets/javascripts/security_configuration/graphql/utils/optimistic_response.js13
3 files changed, 110 insertions, 23 deletions
diff --git a/app/assets/javascripts/security_configuration/components/training_provider_list.vue b/app/assets/javascripts/security_configuration/components/training_provider_list.vue
index ff7d14ed95a..5bccd91e55e 100644
--- a/app/assets/javascripts/security_configuration/components/training_provider_list.vue
+++ b/app/assets/javascripts/security_configuration/components/training_provider_list.vue
@@ -2,7 +2,7 @@
import { GlAlert, GlCard, GlToggle, GlLink, GlSkeletonLoader } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import Tracking from '~/tracking';
-import { __ } from '~/locale';
+import { __, s__ } from '~/locale';
import {
TRACK_TOGGLE_TRAINING_PROVIDER_ACTION,
TRACK_TOGGLE_TRAINING_PROVIDER_LABEL,
@@ -10,9 +10,12 @@ import {
TRACK_PROVIDER_LEARN_MORE_CLICK_LABEL,
} from '~/security_configuration/constants';
import dismissUserCalloutMutation from '~/graphql_shared/mutations/dismiss_user_callout.mutation.graphql';
-import { updateSecurityTrainingOptimisticResponse } from '~/security_configuration/graphql/utils/optimistic_response';
-import securityTrainingProvidersQuery from '../graphql/security_training_providers.query.graphql';
-import configureSecurityTrainingProvidersMutation from '../graphql/configure_security_training_providers.mutation.graphql';
+import securityTrainingProvidersQuery from '~/security_configuration/graphql/security_training_providers.query.graphql';
+import configureSecurityTrainingProvidersMutation from '~/security_configuration/graphql/configure_security_training_providers.mutation.graphql';
+import {
+ updateSecurityTrainingCache,
+ updateSecurityTrainingOptimisticResponse,
+} from '~/security_configuration/graphql/cache_utils';
const i18n = {
providerQueryErrorMessage: __(
@@ -21,6 +24,7 @@ const i18n = {
configMutationErrorMessage: __(
'Could not save configuration. Please refresh the page, or try again later.',
),
+ primaryTraining: s__('SecurityTraining|Primary Training'),
};
export default {
@@ -57,6 +61,9 @@ export default {
};
},
computed: {
+ enabledProviders() {
+ return this.securityTrainingProviders.filter(({ isEnabled }) => isEnabled);
+ },
isLoading() {
return this.$apollo.queries.securityTrainingProviders.loading;
},
@@ -91,14 +98,42 @@ export default {
Sentry.captureException(e);
}
},
- toggleProvider(provider) {
- const { isEnabled } = provider;
+ async toggleProvider(provider) {
+ const { isEnabled, isPrimary } = provider;
const toggledIsEnabled = !isEnabled;
this.trackProviderToggle(provider.id, toggledIsEnabled);
- this.storeProvider({ ...provider, isEnabled: toggledIsEnabled });
+
+ // when the current primary provider gets disabled then set the first enabled to be the new primary
+ if (!toggledIsEnabled && isPrimary && this.enabledProviders.length > 1) {
+ const firstOtherEnabledProvider = this.enabledProviders.find(
+ ({ id }) => id !== provider.id,
+ );
+ this.setPrimaryProvider(firstOtherEnabledProvider);
+ }
+
+ this.storeProvider({
+ ...provider,
+ isEnabled: toggledIsEnabled,
+ });
+ },
+ setPrimaryProvider(provider) {
+ this.storeProvider({ ...provider, isPrimary: true });
},
- async storeProvider({ id, isEnabled, isPrimary }) {
+ async storeProvider(provider) {
+ const { id, isEnabled, isPrimary } = provider;
+ let nextIsPrimary = isPrimary;
+
+ // if the current provider has been disabled it can't be primary
+ if (!isEnabled) {
+ nextIsPrimary = false;
+ }
+
+ // if the current provider is the only enabled provider it should be primary
+ if (isEnabled && !this.enabledProviders.length) {
+ nextIsPrimary = true;
+ }
+
try {
const {
data: {
@@ -111,13 +146,17 @@ export default {
projectPath: this.projectFullPath,
providerId: id,
isEnabled,
- isPrimary,
+ isPrimary: nextIsPrimary,
},
},
optimisticResponse: updateSecurityTrainingOptimisticResponse({
id,
isEnabled,
- isPrimary,
+ isPrimary: nextIsPrimary,
+ }),
+ update: updateSecurityTrainingCache({
+ query: securityTrainingProvidersQuery,
+ variables: { fullPath: this.projectFullPath },
}),
});
@@ -188,6 +227,27 @@ export default {
{{ __('Learn more.') }}
</gl-link>
</p>
+ <!-- Note: The following `div` and it's content will be replaced by 'GlFormRadio' once https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1720#note_857342988 is resolved -->
+ <div
+ class="gl-form-radio custom-control custom-radio"
+ data-testid="primary-provider-radio"
+ >
+ <input
+ :id="`security-training-provider-${provider.id}`"
+ type="radio"
+ :checked="provider.isPrimary"
+ name="radio-group-name"
+ class="custom-control-input"
+ :disabled="!provider.isEnabled"
+ @change="setPrimaryProvider(provider)"
+ />
+ <label
+ class="custom-control-label"
+ :for="`security-training-provider-${provider.id}`"
+ >
+ {{ $options.i18n.primaryTraining }}
+ </label>
+ </div>
</div>
</div>
</gl-card>
diff --git a/app/assets/javascripts/security_configuration/graphql/cache_utils.js b/app/assets/javascripts/security_configuration/graphql/cache_utils.js
new file mode 100644
index 00000000000..6d5258b01dc
--- /dev/null
+++ b/app/assets/javascripts/security_configuration/graphql/cache_utils.js
@@ -0,0 +1,40 @@
+import produce from 'immer';
+
+export const updateSecurityTrainingOptimisticResponse = (changes) => ({
+ // False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ __typename: 'Mutation',
+ securityTrainingUpdate: {
+ __typename: 'SecurityTrainingUpdatePayload',
+ training: {
+ __typename: 'ProjectSecurityTraining',
+ ...changes,
+ },
+ errors: [],
+ },
+});
+
+export const updateSecurityTrainingCache = ({ query, variables }) => (cache, { data }) => {
+ const {
+ securityTrainingUpdate: { training: updatedProvider },
+ } = data;
+ const { project } = cache.readQuery({ query, variables });
+ if (!updatedProvider.isPrimary) {
+ return;
+ }
+
+ // when we set a new primary provider, we need to unset the previous one(s)
+ const updatedProject = produce(project, (draft) => {
+ draft.securityTrainingProviders.forEach((provider) => {
+ // eslint-disable-next-line no-param-reassign
+ provider.isPrimary = provider.id === updatedProvider.id;
+ });
+ });
+
+ // write to the cache
+ cache.writeQuery({
+ query,
+ variables,
+ data: { project: updatedProject },
+ });
+};
diff --git a/app/assets/javascripts/security_configuration/graphql/utils/optimistic_response.js b/app/assets/javascripts/security_configuration/graphql/utils/optimistic_response.js
deleted file mode 100644
index 8d1082d081a..00000000000
--- a/app/assets/javascripts/security_configuration/graphql/utils/optimistic_response.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export const updateSecurityTrainingOptimisticResponse = (changes) => ({
- // False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26
- // eslint-disable-next-line @gitlab/require-i18n-strings
- __typename: 'Mutation',
- securityTrainingUpdate: {
- __typename: 'SecurityTrainingUpdatePayload',
- training: {
- __typename: 'ProjectSecurityTraining',
- ...changes,
- },
- errors: [],
- },
-});