diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-18 22:00:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-18 22:00:14 +0300 |
commit | 05f0ebba3a2c8ddf39e436f412dc2ab5bf1353b2 (patch) | |
tree | 11d0f2a6ec31c7793c184106cedc2ded3d9a2cc5 /app/assets/javascripts/projects | |
parent | ec73467c23693d0db63a797d10194da9e72a74af (diff) |
Add latest changes from gitlab-org/gitlab@15-8-stable-eev15.8.0-rc42
Diffstat (limited to 'app/assets/javascripts/projects')
9 files changed, 135 insertions, 104 deletions
diff --git a/app/assets/javascripts/projects/commit/components/branches_dropdown.vue b/app/assets/javascripts/projects/commit/components/branches_dropdown.vue index a037e721677..a1fc3f1a731 100644 --- a/app/assets/javascripts/projects/commit/components/branches_dropdown.vue +++ b/app/assets/javascripts/projects/commit/components/branches_dropdown.vue @@ -1,11 +1,5 @@ <script> -import { - GlDropdown, - GlSearchBoxByType, - GlDropdownItem, - GlDropdownText, - GlLoadingIcon, -} from '@gitlab/ui'; +import { GlCollapsibleListbox } from '@gitlab/ui'; import { mapActions, mapGetters, mapState } from 'vuex'; import { I18N_NO_RESULTS_MESSAGE, @@ -16,11 +10,7 @@ import { export default { name: 'BranchesDropdown', components: { - GlDropdown, - GlSearchBoxByType, - GlDropdownItem, - GlDropdownText, - GlLoadingIcon, + GlCollapsibleListbox, }, props: { value: { @@ -46,13 +36,16 @@ export default { }, computed: { ...mapGetters(['joinedBranches']), - ...mapState(['isFetching', 'branch', 'branches']), + ...mapState(['isFetching']), filteredResults() { const lowerCasedSearchTerm = this.searchTerm.toLowerCase(); return this.joinedBranches.filter((resultString) => resultString.toLowerCase().includes(lowerCasedSearchTerm), ); }, + listboxItems() { + return this.filteredResults.map((value) => ({ value, text: value })); + }, }, watch: { // Parent component can set the branch value (e.g. when the user selects a different project) @@ -68,10 +61,6 @@ export default { ...mapActions(['fetchBranches']), selectBranch(branch) { this.$emit('selectBranch', branch); - this.searchTerm = branch; // enables isSelected to work as expected - }, - isSelected(selectedBranch) { - return selectedBranch === this.branch; }, searchTermChanged(value) { this.searchTerm = value; @@ -81,36 +70,16 @@ export default { }; </script> <template> - <gl-dropdown :text="value" :header-text="$options.i18n.branchHeaderTitle"> - <gl-search-box-by-type - :value="searchTerm" - trim - autocomplete="off" - :debounce="250" - :placeholder="$options.i18n.branchSearchPlaceholder" - data-testid="dropdown-search-box" - @input="searchTermChanged" - /> - <gl-dropdown-item - v-for="branch in filteredResults" - v-show="!isFetching" - :key="branch" - :name="branch" - :is-checked="isSelected(branch)" - is-check-item - data-testid="dropdown-item" - @click="selectBranch(branch)" - > - {{ branch }} - </gl-dropdown-item> - <gl-dropdown-text v-show="isFetching" data-testid="dropdown-text-loading-icon"> - <gl-loading-icon size="sm" class="gl-mx-auto" /> - </gl-dropdown-text> - <gl-dropdown-text - v-if="!filteredResults.length && !isFetching" - data-testid="empty-result-message" - > - <span class="gl-text-gray-500">{{ $options.i18n.noResultsMessage }}</span> - </gl-dropdown-text> - </gl-dropdown> + <gl-collapsible-listbox + :header-text="$options.i18n.branchHeaderTitle" + :toggle-text="value" + :items="listboxItems" + searchable + :search-placeholder="$options.i18n.branchSearchPlaceholder" + :searching="isFetching" + :selected="value" + :no-results-text="$options.i18n.noResultsMessage" + @search="searchTermChanged" + @select="selectBranch" + /> </template> diff --git a/app/assets/javascripts/projects/commit/components/form_modal.vue b/app/assets/javascripts/projects/commit/components/form_modal.vue index 1febe8ceaab..b31ba4a100c 100644 --- a/app/assets/javascripts/projects/commit/components/form_modal.vue +++ b/app/assets/javascripts/projects/commit/components/form_modal.vue @@ -141,11 +141,7 @@ export default { :value="targetProjectId" /> - <projects-dropdown - class="gl-w-half" - :value="targetProjectName" - @selectProject="setSelectedProject" - /> + <projects-dropdown :value="targetProjectName" @selectProject="setSelectedProject" /> </gl-form-group> <gl-form-group @@ -155,12 +151,7 @@ export default { > <input id="start_branch" type="hidden" name="start_branch" :value="branch" /> - <branches-dropdown - class="gl-w-half" - :value="branch" - :blanked="isRevert" - @selectBranch="setBranch" - /> + <branches-dropdown :value="branch" :blanked="isRevert" @selectBranch="setBranch" /> </gl-form-group> <gl-form-checkbox diff --git a/app/assets/javascripts/projects/commit/components/projects_dropdown.vue b/app/assets/javascripts/projects/commit/components/projects_dropdown.vue index 6288bcdaad0..d43f5b99e2c 100644 --- a/app/assets/javascripts/projects/commit/components/projects_dropdown.vue +++ b/app/assets/javascripts/projects/commit/components/projects_dropdown.vue @@ -1,5 +1,5 @@ <script> -import { GlDropdown, GlSearchBoxByType, GlDropdownItem, GlDropdownText } from '@gitlab/ui'; +import { GlCollapsibleListbox } from '@gitlab/ui'; import { mapGetters, mapState } from 'vuex'; import { I18N_NO_RESULTS_MESSAGE, @@ -10,10 +10,7 @@ import { export default { name: 'ProjectsDropdown', components: { - GlDropdown, - GlSearchBoxByType, - GlDropdownItem, - GlDropdownText, + GlCollapsibleListbox, }, props: { value: { @@ -41,17 +38,20 @@ export default { project.name.toLowerCase().includes(lowerCasedFilterTerm), ); }, + listboxItems() { + return this.filteredResults.map(({ id, name }) => ({ value: id, text: name })); + }, selectedProject() { return this.sortedProjects.find((project) => project.id === this.targetProjectId) || {}; }, }, methods: { - selectProject(project) { - this.$emit('selectProject', project.id); - this.filterTerm = project.name; // when we select a project, we want the dropdown to filter to the selected project - }, - isSelected(selectedProject) { - return selectedProject === this.selectedProject; + selectProject(value) { + this.$emit('selectProject', value); + + // when we select a project, we want the dropdown to filter to the selected project + const project = this.listboxItems.find((x) => x.value === value); + this.filterTerm = project?.text || ''; }, filterTermChanged(value) { this.filterTerm = value; @@ -60,28 +60,15 @@ export default { }; </script> <template> - <gl-dropdown :text="selectedProject.name" :header-text="$options.i18n.projectHeaderTitle"> - <gl-search-box-by-type - :value="filterTerm" - trim - autocomplete="off" - :placeholder="$options.i18n.projectSearchPlaceholder" - data-testid="dropdown-search-box" - @input="filterTermChanged" - /> - <gl-dropdown-item - v-for="project in filteredResults" - :key="project.name" - :name="project.name" - :is-checked="isSelected(project)" - is-check-item - data-testid="dropdown-item" - @click="selectProject(project)" - > - {{ project.name }} - </gl-dropdown-item> - <gl-dropdown-text v-if="!filteredResults.length" data-testid="empty-result-message"> - <span class="gl-text-gray-500">{{ $options.i18n.noResultsMessage }}</span> - </gl-dropdown-text> - </gl-dropdown> + <gl-collapsible-listbox + :header-text="$options.i18n.projectHeaderTitle" + :items="listboxItems" + searchable + :search-placeholder="$options.i18n.projectSearchPlaceholder" + :selected="selectedProject.id" + :toggle-text="selectedProject.name" + :no-results-text="$options.i18n.noResultsMessage" + @search="filterTermChanged" + @select="selectProject" + /> </template> diff --git a/app/assets/javascripts/projects/commits/index.js b/app/assets/javascripts/projects/commits/index.js index 53169f689c9..f56884f605f 100644 --- a/app/assets/javascripts/projects/commits/index.js +++ b/app/assets/javascripts/projects/commits/index.js @@ -33,20 +33,31 @@ export const initCommitsRefSwitcher = () => { if (!el) return false; - const { projectId, ref, commitsPath } = el.dataset; + const { projectId, ref, commitsPath, refType } = el.dataset; const commitsPathPrefix = commitsPath.match(COMMITS_PATH_REGEX)?.[0]; - + const useSymbolicRefNames = Boolean(refType); return new Vue({ el, render(createElement) { return createElement(RefSelector, { props: { projectId, - value: ref, + value: useSymbolicRefNames ? `refs/${refType}/${ref}` : ref, + useSymbolicRefNames, + refType, }, on: { input(selected) { - visitUrl(`${commitsPathPrefix}/${selected}`); + if (useSymbolicRefNames) { + const matches = selected.match(/refs\/(heads|tags)\/(.+)/); + if (matches) { + visitUrl(`${commitsPathPrefix}/${matches[2]}?ref_type=${matches[1]}`); + } else { + visitUrl(`${commitsPathPrefix}/${selected}`); + } + } else { + visitUrl(`${commitsPathPrefix}/${selected}`); + } }, }, }); diff --git a/app/assets/javascripts/projects/merge_requests/components/report_abuse_dropdown_item.vue b/app/assets/javascripts/projects/merge_requests/components/report_abuse_dropdown_item.vue new file mode 100644 index 00000000000..31890249f41 --- /dev/null +++ b/app/assets/javascripts/projects/merge_requests/components/report_abuse_dropdown_item.vue @@ -0,0 +1,41 @@ +<script> +import { GlDropdownItem } from '@gitlab/ui'; +import { MountingPortal } from 'portal-vue'; +import { s__ } from '~/locale'; + +import AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue'; + +export default { + name: 'ReportAbuseDropdownItem', + components: { + GlDropdownItem, + MountingPortal, + AbuseCategorySelector, + }, + i18n: { + reportAbuse: s__('ReportAbuse|Report abuse to administrator'), + }, + data() { + return { + open: false, + }; + }, + methods: { + openDrawer() { + this.open = true; + }, + closeDrawer() { + this.open = false; + }, + }, +}; +</script> +<template> + <span> + <gl-dropdown-item @click="openDrawer">{{ $options.i18n.reportAbuse }}</gl-dropdown-item> + + <mounting-portal mount-to="#js-report-abuse-drawer" name="abuse-category-selector" append> + <abuse-category-selector :show-drawer="open" @close-drawer="closeDrawer" /> + </mounting-portal> + </span> +</template> diff --git a/app/assets/javascripts/projects/merge_requests/index.js b/app/assets/javascripts/projects/merge_requests/index.js new file mode 100644 index 00000000000..25a70121d68 --- /dev/null +++ b/app/assets/javascripts/projects/merge_requests/index.js @@ -0,0 +1,18 @@ +import Vue from 'vue'; +import ReportAbuseDropdownItem from './components/report_abuse_dropdown_item.vue'; + +export const initReportAbuse = () => { + const el = document.getElementById('js-report-abuse-dropdown-item'); + + if (!el) return false; + + const { reportAbusePath, reportedUserId, reportedFromUrl } = el.dataset; + + return new Vue({ + el, + provide: { reportAbusePath, reportedUserId, reportedFromUrl }, + render(createElement) { + return createElement(ReportAbuseDropdownItem); + }, + }); +}; diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue b/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue index 626ed67c466..6260c8dd4d0 100644 --- a/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue +++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue @@ -56,6 +56,7 @@ export default { }, update({ project: { branchRules } }) { const branchRule = branchRules.nodes.find((rule) => rule.name === this.branch); + this.branchRule = branchRule; this.branchProtection = branchRule?.branchProtection; this.approvalRules = branchRule?.approvalRules; this.statusChecks = branchRule?.externalStatusChecks?.nodes || []; @@ -69,6 +70,7 @@ export default { branchProtection: {}, approvalRules: {}, statusChecks: [], + branchRule: {}, matchingBranchesCount: null, }; }, @@ -88,12 +90,12 @@ export default { }, allowedToMergeHeader() { return sprintf(this.$options.i18n.allowedToMergeHeader, { - total: this.mergeAccessLevels.total, + total: this.mergeAccessLevels?.total || 0, }); }, allowedToPushHeader() { return sprintf(this.$options.i18n.allowedToPushHeader, { - total: this.pushAccessLevels.total, + total: this.pushAccessLevels?.total || 0, }); }, approvalsHeader() { @@ -141,7 +143,7 @@ export default { <template> <gl-loading-icon v-if="$apollo.loading" /> - <div v-else-if="!branchProtection">{{ $options.i18n.noData }}</div> + <div v-else-if="!branchRule">{{ $options.i18n.noData }}</div> <div v-else> <strong data-testid="branch-title">{{ branchTitle }}</strong> <p v-if="!allBranches" class="gl-mb-3 gl-text-gray-400"> diff --git a/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js b/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js index 5ca864a412b..54120b3525d 100644 --- a/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js +++ b/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js @@ -4,6 +4,10 @@ import SharedRunnersToggle from '~/projects/settings/components/shared_runners_t export default (containerId = 'toggle-shared-runners-form') => { const containerEl = document.getElementById(containerId); + if (!containerEl) { + return null; + } + const { isDisabledAndUnoverridable, isEnabled, diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue b/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue index 41947834bdb..4a24df4b0dc 100644 --- a/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue +++ b/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue @@ -5,6 +5,7 @@ import { getAccessLevels } from '../../../utils'; export const i18n = { defaultLabel: s__('BranchRules|default'), + protectedLabel: s__('BranchRules|protected'), detailsButtonLabel: s__('BranchRules|Details'), allowForcePush: s__('BranchRules|Allowed to force push'), codeOwnerApprovalRequired: s__('BranchRules|Requires CODEOWNERS approval'), @@ -62,6 +63,9 @@ export default { isWildcard() { return this.name.includes('*'); }, + isProtected() { + return Boolean(this.branchProtection); + }, hasApprovalDetails() { return this.approvalDetails.length; }, @@ -105,10 +109,10 @@ export default { if (this.isWildcard) { approvalDetails.push(this.matchingBranchesText); } - if (this.branchProtection.allowForcePush) { + if (this.branchProtection?.allowForcePush) { approvalDetails.push(this.$options.i18n.allowForcePush); } - if (this.branchProtection.codeOwnerApprovalRequired) { + if (this.branchProtection?.codeOwnerApprovalRequired) { approvalDetails.push(this.$options.i18n.codeOwnerApprovalRequired); } if (this.statusChecksTotal) { @@ -154,6 +158,10 @@ export default { $options.i18n.defaultLabel }}</gl-badge> + <gl-badge v-if="isProtected" variant="success" size="sm" class="gl-ml-2">{{ + $options.i18n.protectedLabel + }}</gl-badge> + <ul v-if="hasApprovalDetails" class="gl-pl-6 gl-mt-2 gl-mb-0 gl-text-gray-500"> <li v-for="(detail, index) in approvalDetails" :key="index">{{ detail }}</li> </ul> |