diff options
Diffstat (limited to 'app/assets/javascripts/projects/settings/branch_rules/components/edit')
5 files changed, 350 insertions, 0 deletions
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/edit/branch_dropdown.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/branch_dropdown.vue new file mode 100644 index 00000000000..f2b1c749abc --- /dev/null +++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/branch_dropdown.vue @@ -0,0 +1,137 @@ +<script> +import { + GlDropdown, + GlDropdownItem, + GlDropdownDivider, + GlSearchBoxByType, + GlSprintf, + GlLink, +} from '@gitlab/ui'; +import { createAlert } from '~/flash'; +import { s__, sprintf } from '~/locale'; +import { helpPagePath } from '~/helpers/help_page_helper'; +import branchesQuery from '../../queries/branches.query.graphql'; + +export const i18n = { + fetchBranchesError: s__('BranchRules|An error occurred while fetching branches.'), + noMatch: s__('BranchRules|No matching results'), + branchHelpText: s__( + 'BranchRules|%{linkStart}Wildcards%{linkEnd} such as *-stable or production/* are supported.', + ), + wildCardSearchHelp: s__('BranchRules|Create wildcard: %{searchTerm}'), +}; + +export default { + i18n, + name: 'BranchDropdown', + components: { + GlDropdown, + GlDropdownItem, + GlDropdownDivider, + GlSearchBoxByType, + GlSprintf, + GlLink, + }, + apollo: { + branchNames: { + query: branchesQuery, + variables() { + return { + projectPath: this.projectPath, + searchPattern: `*${this.searchTerm}*`, + }; + }, + update({ project: { repository = {} } } = {}) { + return repository.branchNames || []; + }, + error(e) { + createAlert({ + message: this.$options.i18n.fetchBranchesError, + captureError: true, + error: e, + }); + }, + }, + }, + searchInputDelay: 250, + wildcardsHelpPath: helpPagePath('user/project/protected_branches', { + anchor: 'configure-multiple-protected-branches-by-using-a-wildcard', + }), + props: { + projectPath: { + type: String, + required: true, + }, + value: { + type: String, + required: false, + default: null, + }, + }, + data() { + return { + searchTerm: '', + branchNames: [], + }; + }, + computed: { + createButtonLabel() { + return sprintf(this.$options.i18n.wildCardSearchHelp, { + searchTerm: this.searchTerm, + }); + }, + shouldRenderCreateButton() { + return this.searchTerm && !this.branchNames.includes(this.searchTerm); + }, + isLoading() { + return this.$apollo.queries.branchNames.loading; + }, + }, + methods: { + selectBranch(selected) { + this.$emit('input', selected); + }, + createWildcard() { + this.$emit('createWildcard', this.searchTerm); + }, + isSelected(branch) { + return this.value === branch; + }, + }, +}; +</script> +<template> + <div> + <gl-dropdown :text="value || branchNames[0]" class="gl-w-full"> + <gl-search-box-by-type + v-model.trim="searchTerm" + data-testid="branch-search" + :debounce="$options.searchInputDelay" + :is-loading="isLoading" + /> + <gl-dropdown-item + v-for="branch in branchNames" + :key="branch" + :is-checked="isSelected(branch)" + is-check-item + @click="selectBranch(branch)" + > + {{ branch }} + </gl-dropdown-item> + <gl-dropdown-item v-if="!branchNames.length && !isLoading" data-testid="no-data">{{ + $options.i18n.noMatch + }}</gl-dropdown-item> + <template v-if="shouldRenderCreateButton"> + <gl-dropdown-divider /> + <gl-dropdown-item data-testid="create-wildcard-button" @click="createWildcard"> + {{ createButtonLabel }} + </gl-dropdown-item> + </template> + </gl-dropdown> + <gl-sprintf :message="$options.i18n.branchHelpText"> + <template #link="{ content }"> + <gl-link :href="$options.wildcardsHelpPath">{{ content }}</gl-link> + </template> + </gl-sprintf> + </div> +</template> diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/edit/index.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/index.vue new file mode 100644 index 00000000000..ad3eb7d2899 --- /dev/null +++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/index.vue @@ -0,0 +1,56 @@ +<script> +import { GlFormGroup } from '@gitlab/ui'; +import { s__ } from '~/locale'; +import { getParameterByName } from '~/lib/utils/url_utility'; +import BranchDropdown from './branch_dropdown.vue'; +import Protections from './protections/index.vue'; + +export default { + name: 'RuleEdit', + i18n: { branch: s__('BranchRules|Branch') }, + components: { + BranchDropdown, + GlFormGroup, + Protections, + }, + props: { + projectPath: { + type: String, + required: true, + }, + }, + data() { + return { + branch: getParameterByName('branch'), + protections: { + membersAllowedToPush: [], + allowForcePush: false, + membersAllowedToMerge: [], + requireCodeOwnersApproval: false, + }, + }; + }, +}; +</script> + +<template> + <div> + <gl-form-group :label="$options.i18n.branch"> + <branch-dropdown + id="branches" + v-model="branch" + class="gl-w-half" + :project-path="projectPath" + @createWildcard="branch = $event" + /> + </gl-form-group> + + <protections + :protections="protections" + @change-allowed-to-push-members="protections.membersAllowedToPush = $event" + @change-allow-force-push="protections.allowForcePush = $event" + @change-allowed-to-merge-members="protections.membersAllowedToMerge = $event" + @change-require-code-owners-approval="protections.requireCodeOwnersApproval = $event" + /> + </div> +</template> diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/index.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/index.vue new file mode 100644 index 00000000000..bcc0f64d667 --- /dev/null +++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/index.vue @@ -0,0 +1,59 @@ +<script> +import { GlSprintf, GlLink } from '@gitlab/ui'; +import { s__ } from '~/locale'; +import { helpPagePath } from '~/helpers/help_page_helper'; +import PushProtections from './push_protections.vue'; +import MergeProtections from './merge_protections.vue'; + +export const i18n = { + protections: s__('BranchRules|Protections'), + protectionsHelpText: s__( + 'BranchRules|Keep stable branches secure and force developers to use merge requests. %{linkStart}What are protected branches?%{linkEnd}', + ), +}; + +export default { + name: 'BranchProtections', + i18n, + components: { + GlSprintf, + GlLink, + PushProtections, + MergeProtections, + }, + protectedBranchesHelpPath: helpPagePath('user/project/protected_branches'), + props: { + protections: { + type: Object, + required: true, + }, + }, +}; +</script> + +<template> + <div> + <h4 class="gl-border-t gl-pt-4">{{ $options.i18n.protections }}</h4> + + <div data-testid="protections-help-text"> + <gl-sprintf :message="$options.i18n.protectionsHelpText"> + <template #link="{ content }"> + <gl-link :href="$options.protectedBranchesHelpPath">{{ content }}</gl-link> + </template> + </gl-sprintf> + </div> + + <push-protections + class="gl-mt-5" + :members-allowed-to-push="protections.membersAllowedToPush" + :allow-force-push="protections.allowForcePush" + v-on="$listeners" + /> + + <merge-protections + :members-allowed-to-merge="protections.membersAllowedToMerge" + :require-code-owners-approval="protections.requireCodeOwnersApproval" + v-on="$listeners" + /> + </div> +</template> diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/merge_protections.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/merge_protections.vue new file mode 100644 index 00000000000..85f168af4a8 --- /dev/null +++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/merge_protections.vue @@ -0,0 +1,46 @@ +<script> +import { GlFormGroup, GlFormCheckbox } from '@gitlab/ui'; +import { s__ } from '~/locale'; + +export const i18n = { + allowedToMerge: s__('BranchRules|Allowed to merge'), + requireApprovalTitle: s__('BranchRules|Require approval from code owners.'), + requireApprovalHelpText: s__( + 'BranchRules|Reject code pushes that change files listed in the CODEOWNERS file.', + ), +}; + +export default { + name: 'BranchMergeProtections', + i18n, + components: { + GlFormGroup, + GlFormCheckbox, + }, + props: { + membersAllowedToMerge: { + type: Array, + required: true, + }, + requireCodeOwnersApproval: { + type: Boolean, + required: true, + }, + }, +}; +</script> + +<template> + <gl-form-group :label="$options.i18n.allowedToMerge"> + <!-- TODO: add multi-select-dropdown (https://gitlab.com/gitlab-org/gitlab/-/issues/362212) --> + + <gl-form-checkbox + class="gl-mt-5" + :checked="requireCodeOwnersApproval" + @change="$emit('change-require-code-owners-approval', $event)" + > + <span>{{ $options.i18n.requireApprovalTitle }}</span> + <template #help>{{ $options.i18n.requireApprovalHelpText }}</template> + </gl-form-checkbox> + </gl-form-group> +</template> diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/push_protections.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/push_protections.vue new file mode 100644 index 00000000000..541923bb735 --- /dev/null +++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/push_protections.vue @@ -0,0 +1,52 @@ +<script> +import { GlFormGroup, GlSprintf, GlLink, GlFormCheckbox } from '@gitlab/ui'; +import { s__ } from '~/locale'; +import { helpPagePath } from '~/helpers/help_page_helper'; + +export const i18n = { + allowedToPush: s__('BranchRules|Allowed to push'), + forcePushTitle: s__( + 'BranchRules|Allow all users with push access to %{linkStart}force push%{linkEnd}.', + ), +}; + +export default { + name: 'BranchPushProtections', + i18n, + components: { + GlFormGroup, + GlSprintf, + GlLink, + GlFormCheckbox, + }, + forcePushHelpPath: helpPagePath('topics/git/git_rebase', { anchor: 'force-push' }), + props: { + membersAllowedToPush: { + type: Array, + required: true, + }, + allowForcePush: { + type: Boolean, + required: true, + }, + }, +}; +</script> + +<template> + <gl-form-group :label="$options.i18n.allowedToPush"> + <!-- TODO: add multi-select-dropdown (https://gitlab.com/gitlab-org/gitlab/-/issues/362212) --> + + <gl-form-checkbox + class="gl-mt-5" + :checked="allowForcePush" + @change="$emit('change-allow-force-push', $event)" + > + <gl-sprintf :message="$options.i18n.forcePushTitle"> + <template #link="{ content }"> + <gl-link :href="$options.forcePushHelpPath">{{ content }}</gl-link> + </template> + </gl-sprintf> + </gl-form-checkbox> + </gl-form-group> +</template> |