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>2023-01-18 22:00:14 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-01-18 22:00:14 +0300
commit05f0ebba3a2c8ddf39e436f412dc2ab5bf1353b2 (patch)
tree11d0f2a6ec31c7793c184106cedc2ded3d9a2cc5 /app/assets/javascripts/projects
parentec73467c23693d0db63a797d10194da9e72a74af (diff)
Add latest changes from gitlab-org/gitlab@15-8-stable-eev15.8.0-rc42
Diffstat (limited to 'app/assets/javascripts/projects')
-rw-r--r--app/assets/javascripts/projects/commit/components/branches_dropdown.vue67
-rw-r--r--app/assets/javascripts/projects/commit/components/form_modal.vue13
-rw-r--r--app/assets/javascripts/projects/commit/components/projects_dropdown.vue57
-rw-r--r--app/assets/javascripts/projects/commits/index.js19
-rw-r--r--app/assets/javascripts/projects/merge_requests/components/report_abuse_dropdown_item.vue41
-rw-r--r--app/assets/javascripts/projects/merge_requests/index.js18
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue8
-rw-r--r--app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js4
-rw-r--r--app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue12
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>