From 4862107805612031e6cdbfde5471e42f29102c40 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 15 Jan 2024 18:43:50 +0100 Subject: [PATCH 1/6] feat: Protected packages: Update protection rules in project settings ui MR includes: - Adding option to update the protection rule - Sending a graphql mutation "updatePackagesProtectionRule" when access level for push protection changes - Adding an alert when the graphql mutation is not successful - Adding tests Changelog: added --- .../components/packages_protection_rules.vue | 107 +++++++++--- ..._packages_protection_rule.mutation.graphql | 10 ++ locale/gitlab.pot | 3 + .../packages_protection_rules_spec.js | 155 +++++++++++++++++- .../settings/project/settings/mock_data.js | 15 ++ 5 files changed, 263 insertions(+), 27 deletions(-) create mode 100644 app/assets/javascripts/packages_and_registries/settings/project/graphql/mutations/update_packages_protection_rule.mutation.graphql diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_protection_rules.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_protection_rules.vue index 152ce8474f2465..8238d7d7f95dd8 100644 --- a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_protection_rules.vue +++ b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_protection_rules.vue @@ -8,22 +8,18 @@ import { GlKeysetPagination, GlModal, GlModalDirective, + GlFormSelect, } from '@gitlab/ui'; import packagesProtectionRuleQuery from '~/packages_and_registries/settings/project/graphql/queries/get_packages_protection_rules.query.graphql'; import { getPackageTypeLabel } from '~/packages_and_registries/package_registry/utils'; import deletePackagesProtectionRuleMutation from '~/packages_and_registries/settings/project/graphql/mutations/delete_packages_protection_rule.mutation.graphql'; +import updatePackagesProtectionRuleMutation from '~/packages_and_registries/settings/project/graphql/mutations/update_packages_protection_rule.mutation.graphql'; import SettingsBlock from '~/packages_and_registries/shared/components/settings_block.vue'; import PackagesProtectionRuleForm from '~/packages_and_registries/settings/project/components/packages_protection_rule_form.vue'; import { s__, __ } from '~/locale'; const PAGINATION_DEFAULT_PER_PAGE = 10; -const ACCESS_LEVEL_GRAPHQL_VALUE_TO_LABEL = { - DEVELOPER: __('Developer'), - MAINTAINER: __('Maintainer'), - OWNER: __('Owner'), -}; - export default { components: { SettingsBlock, @@ -35,6 +31,7 @@ export default { PackagesProtectionRuleForm, GlKeysetPagination, GlModal, + GlFormSelect, }, directives: { GlModal: GlModalDirective, @@ -59,11 +56,9 @@ export default { protectionRuleFormVisibility: false, packageProtectionRulesQueryPayload: { nodes: [], pageInfo: {} }, packageProtectionRulesQueryPaginationParams: { first: PAGINATION_DEFAULT_PER_PAGE }, - deleteInProgress: false, - deleteItem: null, + protectionRuleMutationInProgress: false, + protectionRuleMutationItem: null, alertErrorMessage: '', - protectionRuleDeletionInProgress: false, - protectionRuleDeletionItem: null, }; }, computed: { @@ -71,12 +66,9 @@ export default { return this.packageProtectionRulesQueryResult.map((packagesProtectionRule) => { return { id: packagesProtectionRule.id, + pushProtectedUpToAccessLevel: packagesProtectionRule.pushProtectedUpToAccessLevel, col_1_package_name_pattern: packagesProtectionRule.packageNamePattern, col_2_package_type: getPackageTypeLabel(packagesProtectionRule.packageType), - col_3_push_protected_up_to_access_level: - ACCESS_LEVEL_GRAPHQL_VALUE_TO_LABEL[ - packagesProtectionRule.pushProtectedUpToAccessLevel - ], }; }); }, @@ -105,6 +97,13 @@ export default { text: __('Cancel'), }; }, + pushProtectedUpToAccessLevelOptions() { + return [ + { value: 'DEVELOPER', text: __('Developer') }, + { value: 'MAINTAINER', text: __('Maintainer') }, + { value: 'OWNER', text: __('Owner') }, + ]; + }, }, apollo: { packageProtectionRulesQueryPayload: { @@ -146,16 +145,13 @@ export default { last: PAGINATION_DEFAULT_PER_PAGE, }; }, - isButtonDisabled(item) { - return this.protectionRuleDeletionItem === item && this.protectionRuleDeletionInProgress; - }, showProtectionRuleDeletionConfirmModal(protectionRule) { - this.protectionRuleDeletionItem = protectionRule; + this.protectionRuleMutationItem = protectionRule; }, deleteProtectionRule(protectionRule) { this.clearAlertMessage(); - this.protectionRuleDeletionInProgress = true; + this.protectionRuleMutationInProgress = true; return this.$apollo .mutate({ @@ -175,30 +171,78 @@ export default { this.alertErrorMessage = e.message; }) .finally(() => { - this.protectionRuleDeletionItem = null; - this.protectionRuleDeletionInProgress = false; + this.resetProtectionRuleMutation(); + }); + }, + updatePackageProtectionRule(packageProtectionRule) { + this.clearAlertMessage(); + + this.protectionRuleMutationItem = packageProtectionRule; + this.protectionRuleMutationInProgress = true; + + return this.$apollo + .mutate({ + mutation: updatePackagesProtectionRuleMutation, + variables: { + input: { + id: packageProtectionRule.id, + pushProtectedUpToAccessLevel: packageProtectionRule.pushProtectedUpToAccessLevel, + }, + }, + }) + .then(({ data }) => { + const [errorMessage] = data?.updatePackagesProtectionRule?.errors ?? []; + if (errorMessage) { + this.alertErrorMessage = errorMessage; + } + + this.$toast.show(s__('PackageRegistry|Package protection rule updated.')); + }) + .catch((error) => { + this.alertErrorMessage = error.message; + }) + .finally(() => { + this.resetProtectionRuleMutation(); }); }, clearAlertMessage() { this.alertErrorMessage = ''; }, + resetProtectionRuleMutation() { + this.protectionRuleMutationItem = null; + this.protectionRuleMutationInProgress = false; + }, + isProtectionRulePushProtectedUpToAccessLevelFormSelectDisabled(item) { + return this.isProtectionRuleMutationInProgress(item); + }, + isProtectionRuleDeleteButtonDisabled(item) { + return this.isProtectionRuleMutationInProgress(item); + }, + isProtectionRuleMutationInProgress(item) { + return this.protectionRuleMutationItem === item && this.protectionRuleMutationInProgress; + }, }, - table: {}, fields: [ { key: 'col_1_package_name_pattern', label: s__('PackageRegistry|Package name pattern'), + tdClass: 'gl-w-30', + }, + { + key: 'col_2_package_type', + label: s__('PackageRegistry|Package type'), + tdClass: 'gl-w-10', }, - { key: 'col_2_package_type', label: s__('PackageRegistry|Package type') }, { key: 'col_3_push_protected_up_to_access_level', label: s__('PackageRegistry|Push protected up to access level'), + tdClass: 'gl-w-15', }, { key: 'col_4_actions', label: '', thClass: 'gl-display-none', - tdClass: 'gl-w-15p', + tdClass: 'gl-w-10', }, ], modal: { id: 'delete-package-protection-rule-confirmation-modal' }, @@ -262,13 +306,24 @@ export default { + +