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:
Diffstat (limited to 'app/assets/javascripts/projects')
-rw-r--r--app/assets/javascripts/projects/commit/components/commit_options_dropdown.vue160
-rw-r--r--app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue45
-rw-r--r--app/assets/javascripts/projects/commit_box/info/components/commit_refs.vue134
-rw-r--r--app/assets/javascripts/projects/commit_box/info/components/refs_list.vue112
-rw-r--r--app/assets/javascripts/projects/commit_box/info/constants.js18
-rw-r--r--app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_containing_branches.query.graphql10
-rw-r--r--app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_containing_tags.query.graphql10
-rw-r--r--app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_references.query.graphql19
-rw-r--r--app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql43
-rw-r--r--app/assets/javascripts/projects/commit_box/info/graphql/queries/get_pipeline_stages.query.graphql19
-rw-r--r--app/assets/javascripts/projects/commit_box/info/index.js6
-rw-r--r--app/assets/javascripts/projects/commit_box/info/init_commit_references.js32
-rw-r--r--app/assets/javascripts/projects/commit_box/info/load_branches.js24
-rw-r--r--app/assets/javascripts/projects/compare/components/repo_dropdown.vue55
-rw-r--r--app/assets/javascripts/projects/new/components/app.vue8
-rw-r--r--app/assets/javascripts/projects/project_new.js2
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/components/edit/branch_dropdown.vue2
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js2
-rw-r--r--app/assets/javascripts/projects/settings/components/access_dropdown.vue31
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue4
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue34
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/index.js2
22 files changed, 578 insertions, 194 deletions
diff --git a/app/assets/javascripts/projects/commit/components/commit_options_dropdown.vue b/app/assets/javascripts/projects/commit/components/commit_options_dropdown.vue
index a4edc988d67..7c00ce45b3a 100644
--- a/app/assets/javascripts/projects/commit/components/commit_options_dropdown.vue
+++ b/app/assets/javascripts/projects/commit/components/commit_options_dropdown.vue
@@ -1,14 +1,17 @@
<script>
-import { GlDropdown, GlDropdownItem, GlDropdownDivider, GlDropdownSectionHeader } from '@gitlab/ui';
+import { GlDisclosureDropdownGroup, GlDisclosureDropdown } from '@gitlab/ui';
+import { s__, __ } from '~/locale';
import { OPEN_REVERT_MODAL, OPEN_CHERRY_PICK_MODAL } from '../constants';
import eventHub from '../event_hub';
export default {
+ i18n: {
+ gitlabTag: s__('CreateTag|Tag'),
+ },
+
components: {
- GlDropdown,
- GlDropdownItem,
- GlDropdownDivider,
- GlDropdownSectionHeader,
+ GlDisclosureDropdown,
+ GlDisclosureDropdownGroup,
},
inject: {
newProjectTagPath: {
@@ -43,66 +46,117 @@ export default {
showDivider() {
return this.canRevert || this.canCherryPick || this.canTag;
},
+ cherryPickItem() {
+ return {
+ text: s__('ChangeTypeAction|Cherry-pick'),
+ extraAttrs: {
+ 'data-testid': 'cherry-pick-link',
+ 'data-qa-selector': 'cherry_pick_button',
+ },
+ action: () => this.showModal(OPEN_CHERRY_PICK_MODAL),
+ };
+ },
+
+ revertLinkItem() {
+ return {
+ text: s__('ChangeTypeAction|Revert'),
+ extraAttrs: {
+ 'data-testid': 'revert-link',
+ 'data-qa-selector': 'revert_button',
+ },
+ action: () => this.showModal(OPEN_REVERT_MODAL),
+ };
+ },
+
+ tagLinkItem() {
+ return {
+ text: s__('CreateTag|Tag'),
+ href: this.newProjectTagPath,
+ extraAttrs: {
+ 'data-testid': 'tag-link',
+ },
+ };
+ },
+ plainDiffItem() {
+ return {
+ text: s__('DownloadCommit|Plain Diff'),
+ href: this.plainDiffPath,
+ extraAttrs: {
+ download: '',
+ rel: 'nofollow',
+ 'data-testid': 'plain-diff-link',
+ 'data-qa-selector': 'plain_diff',
+ },
+ };
+ },
+ patchesItem() {
+ return {
+ text: __('Patches'),
+ href: this.emailPatchesPath,
+ extraAttrs: {
+ download: '',
+ rel: 'nofollow',
+ 'data-testid': 'email-patches-link',
+ 'data-qa-selector': 'email_patches',
+ },
+ };
+ },
+
+ downloadsGroup() {
+ const items = [];
+ if (this.canEmailPatches) {
+ items.push(this.patchesItem);
+ }
+ items.push(this.plainDiffItem);
+ return {
+ name: __('Downloads'),
+ items,
+ };
+ },
+
+ optionsGroup() {
+ const items = [];
+ if (this.canRevert) {
+ items.push(this.revertLinkItem);
+ }
+ if (this.canCherryPick) {
+ items.push(this.cherryPickItem);
+ }
+ if (this.canTag) {
+ items.push(this.tagLinkItem);
+ }
+ return {
+ items,
+ };
+ },
},
+
methods: {
showModal(modalId) {
eventHub.$emit(modalId);
},
+ closeDropdown() {
+ this.$refs.userDropdown.close();
+ },
},
- openRevertModal: OPEN_REVERT_MODAL,
- openCherryPickModal: OPEN_CHERRY_PICK_MODAL,
};
</script>
<template>
- <gl-dropdown
- :text="__('Options')"
+ <gl-disclosure-dropdown
+ ref="userDropdown"
+ :toggle-text="__('Options')"
right
data-testid="commit-options-dropdown"
data-qa-selector="options_button"
- class="gl-xs-w-full"
+ class="gl-xs-w-full gl-line-height-20"
>
- <gl-dropdown-item
- v-if="canRevert"
- data-testid="revert-link"
- data-qa-selector="revert_button"
- @click="showModal($options.openRevertModal)"
- >
- {{ s__('ChangeTypeAction|Revert') }}
- </gl-dropdown-item>
- <gl-dropdown-item
- v-if="canCherryPick"
- data-testid="cherry-pick-link"
- data-qa-selector="cherry_pick_button"
- @click="showModal($options.openCherryPickModal)"
- >
- {{ s__('ChangeTypeAction|Cherry-pick') }}
- </gl-dropdown-item>
- <gl-dropdown-item v-if="canTag" :href="newProjectTagPath" data-testid="tag-link">
- {{ s__('CreateTag|Tag') }}
- </gl-dropdown-item>
- <gl-dropdown-divider v-if="showDivider" />
- <gl-dropdown-section-header>
- {{ __('Download') }}
- </gl-dropdown-section-header>
- <gl-dropdown-item
- v-if="canEmailPatches"
- :href="emailPatchesPath"
- download
- rel="nofollow"
- data-testid="email-patches-link"
- data-qa-selector="email_patches"
- >
- {{ __('Patches') }}
- </gl-dropdown-item>
- <gl-dropdown-item
- :href="plainDiffPath"
- download
- rel="nofollow"
- data-testid="plain-diff-link"
- data-qa-selector="plain_diff"
- >
- {{ s__('DownloadCommit|Plain Diff') }}
- </gl-dropdown-item>
- </gl-dropdown>
+ <gl-disclosure-dropdown-group :group="optionsGroup" @action="closeDropdown" />
+
+ <gl-disclosure-dropdown-group
+ :bordered="showDivider"
+ :group="downloadsGroup"
+ @action="closeDropdown"
+ />
+ </gl-disclosure-dropdown>
</template>
diff --git a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue
index 54d13ecc9c8..84e7edb48c1 100644
--- a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue
+++ b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue
@@ -7,10 +7,12 @@ import {
toggleQueryPollingByVisibility,
} from '~/pipelines/components/graph/utils';
import { keepLatestDownstreamPipelines } from '~/pipelines/components/parsing_utils';
+import GraphqlPipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/graphql_pipeline_mini_graph.vue';
import PipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/pipeline_mini_graph.vue';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import getLinkedPipelinesQuery from '~/pipelines/graphql/queries/get_linked_pipelines.query.graphql';
+import getPipelineStagesQuery from '~/pipelines/graphql/queries/get_pipeline_stages.query.graphql';
import { formatStages } from '../utils';
-import getLinkedPipelinesQuery from '../graphql/queries/get_linked_pipelines.query.graphql';
-import getPipelineStagesQuery from '../graphql/queries/get_pipeline_stages.query.graphql';
import { COMMIT_BOX_POLL_INTERVAL } from '../constants';
export default {
@@ -21,8 +23,10 @@ export default {
},
components: {
GlLoadingIcon,
+ GraphqlPipelineMiniGraph,
PipelineMiniGraph,
},
+ mixins: [glFeatureFlagsMixin()],
inject: {
fullPath: {
default: '',
@@ -47,15 +51,15 @@ export default {
},
query: getLinkedPipelinesQuery,
pollInterval: COMMIT_BOX_POLL_INTERVAL,
+ skip() {
+ return !this.fullPath || !this.iid || this.isUsingPipelineMiniGraphQueries;
+ },
variables() {
return {
fullPath: this.fullPath,
iid: this.iid,
};
},
- skip() {
- return !this.fullPath || !this.iid;
- },
update({ project }) {
return project?.pipeline;
},
@@ -69,6 +73,9 @@ export default {
},
query: getPipelineStagesQuery,
pollInterval: COMMIT_BOX_POLL_INTERVAL,
+ skip() {
+ return this.isUsingPipelineMiniGraphQueries;
+ },
variables() {
return {
fullPath: this.fullPath,
@@ -95,6 +102,9 @@ export default {
const downstream = this.pipeline?.downstream?.nodes;
return keepLatestDownstreamPipelines(downstream);
},
+ isUsingPipelineMiniGraphQueries() {
+ return this.glFeatures.ciGraphqlPipelineMiniGraph;
+ },
pipelinePath() {
return this.pipeline?.path ?? '';
},
@@ -128,13 +138,22 @@ export default {
<template>
<div>
<gl-loading-icon v-if="$apollo.queries.pipeline.loading" />
- <pipeline-mini-graph
- v-else
- data-testid="commit-box-pipeline-mini-graph"
- :downstream-pipelines="downstreamPipelines"
- :pipeline-path="pipelinePath"
- :stages="formattedStages"
- :upstream-pipeline="upstreamPipeline"
- />
+ <template v-else>
+ <graphql-pipeline-mini-graph
+ v-if="isUsingPipelineMiniGraphQueries"
+ data-testid="commit-box-pipeline-mini-graph"
+ :pipeline-etag="graphqlResourceEtag"
+ :full-path="fullPath"
+ :iid="iid"
+ />
+ <pipeline-mini-graph
+ v-else
+ data-testid="commit-box-pipeline-mini-graph"
+ :downstream-pipelines="downstreamPipelines"
+ :pipeline-path="pipelinePath"
+ :stages="formattedStages"
+ :upstream-pipeline="upstreamPipeline"
+ />
+ </template>
</div>
</template>
diff --git a/app/assets/javascripts/projects/commit_box/info/components/commit_refs.vue b/app/assets/javascripts/projects/commit_box/info/components/commit_refs.vue
new file mode 100644
index 00000000000..25af4cc8082
--- /dev/null
+++ b/app/assets/javascripts/projects/commit_box/info/components/commit_refs.vue
@@ -0,0 +1,134 @@
+<script>
+import { createAlert } from '~/alert';
+import { joinPaths } from '~/lib/utils/url_utility';
+import commitReferencesQuery from '../graphql/queries/commit_references.query.graphql';
+import containingBranchesQuery from '../graphql/queries/commit_containing_branches.query.graphql';
+import containingTagsQuery from '../graphql/queries/commit_containing_tags.query.graphql';
+import {
+ BRANCHES,
+ TAGS,
+ FETCH_CONTAINING_REFS_EVENT,
+ FETCH_COMMIT_REFERENCES_ERROR,
+ BRANCHES_REF_TYPE,
+ TAGS_REF_TYPE,
+} from '../constants';
+import RefsList from './refs_list.vue';
+
+export default {
+ name: 'CommitRefs',
+ components: {
+ RefsList,
+ },
+ inject: ['fullPath', 'commitSha'],
+ apollo: {
+ project: {
+ query: commitReferencesQuery,
+ variables() {
+ return this.queryVariables;
+ },
+ update({
+ project: {
+ commitReferences: { tippingTags, tippingBranches, containingBranches, containingTags },
+ },
+ }) {
+ this.tippingTags = tippingTags.names;
+ this.tippingBranches = tippingBranches.names;
+ this.hasContainingBranches = Boolean(containingBranches.names.length);
+ this.hasContainingTags = Boolean(containingTags.names.length);
+ },
+ error() {
+ createAlert({
+ message: this.$options.i18n.errorMessage,
+ captureError: true,
+ });
+ },
+ },
+ },
+ data() {
+ return {
+ containingTags: [],
+ containingBranches: [],
+ tippingTags: [],
+ tippingBranches: [],
+ hasContainingBranches: false,
+ hasContainingTags: false,
+ };
+ },
+ computed: {
+ hasBranches() {
+ return this.tippingBranches.length || this.hasContainingBranches;
+ },
+ hasTags() {
+ return this.tippingTags.length || this.hasContainingTags;
+ },
+ queryVariables() {
+ return {
+ fullPath: this.fullPath,
+ commitSha: this.commitSha,
+ };
+ },
+ commitsUrlPart() {
+ const urlPart = joinPaths(gon.relative_url_root || '', `/${this.fullPath}`, `/-/commits/`);
+ return urlPart;
+ },
+ },
+ methods: {
+ async fetchContainingRefs({ query, namespace }) {
+ try {
+ const { data } = await this.$apollo.query({
+ query,
+ variables: this.queryVariables,
+ });
+ this[namespace] = data.project.commitReferences[namespace].names;
+ return data.project.commitReferences[namespace].names;
+ } catch {
+ return createAlert({
+ message: this.$options.i18n.errorMessage,
+ captureError: true,
+ });
+ }
+ },
+ fetchContainingBranches() {
+ this.fetchContainingRefs({ query: containingBranchesQuery, namespace: 'containingBranches' });
+ },
+ fetchContainingTags() {
+ this.fetchContainingRefs({ query: containingTagsQuery, namespace: 'containingTags' });
+ },
+ },
+ i18n: {
+ branches: BRANCHES,
+ tags: TAGS,
+ errorMessage: FETCH_COMMIT_REFERENCES_ERROR,
+ },
+ FETCH_CONTAINING_REFS_EVENT,
+ BRANCHES_REF_TYPE,
+ TAGS_REF_TYPE,
+};
+</script>
+
+<template>
+ <div class="gl-ml-7">
+ <refs-list
+ v-if="hasBranches"
+ :has-containing-refs="hasContainingBranches"
+ :is-loading="$apollo.queries.project.loading"
+ :tipping-refs="tippingBranches"
+ :containing-refs="containingBranches"
+ :namespace="$options.i18n.branches"
+ :url-part="commitsUrlPart"
+ :ref-type="$options.BRANCHES_REF_TYPE"
+ @[$options.FETCH_CONTAINING_REFS_EVENT]="fetchContainingBranches"
+ />
+ <refs-list
+ v-if="hasTags"
+ :has-containing-refs="hasContainingTags"
+ :is-loading="$apollo.queries.project.loading"
+ :tipping-refs="tippingTags"
+ :containing-refs="containingTags"
+ :namespace="$options.i18n.tags"
+ :url-part="commitsUrlPart"
+ :ref-type="$options.TAGS_REF_TYPE"
+ @[$options.FETCH_CONTAINING_REFS_EVENT]="fetchContainingTags"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/commit_box/info/components/refs_list.vue b/app/assets/javascripts/projects/commit_box/info/components/refs_list.vue
new file mode 100644
index 00000000000..8ceab9cb60b
--- /dev/null
+++ b/app/assets/javascripts/projects/commit_box/info/components/refs_list.vue
@@ -0,0 +1,112 @@
+<script>
+import { GlCollapse, GlBadge, GlButton, GlIcon, GlSkeletonLoader } from '@gitlab/ui';
+import { CONTAINING_COMMIT, FETCH_CONTAINING_REFS_EVENT } from '../constants';
+
+export default {
+ name: 'RefsList',
+ components: {
+ GlCollapse,
+ GlSkeletonLoader,
+ GlBadge,
+ GlButton,
+ GlIcon,
+ },
+ props: {
+ urlPart: {
+ type: String,
+ required: true,
+ },
+ refType: {
+ type: String,
+ required: true,
+ },
+ containingRefs: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ tippingRefs: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ namespace: {
+ type: String,
+ required: true,
+ },
+ hasContainingRefs: {
+ type: Boolean,
+ required: true,
+ },
+ isLoading: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isContainingRefsVisible: false,
+ };
+ },
+ computed: {
+ collapseIcon() {
+ return this.isContainingRefsVisible ? 'chevron-down' : 'chevron-right';
+ },
+ isLoadingRefs() {
+ return this.isLoading && !this.containingRefs.length;
+ },
+ },
+ methods: {
+ toggleCollapse() {
+ this.isContainingRefsVisible = !this.isContainingRefsVisible;
+ },
+ showRefs() {
+ this.toggleCollapse();
+ this.$emit(FETCH_CONTAINING_REFS_EVENT);
+ },
+ getRefUrl(ref) {
+ return `${this.urlPart}${ref}?ref_type=${this.refType}`;
+ },
+ },
+ i18n: {
+ containingCommit: CONTAINING_COMMIT,
+ },
+};
+</script>
+
+<template>
+ <div class="gl-pt-4">
+ <span data-testid="title" class="gl-mr-2">{{ namespace }}</span>
+ <gl-badge
+ v-for="ref in tippingRefs"
+ :key="ref"
+ :href="getRefUrl(ref)"
+ class="gl-mt-2 gl-mr-2"
+ size="sm"
+ >{{ ref }}</gl-badge
+ >
+ <gl-button
+ v-if="hasContainingRefs"
+ class="gl-mr-2 gl-font-sm!"
+ variant="link"
+ size="small"
+ @click="showRefs"
+ >
+ <gl-icon :name="collapseIcon" :size="14" />
+ {{ namespace }} {{ $options.i18n.containingCommit }}
+ </gl-button>
+ <gl-collapse :visible="isContainingRefsVisible">
+ <gl-skeleton-loader v-if="isLoadingRefs" :lines="1" />
+ <template v-else>
+ <gl-badge
+ v-for="ref in containingRefs"
+ :key="ref"
+ :href="getRefUrl(ref)"
+ class="gl-mt-3 gl-mr-2"
+ size="sm"
+ >{{ ref }}</gl-badge
+ >
+ </template>
+ </gl-collapse>
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/commit_box/info/constants.js b/app/assets/javascripts/projects/commit_box/info/constants.js
index be0bf715314..4b74fbe19e1 100644
--- a/app/assets/javascripts/projects/commit_box/info/constants.js
+++ b/app/assets/javascripts/projects/commit_box/info/constants.js
@@ -1,7 +1,23 @@
-import { __ } from '~/locale';
+import { __, s__ } from '~/locale';
export const COMMIT_BOX_POLL_INTERVAL = 10000;
export const PIPELINE_STATUS_FETCH_ERROR = __(
'There was a problem fetching the latest pipeline status.',
);
+
+export const BRANCHES = s__('Commit|Branches');
+
+export const TAGS = s__('Commit|Tags');
+
+export const CONTAINING_COMMIT = s__('Commit|containing commit');
+
+export const FETCH_CONTAINING_REFS_EVENT = 'fetch-containing-refs';
+
+export const FETCH_COMMIT_REFERENCES_ERROR = s__(
+ 'Commit|There was an error fetching the commit references. Please try again later.',
+);
+
+export const BRANCHES_REF_TYPE = 'heads';
+
+export const TAGS_REF_TYPE = 'tags';
diff --git a/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_containing_branches.query.graphql b/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_containing_branches.query.graphql
new file mode 100644
index 00000000000..ea74efdbc46
--- /dev/null
+++ b/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_containing_branches.query.graphql
@@ -0,0 +1,10 @@
+query CommitContainingBranches($fullPath: ID!, $commitSha: String!) {
+ project(fullPath: $fullPath) {
+ id
+ commitReferences(commitSha: $commitSha) {
+ containingBranches(excludeTipped: true) {
+ names
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_containing_tags.query.graphql b/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_containing_tags.query.graphql
new file mode 100644
index 00000000000..d736dc3ab66
--- /dev/null
+++ b/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_containing_tags.query.graphql
@@ -0,0 +1,10 @@
+query CommitContainingTags($fullPath: ID!, $commitSha: String!) {
+ project(fullPath: $fullPath) {
+ id
+ commitReferences(commitSha: $commitSha) {
+ containingTags(excludeTipped: true) {
+ names
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_references.query.graphql b/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_references.query.graphql
new file mode 100644
index 00000000000..71d911c2acc
--- /dev/null
+++ b/app/assets/javascripts/projects/commit_box/info/graphql/queries/commit_references.query.graphql
@@ -0,0 +1,19 @@
+query CommitReferences($fullPath: ID!, $commitSha: String!) {
+ project(fullPath: $fullPath) {
+ id
+ commitReferences(commitSha: $commitSha) {
+ containingBranches(excludeTipped: true, limit: 1) {
+ names
+ }
+ containingTags(excludeTipped: true, limit: 1) {
+ names
+ }
+ tippingBranches {
+ names
+ }
+ tippingTags {
+ names
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql b/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql
deleted file mode 100644
index 9257cc7de7b..00000000000
--- a/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_linked_pipelines.query.graphql
+++ /dev/null
@@ -1,43 +0,0 @@
-query getLinkedPipelines($fullPath: ID!, $iid: ID!) {
- project(fullPath: $fullPath) {
- id
- pipeline(iid: $iid) {
- id
- path
- downstream {
- nodes {
- id
- path
- project {
- id
- name
- }
- detailedStatus {
- id
- group
- icon
- label
- }
- sourceJob {
- id
- retried
- }
- }
- }
- upstream {
- id
- path
- project {
- id
- name
- }
- detailedStatus {
- id
- group
- icon
- label
- }
- }
- }
- }
-}
diff --git a/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_pipeline_stages.query.graphql b/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_pipeline_stages.query.graphql
deleted file mode 100644
index 69a29947b16..00000000000
--- a/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_pipeline_stages.query.graphql
+++ /dev/null
@@ -1,19 +0,0 @@
-query getPipelineStages($fullPath: ID!, $iid: ID!) {
- project(fullPath: $fullPath) {
- id
- pipeline(iid: $iid) {
- id
- stages {
- nodes {
- id
- name
- detailedStatus {
- id
- icon
- group
- }
- }
- }
- }
- }
-}
diff --git a/app/assets/javascripts/projects/commit_box/info/index.js b/app/assets/javascripts/projects/commit_box/info/index.js
index 7c4b76fd62f..8f09c8e1e11 100644
--- a/app/assets/javascripts/projects/commit_box/info/index.js
+++ b/app/assets/javascripts/projects/commit_box/info/index.js
@@ -1,12 +1,10 @@
import { fetchCommitMergeRequests } from '~/commit_merge_requests';
import { initCommitPipelineMiniGraph } from './init_commit_pipeline_mini_graph';
-import { loadBranches } from './load_branches';
import initCommitPipelineStatus from './init_commit_pipeline_status';
+import initCommitReferences from './init_commit_references';
export const initCommitBoxInfo = () => {
// Display commit related branches
- loadBranches();
-
// Related merge requests to this commit
fetchCommitMergeRequests();
@@ -14,4 +12,6 @@ export const initCommitBoxInfo = () => {
initCommitPipelineMiniGraph();
initCommitPipelineStatus();
+
+ initCommitReferences();
};
diff --git a/app/assets/javascripts/projects/commit_box/info/init_commit_references.js b/app/assets/javascripts/projects/commit_box/info/init_commit_references.js
new file mode 100644
index 00000000000..c8497187211
--- /dev/null
+++ b/app/assets/javascripts/projects/commit_box/info/init_commit_references.js
@@ -0,0 +1,32 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import CommitBranches from './components/commit_refs.vue';
+
+Vue.use(VueApollo);
+
+const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+});
+
+export default (selector = 'js-commit-branches-and-tags') => {
+ const el = document.getElementById(selector);
+
+ if (!el) {
+ return false;
+ }
+
+ const { fullPath, commitSha } = el.dataset;
+
+ return new Vue({
+ el,
+ apolloProvider,
+ provide: {
+ fullPath,
+ commitSha,
+ },
+ render(createElement) {
+ return createElement(CommitBranches);
+ },
+ });
+};
diff --git a/app/assets/javascripts/projects/commit_box/info/load_branches.js b/app/assets/javascripts/projects/commit_box/info/load_branches.js
deleted file mode 100644
index 8333e70b951..00000000000
--- a/app/assets/javascripts/projects/commit_box/info/load_branches.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import axios from 'axios';
-import { sanitize } from '~/lib/dompurify';
-import { __ } from '~/locale';
-import { initDetailsButton } from './init_details_button';
-
-export const loadBranches = (containerSelector = '.js-commit-box-info') => {
- const containerEl = document.querySelector(containerSelector);
- if (!containerEl) {
- return;
- }
-
- const { commitPath } = containerEl.dataset;
- const branchesEl = containerEl.querySelector('.commit-info.branches');
- axios
- .get(commitPath)
- .then(({ data }) => {
- branchesEl.innerHTML = sanitize(data);
-
- initDetailsButton();
- })
- .catch(() => {
- branchesEl.textContent = __('Failed to load branches. Please try again.');
- });
-};
diff --git a/app/assets/javascripts/projects/compare/components/repo_dropdown.vue b/app/assets/javascripts/projects/compare/components/repo_dropdown.vue
index c00e75db722..4c0b5d0b1f6 100644
--- a/app/assets/javascripts/projects/compare/components/repo_dropdown.vue
+++ b/app/assets/javascripts/projects/compare/components/repo_dropdown.vue
@@ -1,11 +1,9 @@
<script>
-import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
+import { GlCollapsibleListbox } from '@gitlab/ui';
export default {
components: {
- GlDropdown,
- GlDropdownItem,
- GlSearchBoxByType,
+ GlCollapsibleListbox,
},
props: {
paramsName: {
@@ -25,6 +23,7 @@ export default {
data() {
return {
searchTerm: '',
+ selectedProjectId: this.selectedProject.id,
};
},
computed: {
@@ -32,49 +31,45 @@ export default {
return this.projects === null;
},
filteredRepos() {
- const lowerCaseSearchTerm = this.searchTerm.toLowerCase();
+ if (this.disableRepoDropdown) return [];
- return this?.projects.filter(({ name }) => name.toLowerCase().includes(lowerCaseSearchTerm));
+ const lowerCaseSearchTerm = this.searchTerm.toLowerCase();
+ return this.projects
+ .filter(({ name }) => name.toLowerCase().includes(lowerCaseSearchTerm))
+ .map((project) => ({ text: project.name, value: project.id }));
},
inputName() {
return `${this.paramsName}_project_id`;
},
},
methods: {
- onClick(project) {
- this.emitTargetProject(project);
- },
- emitTargetProject(project) {
+ emitTargetProject(projectId) {
+ if (this.disableRepoDropdown) return;
+ const project = this.projects.find(({ id }) => id === projectId);
this.$emit('selectProject', { direction: this.paramsName, project });
},
+ onSearch(searchTerm) {
+ this.searchTerm = searchTerm;
+ },
},
};
</script>
<template>
<div>
- <input type="hidden" :name="inputName" :value="selectedProject.id" />
- <gl-dropdown
- :text="selectedProject.name"
+ <input type="hidden" :name="inputName" :value="selectedProjectId" />
+ <gl-collapsible-listbox
+ v-model="selectedProjectId"
+ :toggle-text="selectedProject.name"
:header-text="s__(`CompareRevisions|Select target project`)"
- class="gl-w-full gl-font-monospace"
+ class="gl-font-monospace"
toggle-class="gl-min-w-0"
:disabled="disableRepoDropdown"
- >
- <template #header>
- <gl-search-box-by-type v-if="!disableRepoDropdown" v-model.trim="searchTerm" />
- </template>
- <template v-if="!disableRepoDropdown">
- <gl-dropdown-item
- v-for="repo in filteredRepos"
- :key="repo.id"
- is-check-item
- :is-checked="selectedProject.id === repo.id"
- @click="onClick(repo)"
- >
- {{ repo.name }}
- </gl-dropdown-item>
- </template>
- </gl-dropdown>
+ :items="filteredRepos"
+ block
+ searchable
+ @select="emitTargetProject"
+ @search="onSearch"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/projects/new/components/app.vue b/app/assets/javascripts/projects/new/components/app.vue
index 2f58d4468be..6ca83b0b500 100644
--- a/app/assets/javascripts/projects/new/components/app.vue
+++ b/app/assets/javascripts/projects/new/components/app.vue
@@ -1,8 +1,8 @@
<script>
-import createFromTemplateIllustration from '@gitlab/svgs/dist/illustrations/project-create-from-template-sm.svg';
-import blankProjectIllustration from '@gitlab/svgs/dist/illustrations/project-create-new-sm.svg';
-import importProjectIllustration from '@gitlab/svgs/dist/illustrations/project-import-sm.svg';
-import ciCdProjectIllustration from '@gitlab/svgs/dist/illustrations/project-run-CICD-pipelines-sm.svg';
+import createFromTemplateIllustration from '@gitlab/svgs/dist/illustrations/project-create-from-template-sm.svg?raw';
+import blankProjectIllustration from '@gitlab/svgs/dist/illustrations/project-create-new-sm.svg?raw';
+import importProjectIllustration from '@gitlab/svgs/dist/illustrations/project-import-sm.svg?raw';
+import ciCdProjectIllustration from '@gitlab/svgs/dist/illustrations/project-run-CICD-pipelines-sm.svg?raw';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { s__ } from '~/locale';
import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue';
diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js
index 99ea02aaa4f..33320f59b0f 100644
--- a/app/assets/javascripts/projects/project_new.js
+++ b/app/assets/javascripts/projects/project_new.js
@@ -295,7 +295,7 @@ const bindEvents = () => {
});
$newProjectForm.on('submit', () => {
- $projectPath.val($projectPath.val().trim());
+ $projectPath.value = $projectPath.value.trim();
});
const updateUrlPathWarningVisibility = async () => {
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
index 3dcacf9eb34..6494456d560 100644
--- 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
@@ -55,7 +55,7 @@ export default {
},
searchInputDelay: 250,
wildcardsHelpPath: helpPagePath('user/project/protected_branches', {
- anchor: 'configure-multiple-protected-branches-by-using-a-wildcard',
+ anchor: 'protect-multiple-branches-with-wildcard-rules',
}),
props: {
projectPath: {
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js b/app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js
index b71c33d2b91..a45ed5c68af 100644
--- a/app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js
+++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/constants.js
@@ -49,7 +49,7 @@ export const BRANCH_PARAM_NAME = 'branch';
export const ALL_BRANCHES_WILDCARD = '*';
export const WILDCARDS_HELP_PATH =
- 'user/project/protected_branches#configure-multiple-protected-branches-by-using-a-wildcard';
+ 'user/project/protected_branches#protect-multiple-branches-with-wildcard-rules';
export const PROTECTED_BRANCHES_HELP_PATH = 'user/project/protected_branches';
diff --git a/app/assets/javascripts/projects/settings/components/access_dropdown.vue b/app/assets/javascripts/projects/settings/components/access_dropdown.vue
index 08a1c586f69..a2e4827cbfa 100644
--- a/app/assets/javascripts/projects/settings/components/access_dropdown.vue
+++ b/app/assets/javascripts/projects/settings/components/access_dropdown.vue
@@ -63,6 +63,11 @@ export default {
required: false,
default: () => [],
},
+ items: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
},
data() {
return {
@@ -143,11 +148,37 @@ export default {
query: debounce(function debouncedSearch() {
return this.getData();
}, 500),
+ items(items) {
+ this.setDataForSave(items);
+ },
},
created() {
this.getData({ initial: true });
},
methods: {
+ setDataForSave(items) {
+ this.selected = items.reduce(
+ (selected, item) => {
+ if (item.group_id) {
+ selected[LEVEL_TYPES.GROUP].push({ id: item.group_id, ...item });
+ } else if (item.user_id) {
+ selected[LEVEL_TYPES.USER].push({ id: item.user_id, ...item });
+ } else if (item.access_level) {
+ const level = this.accessLevelsData.find(({ id }) => item.access_level === id);
+ selected[LEVEL_TYPES.ROLE].push(level);
+ } else if (item.deploy_key_id) {
+ selected[LEVEL_TYPES.DEPLOY_KEY].push({ id: item.deploy_key_id, ...item });
+ }
+ return selected;
+ },
+ {
+ [LEVEL_TYPES.GROUP]: [],
+ [LEVEL_TYPES.USER]: [],
+ [LEVEL_TYPES.ROLE]: [],
+ [LEVEL_TYPES.DEPLOY_KEY]: [],
+ },
+ );
+ },
focusInput() {
this.$refs.search.focusInput();
},
diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue
index 79ece99e6ec..650b60cba4f 100644
--- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue
+++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue
@@ -23,6 +23,9 @@ export default {
initialIsEnabled: {
default: false,
},
+ isIssueTrackerEnabled: {
+ default: false,
+ },
endpoint: {
default: '',
},
@@ -163,6 +166,7 @@ export default {
</gl-alert>
<service-desk-setting
:is-enabled="isEnabled"
+ :is-issue-tracker-enabled="isIssueTrackerEnabled"
:incoming-email="incomingEmail"
:custom-email="updatedCustomEmail"
:custom-email-enabled="customEmailEnabled"
diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
index 5a3930b5df4..38a2c12d137 100644
--- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
+++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
@@ -8,6 +8,7 @@ import {
GlFormGroup,
GlFormInput,
GlLink,
+ GlAlert,
} from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
import { __ } from '~/locale';
@@ -17,6 +18,9 @@ import ServiceDeskTemplateDropdown from './service_desk_template_dropdown.vue';
export default {
i18n: {
toggleLabel: __('Activate Service Desk'),
+ issueTrackerEnableMessage: __(
+ 'To use Service Desk in this project, you must %{linkStart}activate the issue tracker%{linkEnd}.',
+ ),
},
components: {
ClipboardButton,
@@ -28,6 +32,7 @@ export default {
GlFormGroup,
GlFormInputGroup,
GlLink,
+ GlAlert,
ServiceDeskTemplateDropdown,
},
props: {
@@ -35,6 +40,10 @@ export default {
type: Boolean,
required: true,
},
+ isIssueTrackerEnabled: {
+ type: Boolean,
+ required: true,
+ },
incomingEmail: {
type: String,
required: false,
@@ -110,6 +119,11 @@ export default {
anchor: 'use-a-custom-email-address',
});
},
+ issuesHelpPagePath() {
+ return helpPagePath('user/project/settings/index.md', {
+ anchor: 'configure-project-visibility-features-and-permissions',
+ });
+ },
},
methods: {
onCheckboxToggle(isChecked) {
@@ -141,9 +155,24 @@ export default {
<template>
<div>
+ <gl-alert v-if="!isIssueTrackerEnabled" class="mb-3" variant="info" :dismissible="false">
+ <gl-sprintf :message="$options.i18n.issueTrackerEnableMessage">
+ <template #link="{ content }">
+ <gl-link
+ class="gl-display-inline-block"
+ data-testid="issue-help-page"
+ :href="issuesHelpPagePath"
+ target="_blank"
+ >
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
<gl-toggle
id="service-desk-checkbox"
:value="isEnabled"
+ :disabled="!isIssueTrackerEnabled"
class="d-inline-block align-middle mr-1"
:label="$options.i18n.toggleLabel"
label-position="hidden"
@@ -194,6 +223,7 @@ export default {
:label="__('Email address suffix')"
:state="!projectKeyError"
data-testid="suffix-form-group"
+ :disabled="!isIssueTrackerEnabled"
>
<gl-form-input
v-if="hasProjectKeySupport"
@@ -249,6 +279,7 @@ export default {
:label="__('Template to append to all Service Desk issues')"
:state="!projectKeyError"
class="mt-3"
+ :disabled="!isIssueTrackerEnabled"
>
<service-desk-template-dropdown
:selected-template="selectedTemplate"
@@ -268,6 +299,7 @@ export default {
id="service-desk-email-from-name"
v-model.trim="outgoingName"
data-testid="email-from-name"
+ :disabled="!isIssueTrackerEnabled"
/>
<template #description>
@@ -280,7 +312,7 @@ export default {
class="gl-mt-5"
data-testid="save_service_desk_settings_button"
data-qa-selector="save_service_desk_settings_button"
- :disabled="isTemplateSaving"
+ :disabled="isTemplateSaving || !isIssueTrackerEnabled"
@click="onSaveTemplate"
>
{{ __('Save changes') }}
diff --git a/app/assets/javascripts/projects/settings_service_desk/index.js b/app/assets/javascripts/projects/settings_service_desk/index.js
index 26435a5fac9..84229175c0b 100644
--- a/app/assets/javascripts/projects/settings_service_desk/index.js
+++ b/app/assets/javascripts/projects/settings_service_desk/index.js
@@ -13,6 +13,7 @@ export default () => {
customEmail,
customEmailEnabled,
enabled,
+ issueTrackerEnabled,
endpoint,
incomingEmail,
outgoingName,
@@ -31,6 +32,7 @@ export default () => {
endpoint,
initialIncomingEmail: incomingEmail,
initialIsEnabled: parseBoolean(enabled),
+ isIssueTrackerEnabled: parseBoolean(issueTrackerEnabled),
outgoingName,
projectKey,
selectedTemplate,