summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/projects
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/projects')
-rw-r--r--app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue36
-rw-r--r--app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue2
-rw-r--r--app/assets/javascripts/projects/project_visibility.js11
-rw-r--r--app/assets/javascripts/projects/settings/repository/branch_rules/app.vue52
-rw-r--r--app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue61
-rw-r--r--app/assets/javascripts/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql10
-rw-r--r--app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js17
-rw-r--r--app/assets/javascripts/projects/settings/topics/components/topics_token_selector.vue2
-rw-r--r--app/assets/javascripts/projects/settings/topics/queries/project_topics_search.query.graphql10
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue32
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue64
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue2
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/index.js2
-rw-r--r--app/assets/javascripts/projects/star.js3
-rw-r--r--app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue4
15 files changed, 235 insertions, 73 deletions
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 1cdf26b76b7..4505dd1f85c 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
@@ -2,11 +2,11 @@
import { GlLoadingIcon } from '@gitlab/ui';
import createFlash from '~/flash';
import { __ } from '~/locale';
-import PipelineMiniGraph from '~/pipelines/components/pipelines_list/pipeline_mini_graph.vue';
import {
getQueryHeaders,
toggleQueryPollingByVisibility,
} from '~/pipelines/components/graph/utils';
+import PipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/pipeline_mini_graph.vue';
import { formatStages } from '../utils';
import getLinkedPipelinesQuery from '../graphql/queries/get_linked_pipelines.query.graphql';
import getPipelineStagesQuery from '../graphql/queries/get_pipeline_stages.query.graphql';
@@ -21,8 +21,6 @@ export default {
components: {
GlLoadingIcon,
PipelineMiniGraph,
- LinkedPipelinesMiniList: () =>
- import('ee_component/vue_shared/components/linked_pipelines_mini_list.vue'),
},
inject: {
fullPath: {
@@ -92,12 +90,12 @@ export default {
};
},
computed: {
- hasDownstream() {
- return this.pipeline?.downstream?.nodes.length > 0;
- },
downstreamPipelines() {
return this.pipeline?.downstream?.nodes;
},
+ pipelinePath() {
+ return this.pipeline?.path ?? '';
+ },
upstreamPipeline() {
return this.pipeline?.upstream;
},
@@ -128,23 +126,13 @@ export default {
<template>
<div class="gl-pt-2">
<gl-loading-icon v-if="$apollo.queries.pipeline.loading" />
- <div v-else class="gl-align-items-center gl-display-flex">
- <linked-pipelines-mini-list
- v-if="upstreamPipeline"
- :triggered-by="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ [
- upstreamPipeline,
- ] /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */"
- data-testid="commit-box-mini-graph-upstream"
- />
-
- <pipeline-mini-graph :stages="formattedStages" data-testid="commit-box-mini-graph" />
-
- <linked-pipelines-mini-list
- v-if="hasDownstream"
- :triggered="downstreamPipelines"
- :pipeline-path="pipeline.path"
- data-testid="commit-box-mini-graph-downstream"
- />
- </div>
+ <pipeline-mini-graph
+ v-else
+ data-testid="commit-box-pipeline-mini-graph"
+ :downstream-pipelines="downstreamPipelines"
+ :pipeline-path="pipelinePath"
+ :stages="formattedStages"
+ :upstream-pipeline="upstreamPipeline"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue b/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue
index ecd2288eb2f..06d96ef7bef 100644
--- a/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue
+++ b/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue
@@ -1,7 +1,7 @@
<script>
import { GlAlert, GlSkeletonLoader } from '@gitlab/ui';
import { GlColumnChart } from '@gitlab/ui/dist/charts';
-import dateFormat from 'dateformat';
+import dateFormat from '~/lib/dateformat';
import { getDateInPast } from '~/lib/utils/datetime_utility';
import { __, s__, sprintf } from '~/locale';
import CiCdAnalyticsCharts from '~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_charts.vue';
diff --git a/app/assets/javascripts/projects/project_visibility.js b/app/assets/javascripts/projects/project_visibility.js
index b8ac17a01f2..84b8936c17f 100644
--- a/app/assets/javascripts/projects/project_visibility.js
+++ b/app/assets/javascripts/projects/project_visibility.js
@@ -1,13 +1,7 @@
import { escape } from 'lodash';
import { __, sprintf } from '~/locale';
import eventHub from '~/projects/new/event_hub';
-
-// Values are from lib/gitlab/visibility_level.rb
-const visibilityLevel = {
- private: 0,
- internal: 10,
- public: 20,
-};
+import { VISIBILITY_LEVELS_STRING_TO_INTEGER } from '~/visibility_level/constants';
function setVisibilityOptions({ name, visibility, showPath, editPath }) {
document.querySelectorAll('.visibility-level-setting .gl-form-radio').forEach((option) => {
@@ -19,13 +13,14 @@ function setVisibilityOptions({ name, visibility, showPath, editPath }) {
const optionInput = option.querySelector('input[type=radio]');
const optionValue = optionInput ? parseInt(optionInput.value, 10) : 0;
- if (visibilityLevel[visibility] < optionValue) {
+ if (VISIBILITY_LEVELS_STRING_TO_INTEGER[visibility] < optionValue) {
option.classList.add('disabled');
optionInput.disabled = true;
const reason = option.querySelector('.option-disabled-reason');
if (reason) {
const optionTitle = option.querySelector('.js-visibility-level-radio span');
const optionName = optionTitle ? optionTitle.innerText.toLowerCase() : '';
+ // eslint-disable-next-line no-unsanitized/property
reason.innerHTML = sprintf(
__(
'This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group.',
diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/app.vue b/app/assets/javascripts/projects/settings/repository/branch_rules/app.vue
index ada951f6867..e8eaf0a70b2 100644
--- a/app/assets/javascripts/projects/settings/repository/branch_rules/app.vue
+++ b/app/assets/javascripts/projects/settings/repository/branch_rules/app.vue
@@ -1,16 +1,58 @@
<script>
-import { __ } from '~/locale';
+import { s__ } from '~/locale';
+import createFlash from '~/flash';
+import branchRulesQuery from './graphql/queries/branch_rules.query.graphql';
+import BranchRule from './components/branch_rule.vue';
+
+export const i18n = {
+ queryError: s__(
+ 'ProtectedBranch|An error occurred while loading branch rules. Please try again.',
+ ),
+ emptyState: s__(
+ 'ProtectedBranch|Protected branches, merge request approvals, and status checks will appear here once configured.',
+ ),
+};
export default {
name: 'BranchRules',
- i18n: { heading: __('Branch') },
+ i18n,
+ components: {
+ BranchRule,
+ },
+ apollo: {
+ branchRules: {
+ query: branchRulesQuery,
+ variables() {
+ return {
+ projectPath: this.projectPath,
+ };
+ },
+ update(data) {
+ return data.project?.branchRules?.nodes || [];
+ },
+ error() {
+ createFlash({ message: this.$options.i18n.queryError });
+ },
+ },
+ },
+ props: {
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ branchRules: [],
+ };
+ },
};
</script>
<template>
- <div>
- <strong>{{ $options.i18n.heading }}</strong>
+ <div class="settings-content">
+ <branch-rule v-for="rule in branchRules" :key="rule.name" :name="rule.name" />
- <!-- TODO - List branch rules (https://gitlab.com/gitlab-org/gitlab/-/issues/362217) -->
+ <span v-if="!branchRules.length" data-testid="empty">{{ $options.i18n.emptyState }}</span>
</div>
</template>
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
new file mode 100644
index 00000000000..68750318029
--- /dev/null
+++ b/app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue
@@ -0,0 +1,61 @@
+<script>
+import { GlBadge } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
+export const i18n = {
+ defaultLabel: s__('BranchRules|default'),
+ protectedLabel: s__('BranchRules|protected'),
+};
+
+export default {
+ name: 'BranchRule',
+ i18n,
+ components: {
+ GlBadge,
+ },
+ props: {
+ name: {
+ type: String,
+ required: true,
+ },
+ isDefault: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isProtected: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ approvalDetails: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ },
+ computed: {
+ hasApprovalDetails() {
+ return this.approvalDetails && this.approvalDetails.length;
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="gl-border-b gl-pt-5 gl-pb-5">
+ <strong class="gl-font-monospace">{{ name }}</strong>
+
+ <gl-badge v-if="isDefault" variant="info" size="sm" class="gl-ml-2">{{
+ $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>
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql b/app/assets/javascripts/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql
new file mode 100644
index 00000000000..104a0c25a80
--- /dev/null
+++ b/app/assets/javascripts/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql
@@ -0,0 +1,10 @@
+query getBranchRules($projectPath: ID!) {
+ project(fullPath: $projectPath) {
+ id
+ branchRules {
+ nodes {
+ name
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js b/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js
index abe0b93081e..35322e2e466 100644
--- a/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js
+++ b/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js
@@ -1,13 +1,28 @@
import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
import BranchRulesApp from '~/projects/settings/repository/branch_rules/app.vue';
+Vue.use(VueApollo);
+
+const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+});
+
export default function mountBranchRules(el) {
if (!el) return null;
+ const { projectPath } = el.dataset;
+
return new Vue({
el,
+ apolloProvider,
render(createElement) {
- return createElement(BranchRulesApp);
+ return createElement(BranchRulesApp, {
+ props: {
+ projectPath,
+ },
+ });
},
});
}
diff --git a/app/assets/javascripts/projects/settings/topics/components/topics_token_selector.vue b/app/assets/javascripts/projects/settings/topics/components/topics_token_selector.vue
index 9c8de9bef2d..3d553e71f71 100644
--- a/app/assets/javascripts/projects/settings/topics/components/topics_token_selector.vue
+++ b/app/assets/javascripts/projects/settings/topics/components/topics_token_selector.vue
@@ -2,7 +2,7 @@
import { GlTokenSelector, GlAvatarLabeled } from '@gitlab/ui';
import { s__ } from '~/locale';
import { AVATAR_SHAPE_OPTION_RECT } from '~/vue_shared/constants';
-import searchProjectTopics from '../queries/project_topics_search.query.graphql';
+import searchProjectTopics from '~/graphql_shared/queries/project_topics_search.query.graphql';
export default {
components: {
diff --git a/app/assets/javascripts/projects/settings/topics/queries/project_topics_search.query.graphql b/app/assets/javascripts/projects/settings/topics/queries/project_topics_search.query.graphql
deleted file mode 100644
index 0c0a874d950..00000000000
--- a/app/assets/javascripts/projects/settings/topics/queries/project_topics_search.query.graphql
+++ /dev/null
@@ -1,10 +0,0 @@
-query searchProjectTopics($search: String) {
- topics(search: $search) {
- nodes {
- id
- name
- title
- avatarUrl
- }
- }
-}
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 14c8c53dd19..71ff3e892b1 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
@@ -1,12 +1,18 @@
<script>
-import { GlAlert, GlSafeHtmlDirective } from '@gitlab/ui';
+import { GlAlert, GlSprintf, GlLink, GlSafeHtmlDirective } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
+import { helpPagePath } from '~/helpers/help_page_helper';
import { __, sprintf } from '~/locale';
import ServiceDeskSetting from './service_desk_setting.vue';
export default {
+ customEmailHelpPath: helpPagePath('/user/project/service_desk.html', {
+ anchor: 'using-a-custom-email-address',
+ }),
components: {
GlAlert,
+ GlSprintf,
+ GlLink,
ServiceDeskSetting,
},
directives: {
@@ -43,6 +49,9 @@ export default {
templates: {
default: [],
},
+ publicProject: {
+ default: false,
+ },
},
data() {
return {
@@ -127,6 +136,27 @@ export default {
<template>
<div>
+ <gl-alert
+ v-if="publicProject && isEnabled"
+ class="mb-3"
+ variant="warning"
+ data-testid="public-project-alert"
+ :dismissible="false"
+ >
+ <gl-sprintf
+ :message="
+ __(
+ 'This project is public. Non-members can guess the Service Desk email address, because it contains the group and project name. %{linkStart}How do I create a custom email address?%{linkEnd}',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link :href="$options.customEmailHelpPath" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
<gl-alert v-if="isAlertShowing" class="mb-3" :variant="alertVariant" @dismiss="onDismiss">
<span v-safe-html="alertMessage"></span>
</gl-alert>
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 8a9a0b541f3..452e7a4fd21 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
@@ -176,7 +176,7 @@ export default {
</template>
</gl-form-input-group>
<template v-if="email && hasCustomEmail" #description>
- <span class="gl-mt-2 d-inline-block">
+ <span class="gl-mt-2 gl-display-inline-block">
<gl-sprintf :message="__('Emails sent to %{email} are also supported.')">
<template #email>
<code>{{ incomingEmail }}</code>
@@ -190,7 +190,11 @@ export default {
</template>
</gl-form-group>
- <gl-form-group :label="__('Email address suffix')" :state="!projectKeyError">
+ <gl-form-group
+ :label="__('Email address suffix')"
+ :state="!projectKeyError"
+ data-testid="suffix-form-group"
+ >
<gl-form-input
v-if="hasProjectKeySupport"
id="service-desk-project-suffix"
@@ -216,22 +220,24 @@ export default {
</gl-sprintf>
</template>
<template v-else #description>
- <gl-sprintf
- :message="
- __(
- 'To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more.%{linkEnd}',
- )
- "
- >
- <template #link="{ content }">
- <gl-link
- :href="customEmailAddressHelpUrl"
- target="_blank"
- class="gl-text-blue-600 font-size-inherit"
- >{{ content }}
- </gl-link>
- </template>
- </gl-sprintf>
+ <span class="gl-text-gray-900">
+ <gl-sprintf
+ :message="
+ __(
+ 'To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more.%{linkEnd}',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link
+ :href="customEmailAddressHelpUrl"
+ target="_blank"
+ class="gl-text-blue-600 font-size-inherit"
+ >{{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
</template>
<template v-if="hasProjectKeySupport && projectKeyError" #invalid-feedback>
@@ -266,7 +272,27 @@ export default {
/>
<template v-if="hasProjectKeySupport" #description>
- {{ __('Emails sent from Service Desk have this name.') }}
+ {{ __('Name to be used as the sender for emails from Service Desk.') }}
+ </template>
+ <template v-else #description>
+ <span class="gl-text-gray-900">
+ <gl-sprintf
+ :message="
+ __(
+ 'To add display name, set up a Service Desk email address. %{linkStart}Learn more.%{linkEnd}',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link
+ :href="customEmailAddressHelpUrl"
+ target="_blank"
+ class="gl-text-blue-600 font-size-inherit"
+ >{{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
</template>
</gl-form-group>
diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue
index bdd9f940d79..315f0743b53 100644
--- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue
+++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue
@@ -100,7 +100,7 @@ export default {
<gl-dropdown-item
v-for="template in item"
:key="template.key"
- :is-check-item="true"
+ is-check-item
:is-checked="
template.project_id === selectedFileTemplateProjectId &&
template.name === selectedTemplate
diff --git a/app/assets/javascripts/projects/settings_service_desk/index.js b/app/assets/javascripts/projects/settings_service_desk/index.js
index e14cdee17ce..26435a5fac9 100644
--- a/app/assets/javascripts/projects/settings_service_desk/index.js
+++ b/app/assets/javascripts/projects/settings_service_desk/index.js
@@ -20,6 +20,7 @@ export default () => {
selectedTemplate,
selectedFileTemplateProjectId,
templates,
+ publicProject,
} = el.dataset;
return new Vue({
@@ -35,6 +36,7 @@ export default () => {
selectedTemplate,
selectedFileTemplateProjectId: parseInt(selectedFileTemplateProjectId, 10) || null,
templates: JSON.parse(templates),
+ publicProject: parseBoolean(publicProject),
},
render: (createElement) => createElement(ServiceDeskRoot),
});
diff --git a/app/assets/javascripts/projects/star.js b/app/assets/javascripts/projects/star.js
index 5bbace11b15..e063064663b 100644
--- a/app/assets/javascripts/projects/star.js
+++ b/app/assets/javascripts/projects/star.js
@@ -22,11 +22,14 @@ export default class Star {
starSpan.classList.remove('starred');
starSpan.textContent = s__('StarProject|Star');
starIcon.remove();
+ // eslint-disable-next-line no-unsanitized/method
starSpan.insertAdjacentHTML('beforebegin', spriteIcon('star-o', iconClasses));
} else {
starSpan.classList.add('starred');
starSpan.textContent = __('Unstar');
starIcon.remove();
+
+ // eslint-disable-next-line no-unsanitized/method
starSpan.insertAdjacentHTML('beforebegin', spriteIcon('star', iconClasses));
}
})
diff --git a/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue b/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue
index a79da00de43..6b14ebadacc 100644
--- a/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue
+++ b/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue
@@ -4,7 +4,7 @@ import Visibility from 'visibilityjs';
import createFlash from '~/flash';
import Poll from '~/lib/utils/poll';
import { __, s__, sprintf } from '~/locale';
-import ciIcon from '~/vue_shared/components/ci_icon.vue';
+import CiIcon from '~/vue_shared/components/ci_icon.vue';
import CommitPipelineService from '../services/commit_pipeline_service';
export default {
@@ -12,7 +12,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
components: {
- ciIcon,
+ CiIcon,
GlLoadingIcon,
},
props: {