diff options
Diffstat (limited to 'app/assets/javascripts/projects')
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({ |