diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 41c8525c0a4..62fb7c75cca 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -653,7 +653,6 @@ .rails:rules:decomposed-databases: rules: - <<: *if-merge-request-run-decomposed - allow_failure: true .rails:rules:ee-and-foss-migration: rules: diff --git a/app/assets/javascripts/behaviors/preview_markdown.js b/app/assets/javascripts/behaviors/preview_markdown.js index a1911585f80..a548b283142 100644 --- a/app/assets/javascripts/behaviors/preview_markdown.js +++ b/app/assets/javascripts/behaviors/preview_markdown.js @@ -81,7 +81,7 @@ MarkdownPreview.prototype.fetchMarkdownPreview = function (text, url, success) { }) .catch(() => createFlash({ - message: __('An error occurred while fetching markdown preview'), + message: __('An error occurred while fetching Markdown preview'), }), ); }; diff --git a/app/assets/javascripts/cycle_analytics/index.js b/app/assets/javascripts/cycle_analytics/index.js index 620da0104e0..34ef03409b8 100644 --- a/app/assets/javascripts/cycle_analytics/index.js +++ b/app/assets/javascripts/cycle_analytics/index.js @@ -45,6 +45,7 @@ export default () => { new Vue({ el, name: 'CycleAnalytics', + apolloProvider: {}, store, render: (createElement) => createElement(CycleAnalytics, { diff --git a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue index 051ab710e5f..7acb5549273 100644 --- a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue +++ b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue @@ -25,7 +25,7 @@ export default { lazy: true, }, translations: { - cronPlaceholder: __('* * * * *'), + cronPlaceholder: '* * * * *', cronSyntaxInstructions: __( 'Define a custom deploy freeze pattern with %{cronSyntaxStart}cron syntax%{cronSyntaxEnd}', ), diff --git a/app/assets/javascripts/notifications/constants.js b/app/assets/javascripts/notifications/constants.js index 4f875977d78..f5891c9acb5 100644 --- a/app/assets/javascripts/notifications/constants.js +++ b/app/assets/javascripts/notifications/constants.js @@ -31,7 +31,7 @@ export const i18n = { title: __('Custom notification events'), bodyTitle: __('Notification events'), bodyMessage: __( - 'Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notificationLinkStart} notification emails%{notificationLinkEnd}.', + 'Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notificationLinkStart}notification emails%{notificationLinkEnd}.', ), }, eventNames: { diff --git a/app/assets/javascripts/packages_and_registries/settings/project/constants.js b/app/assets/javascripts/packages_and_registries/settings/project/constants.js index 165c4aae3cb..4d477fbd05d 100644 --- a/app/assets/javascripts/packages_and_registries/settings/project/constants.js +++ b/app/assets/javascripts/packages_and_registries/settings/project/constants.js @@ -73,6 +73,7 @@ export const OLDER_THAN_OPTIONS = [ { key: 'SEVEN_DAYS', variable: 7, default: false }, { key: 'FOURTEEN_DAYS', variable: 14, default: false }, { key: 'THIRTY_DAYS', variable: 30, default: false }, + { key: 'SIXTY_DAYS', variable: 60, default: false }, { key: 'NINETY_DAYS', variable: 90, default: true }, ]; diff --git a/app/assets/javascripts/pages/profiles/index.js b/app/assets/javascripts/pages/profiles/index.js index 80bc32dd43f..6afb3636998 100644 --- a/app/assets/javascripts/pages/profiles/index.js +++ b/app/assets/javascripts/pages/profiles/index.js @@ -2,6 +2,7 @@ import $ from 'jquery'; import '~/profile/gl_crop'; import Profile from '~/profile/profile'; import initSearchSettings from '~/search_settings'; +import initPasswordPrompt from './password_prompt'; // eslint-disable-next-line func-names $(document).on('input.ssh_key', '#key_key', function () { @@ -19,3 +20,4 @@ $(document).on('input.ssh_key', '#key_key', function () { new Profile(); // eslint-disable-line no-new initSearchSettings(); +initPasswordPrompt(); diff --git a/app/assets/javascripts/pages/profiles/password_prompt/constants.js b/app/assets/javascripts/pages/profiles/password_prompt/constants.js new file mode 100644 index 00000000000..99b8442c928 --- /dev/null +++ b/app/assets/javascripts/pages/profiles/password_prompt/constants.js @@ -0,0 +1,9 @@ +import { __, s__ } from '~/locale'; + +export const I18N_PASSWORD_PROMPT_TITLE = s__('PasswordPrompt|Confirm password to continue'); +export const I18N_PASSWORD_PROMPT_FORM_LABEL = s__( + 'PasswordPrompt|Please enter your password to confirm', +); +export const I18N_PASSWORD_PROMPT_ERROR_MESSAGE = s__('PasswordPrompt|Password is required'); +export const I18N_PASSWORD_PROMPT_CONFIRM_BUTTON = s__('PasswordPrompt|Confirm password'); +export const I18N_PASSWORD_PROMPT_CANCEL_BUTTON = __('Cancel'); diff --git a/app/assets/javascripts/pages/profiles/password_prompt/index.js b/app/assets/javascripts/pages/profiles/password_prompt/index.js new file mode 100644 index 00000000000..20645112893 --- /dev/null +++ b/app/assets/javascripts/pages/profiles/password_prompt/index.js @@ -0,0 +1,58 @@ +import Vue from 'vue'; +import Translate from '~/vue_shared/translate'; +import PasswordPromptModal from './password_prompt_modal.vue'; + +Vue.use(Translate); + +const emailFieldSelector = '#user_email'; +const editFormSelector = '.js-password-prompt-form'; +const passwordPromptFieldSelector = '.js-password-prompt-field'; +const passwordPromptBtnSelector = '.js-password-prompt-btn'; + +const passwordPromptModalId = 'password-prompt-modal'; + +const getEmailValue = () => document.querySelector(emailFieldSelector).value.trim(); +const passwordPromptButton = document.querySelector(passwordPromptBtnSelector); +const field = document.querySelector(passwordPromptFieldSelector); +const form = document.querySelector(editFormSelector); + +const handleConfirmPassword = (pw) => { + // update the validation_password field + field.value = pw; + // submit the form + form.submit(); +}; + +export default () => { + const passwordPromptModalEl = document.getElementById(passwordPromptModalId); + + if (passwordPromptModalEl && field) { + return new Vue({ + el: passwordPromptModalEl, + data() { + return { + initialEmail: '', + }; + }, + mounted() { + this.initialEmail = getEmailValue(); + passwordPromptButton.addEventListener('click', this.handleSettingsUpdate); + }, + methods: { + handleSettingsUpdate(ev) { + const email = getEmailValue(); + if (email !== this.initialEmail) { + ev.preventDefault(); + this.$root.$emit('bv::show::modal', passwordPromptModalId, passwordPromptBtnSelector); + } + }, + }, + render(createElement) { + return createElement(PasswordPromptModal, { + props: { handleConfirmPassword }, + }); + }, + }); + } + return null; +}; diff --git a/app/assets/javascripts/pages/profiles/password_prompt/password_prompt_modal.vue b/app/assets/javascripts/pages/profiles/password_prompt/password_prompt_modal.vue new file mode 100644 index 00000000000..44728ea9cdf --- /dev/null +++ b/app/assets/javascripts/pages/profiles/password_prompt/password_prompt_modal.vue @@ -0,0 +1,82 @@ + + + diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js index 02baa76f627..d8f15cfde91 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js +++ b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/constants.js @@ -2,51 +2,51 @@ import { s__ } from '~/locale'; export const PIPELINE_SOURCES = [ { - text: s__('Pipeline|Source|Push'), + text: s__('PipelineSource|Push'), value: 'push', }, { - text: s__('Pipeline|Source|Web'), + text: s__('PipelineSource|Web'), value: 'web', }, { - text: s__('Pipeline|Source|Trigger'), + text: s__('PipelineSource|Trigger'), value: 'trigger', }, { - text: s__('Pipeline|Source|Schedule'), + text: s__('PipelineSource|Schedule'), value: 'schedule', }, { - text: s__('Pipeline|Source|API'), + text: s__('PipelineSource|API'), value: 'api', }, { - text: s__('Pipeline|Source|External'), + text: s__('PipelineSource|External'), value: 'external', }, { - text: s__('Pipeline|Source|Pipeline'), + text: s__('PipelineSource|Pipeline'), value: 'pipeline', }, { - text: s__('Pipeline|Source|Chat'), + text: s__('PipelineSource|Chat'), value: 'chat', }, { - text: s__('Pipeline|Source|Web IDE'), + text: s__('PipelineSource|Web IDE'), value: 'webide', }, { - text: s__('Pipeline|Source|Merge Request'), + text: s__('PipelineSource|Merge Request'), value: 'merge_request_event', }, { - text: s__('Pipeline|Source|External Pull Request'), + text: s__('PipelineSource|External Pull Request'), value: 'external_pull_request_event', }, { - text: s__('Pipeline|Source|Parent Pipeline'), + text: s__('PipelineSource|Parent Pipeline'), value: 'parent_pipeline', }, ]; diff --git a/app/assets/javascripts/related_issues/components/related_issues_block.vue b/app/assets/javascripts/related_issues/components/related_issues_block.vue index c042f0eef5f..7d23c7033f3 100644 --- a/app/assets/javascripts/related_issues/components/related_issues_block.vue +++ b/app/assets/javascripts/related_issues/components/related_issues_block.vue @@ -123,7 +123,7 @@ export default {