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/components/branches_dropdown.vue2
-rw-r--r--app/assets/javascripts/projects/commits/components/author_select.vue5
-rw-r--r--app/assets/javascripts/projects/components/project_delete_button.vue4
-rw-r--r--app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue10
-rw-r--r--app/assets/javascripts/projects/project_new.js21
-rw-r--r--app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue59
-rw-r--r--app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js8
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue7
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue2
-rw-r--r--app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue65
-rw-r--r--app/assets/javascripts/projects/terraform_notification/index.js18
-rw-r--r--app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue6
12 files changed, 178 insertions, 29 deletions
diff --git a/app/assets/javascripts/projects/commit/components/branches_dropdown.vue b/app/assets/javascripts/projects/commit/components/branches_dropdown.vue
index cc5bc703994..52da8aaba4d 100644
--- a/app/assets/javascripts/projects/commit/components/branches_dropdown.vue
+++ b/app/assets/javascripts/projects/commit/components/branches_dropdown.vue
@@ -99,7 +99,7 @@ export default {
{{ branch }}
</gl-dropdown-item>
<gl-dropdown-text v-show="isFetching" data-testid="dropdown-text-loading-icon">
- <gl-loading-icon class="gl-mx-auto" />
+ <gl-loading-icon size="sm" class="gl-mx-auto" />
</gl-dropdown-text>
<gl-dropdown-text
v-if="!filteredResults.length && !isFetching"
diff --git a/app/assets/javascripts/projects/commits/components/author_select.vue b/app/assets/javascripts/projects/commits/components/author_select.vue
index 1566232751d..c8a0a3417f3 100644
--- a/app/assets/javascripts/projects/commits/components/author_select.vue
+++ b/app/assets/javascripts/projects/commits/components/author_select.vue
@@ -9,8 +9,7 @@ import {
} from '@gitlab/ui';
import { debounce } from 'lodash';
import { mapState, mapActions } from 'vuex';
-import { urlParamsToObject } from '~/lib/utils/common_utils';
-import { redirectTo } from '~/lib/utils/url_utility';
+import { redirectTo, queryToObject } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
const tooltipMessage = __('Searching by both author and message is currently not supported.');
@@ -52,7 +51,7 @@ export default {
},
mounted() {
this.fetchAuthors();
- const params = urlParamsToObject(window.location.search);
+ const params = queryToObject(window.location.search);
const { search: searchParam, author: authorParam } = params;
const commitsSearchInput = this.projectCommitsEl.querySelector('#commits-search');
diff --git a/app/assets/javascripts/projects/components/project_delete_button.vue b/app/assets/javascripts/projects/components/project_delete_button.vue
index 81d23a563e2..06711e4025a 100644
--- a/app/assets/javascripts/projects/components/project_delete_button.vue
+++ b/app/assets/javascripts/projects/components/project_delete_button.vue
@@ -24,9 +24,6 @@ export default {
alertBody: __(
'Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc.',
),
- modalBody: __(
- "This action cannot be undone. You will lose this project's repository and all related resources, including issues, merge requests, etc.",
- ),
},
};
</script>
@@ -46,7 +43,6 @@ export default {
</template>
</gl-sprintf>
</gl-alert>
- <p>{{ $options.strings.modalBody }}</p>
</template>
</shared-delete-button>
</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 1c4413bef71..0b0560f63c1 100644
--- a/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue
+++ b/app/assets/javascripts/projects/pipelines/charts/components/pipeline_charts.vue
@@ -225,11 +225,21 @@ export default {
{
name: 'success',
data: this.mergeLabelsAndValues(labels, success),
+ areaStyle: {
+ color: this.$options.successColor,
+ },
+ lineStyle: {
+ color: this.$options.successColor,
+ },
+ itemStyle: {
+ color: this.$options.successColor,
+ },
},
],
};
},
},
+ successColor: '#608b2f',
chartContainerHeight: CHART_CONTAINER_HEIGHT,
timesChartOptions: {
height: INNER_CHART_HEIGHT,
diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js
index 04ea6f760f6..ee02f446795 100644
--- a/app/assets/javascripts/projects/project_new.js
+++ b/app/assets/javascripts/projects/project_new.js
@@ -74,6 +74,7 @@ const deriveProjectPathFromUrl = ($projectImportUrl) => {
const bindEvents = () => {
const $newProjectForm = $('#new_project');
const $projectImportUrl = $('#project_import_url');
+ const $projectImportUrlWarning = $('.js-import-url-warning');
const $projectPath = $('.tab-pane.active #project_path');
const $useTemplateBtn = $('.template-button > input');
const $projectFieldsForm = $('.project-fields-form');
@@ -134,7 +135,25 @@ const bindEvents = () => {
$projectPath.val($projectPath.val().trim());
});
- $projectImportUrl.keyup(() => deriveProjectPathFromUrl($projectImportUrl));
+ function updateUrlPathWarningVisibility() {
+ const url = $projectImportUrl.val();
+ const URL_PATTERN = /(?:git|https?):\/\/.*\/.*\.git$/;
+ const isUrlValid = URL_PATTERN.test(url);
+ $projectImportUrlWarning.toggleClass('hide', isUrlValid);
+ }
+
+ let isProjectImportUrlDirty = false;
+ $projectImportUrl.on('blur', () => {
+ isProjectImportUrlDirty = true;
+ updateUrlPathWarningVisibility();
+ });
+ $projectImportUrl.on('keyup', () => {
+ deriveProjectPathFromUrl($projectImportUrl);
+ // defer error message till first input blur
+ if (isProjectImportUrlDirty) {
+ updateUrlPathWarningVisibility();
+ }
+ });
$('.js-import-git-toggle-button').on('click', () => {
const $projectMirror = $('#project_mirror');
diff --git a/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue b/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
index 0786a74f6b1..e4edb950a1e 100644
--- a/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
+++ b/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
@@ -1,15 +1,23 @@
<script>
import { GlAlert, GlToggle, GlTooltip } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
-import { __ } from '~/locale';
+import { __, s__ } from '~/locale';
const DEFAULT_ERROR_MESSAGE = __('An error occurred while updating the configuration.');
+const REQUIRES_VALIDATION_TEXT = s__(
+ `Billings|Shared runners cannot be enabled until a valid credit card is on file.`,
+);
export default {
+ i18n: {
+ REQUIRES_VALIDATION_TEXT,
+ },
components: {
GlAlert,
GlToggle,
GlTooltip,
+ CcValidationRequiredAlert: () =>
+ import('ee_component/billings/components/cc_validation_required_alert.vue'),
},
props: {
isDisabledAndUnoverridable: {
@@ -20,6 +28,10 @@ export default {
type: Boolean,
required: true,
},
+ isCreditCardValidationRequired: {
+ type: Boolean,
+ required: false,
+ },
updatePath: {
type: String,
required: true,
@@ -28,14 +40,24 @@ export default {
data() {
return {
isLoading: false,
- isSharedRunnerEnabled: false,
+ isSharedRunnerEnabled: this.isEnabled,
errorMessage: null,
+ successfulValidation: false,
};
},
- created() {
- this.isSharedRunnerEnabled = this.isEnabled;
+ computed: {
+ showCreditCardValidation() {
+ return (
+ this.isCreditCardValidationRequired &&
+ !this.isSharedRunnerEnabled &&
+ !this.successfulValidation
+ );
+ },
},
methods: {
+ creditCardValidated() {
+ this.successfulValidation = true;
+ },
toggleSharedRunners() {
this.isLoading = true;
this.errorMessage = null;
@@ -61,16 +83,25 @@ export default {
<gl-alert v-if="errorMessage" class="gl-mb-3" variant="danger" :dismissible="false">
{{ errorMessage }}
</gl-alert>
- <div ref="sharedRunnersToggle">
- <gl-toggle
- :disabled="isDisabledAndUnoverridable"
- :is-loading="isLoading"
- :label="__('Enable shared runners for this project')"
- :value="isSharedRunnerEnabled"
- data-testid="toggle-shared-runners"
- @change="toggleSharedRunners"
- />
- </div>
+
+ <cc-validation-required-alert
+ v-if="showCreditCardValidation"
+ class="gl-pb-5"
+ :custom-message="$options.i18n.REQUIRES_VALIDATION_TEXT"
+ @verifiedCreditCard="creditCardValidated"
+ />
+
+ <gl-toggle
+ v-else
+ ref="sharedRunnersToggle"
+ :disabled="isDisabledAndUnoverridable"
+ :is-loading="isLoading"
+ :label="__('Enable shared runners for this project')"
+ :value="isSharedRunnerEnabled"
+ data-testid="toggle-shared-runners"
+ @change="toggleSharedRunners"
+ />
+
<gl-tooltip v-if="isDisabledAndUnoverridable" :target="() => $refs.sharedRunnersToggle">
{{ __('Shared runners are disabled on group level') }}
</gl-tooltip>
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 eaeb5848b68..5ca864a412b 100644
--- a/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js
+++ b/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js
@@ -4,7 +4,12 @@ import SharedRunnersToggle from '~/projects/settings/components/shared_runners_t
export default (containerId = 'toggle-shared-runners-form') => {
const containerEl = document.getElementById(containerId);
- const { isDisabledAndUnoverridable, isEnabled, updatePath } = containerEl.dataset;
+ const {
+ isDisabledAndUnoverridable,
+ isEnabled,
+ updatePath,
+ isCreditCardValidationRequired,
+ } = containerEl.dataset;
return new Vue({
el: containerEl,
@@ -13,6 +18,7 @@ export default (containerId = 'toggle-shared-runners-form') => {
props: {
isDisabledAndUnoverridable: parseBoolean(isDisabledAndUnoverridable),
isEnabled: parseBoolean(isEnabled),
+ isCreditCardValidationRequired: parseBoolean(isCreditCardValidationRequired),
updatePath,
},
});
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 fb00f58abae..4c083ed5496 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,5 +1,5 @@
<script>
-import { GlAlert } from '@gitlab/ui';
+import { GlAlert, GlSafeHtmlDirective } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import { __, sprintf } from '~/locale';
import ServiceDeskSetting from './service_desk_setting.vue';
@@ -9,6 +9,9 @@ export default {
GlAlert,
ServiceDeskSetting,
},
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
inject: {
initialIsEnabled: {
default: false,
@@ -121,7 +124,7 @@ export default {
<template>
<div>
<gl-alert v-if="isAlertShowing" class="mb-3" :variant="alertVariant" @dismiss="onDismiss">
- {{ alertMessage }}
+ <span v-safe-html="alertMessage"></span>
</gl-alert>
<service-desk-setting
:is-enabled="isEnabled"
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 3294a37c26a..34d53e2de0c 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
@@ -144,7 +144,7 @@ export default {
</span>
</template>
<template v-else>
- <gl-loading-icon :inline="true" />
+ <gl-loading-icon size="sm" :inline="true" />
<span class="sr-only">{{ __('Fetching incoming email') }}</span>
</template>
diff --git a/app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue b/app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue
new file mode 100644
index 00000000000..0b398eddc9c
--- /dev/null
+++ b/app/assets/javascripts/projects/terraform_notification/components/terraform_notification.vue
@@ -0,0 +1,65 @@
+<script>
+import { GlBanner } from '@gitlab/ui';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { parseBoolean, setCookie, getCookie } from '~/lib/utils/common_utils';
+import { s__ } from '~/locale';
+
+export default {
+ name: 'TerraformNotification',
+ i18n: {
+ title: s__('TerraformBanner|Using Terraform? Try the GitLab Managed Terraform State'),
+ description: s__(
+ 'TerraformBanner|The GitLab managed Terraform state backend can store your Terraform state easily and securely, and spares you from setting up additional remote resources. Its features include: versioning, encryption of the state file both in transit and at rest, locking, and remote Terraform plan/apply execution.',
+ ),
+ buttonText: s__("TerraformBanner|Learn more about GitLab's Backend State"),
+ },
+ components: {
+ GlBanner,
+ },
+ props: {
+ projectId: {
+ type: Number,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isVisible: true,
+ };
+ },
+ computed: {
+ bannerDissmisedKey() {
+ return `terraform_notification_dismissed_for_project_${this.projectId}`;
+ },
+ docsUrl() {
+ return helpPagePath('user/infrastructure/terraform_state');
+ },
+ },
+ created() {
+ if (parseBoolean(getCookie(this.bannerDissmisedKey))) {
+ this.isVisible = false;
+ }
+ },
+ methods: {
+ handleClose() {
+ setCookie(this.bannerDissmisedKey, true);
+ this.isVisible = false;
+ },
+ },
+};
+</script>
+<template>
+ <div v-if="isVisible">
+ <div class="gl-py-5">
+ <gl-banner
+ :title="$options.i18n.title"
+ :button-text="$options.i18n.buttonText"
+ :button-link="docsUrl"
+ variant="introduction"
+ @close="handleClose"
+ >
+ <p>{{ $options.i18n.description }}</p>
+ </gl-banner>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/terraform_notification/index.js b/app/assets/javascripts/projects/terraform_notification/index.js
new file mode 100644
index 00000000000..eb04f109a8e
--- /dev/null
+++ b/app/assets/javascripts/projects/terraform_notification/index.js
@@ -0,0 +1,18 @@
+import Vue from 'vue';
+import TerraformNotification from './components/terraform_notification.vue';
+
+export default () => {
+ const el = document.querySelector('.js-terraform-notification');
+
+ if (!el) {
+ return false;
+ }
+
+ const { projectId } = el.dataset;
+
+ return new Vue({
+ el,
+ render: (createElement) =>
+ createElement(TerraformNotification, { props: { projectId: Number(projectId) } }),
+ });
+};
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 f3d12e0dd00..f6f409873c8 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
@@ -1,7 +1,7 @@
<script>
import { GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
import Visibility from 'visibilityjs';
-import { deprecatedCreateFlash as Flash } from '~/flash';
+import createFlash from '~/flash';
import Poll from '~/lib/utils/poll';
import { __, s__, sprintf } from '~/locale';
import ciIcon from '~/vue_shared/components/ci_icon.vue';
@@ -57,7 +57,9 @@ export default {
group: 'notfound',
};
this.isLoading = false;
- Flash(s__('Something went wrong on our end'));
+ createFlash({
+ message: s__('Something went wrong on our end'),
+ });
},
initPolling() {
this.poll = new Poll({