diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-19 18:14:01 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-19 18:14:01 +0000 |
commit | d738ba980c5ce598811b700e215ab957132f3a67 (patch) | |
tree | 5f866d1448f5b670f834fb19a8c4082e839bfac0 /app/assets/javascripts | |
parent | b22f3af733282394aa18261c073adbec117a1d47 (diff) | |
download | gitlab-ce-d738ba980c5ce598811b700e215ab957132f3a67.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts')
10 files changed, 139 insertions, 19 deletions
diff --git a/app/assets/javascripts/content_editor/extensions/image.js b/app/assets/javascripts/content_editor/extensions/image.js index d7fb617f7ee..519f7f168ce 100644 --- a/app/assets/javascripts/content_editor/extensions/image.js +++ b/app/assets/javascripts/content_editor/extensions/image.js @@ -66,6 +66,17 @@ export default Image.extend({ }, ]; }, + renderHTML({ HTMLAttributes }) { + return [ + 'img', + { + src: HTMLAttributes.src, + alt: HTMLAttributes.alt, + title: HTMLAttributes.title, + 'data-canonical-src': HTMLAttributes.canonicalSrc, + }, + ]; + }, addNodeView() { return VueNodeViewRenderer(ImageWrapper); }, diff --git a/app/assets/javascripts/content_editor/services/serialization_helpers.js b/app/assets/javascripts/content_editor/services/serialization_helpers.js index ed5910fca18..4d5a54c0347 100644 --- a/app/assets/javascripts/content_editor/services/serialization_helpers.js +++ b/app/assets/javascripts/content_editor/services/serialization_helpers.js @@ -1,4 +1,4 @@ -import { uniq } from 'lodash'; +import { uniq, isString } from 'lodash'; const defaultAttrs = { td: { colspan: 1, rowspan: 1, colwidth: null }, @@ -325,9 +325,12 @@ export function renderHardBreak(state, node, parent, index) { export function renderImage(state, node) { const { alt, canonicalSrc, src, title } = node.attrs; - const quotedTitle = title ? ` ${state.quote(title)}` : ''; - state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`); + if (isString(src) || isString(canonicalSrc)) { + const quotedTitle = title ? ` ${state.quote(title)}` : ''; + + state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`); + } } export function renderPlayable(state, node) { diff --git a/app/assets/javascripts/environments/components/deployment.vue b/app/assets/javascripts/environments/components/deployment.vue index 292f9a366c3..ef43ca6bc33 100644 --- a/app/assets/javascripts/environments/components/deployment.vue +++ b/app/assets/javascripts/environments/components/deployment.vue @@ -1,13 +1,25 @@ <script> +import DeploymentStatusBadge from './deployment_status_badge.vue'; + export default { + components: { + DeploymentStatusBadge, + }, props: { deployment: { type: Object, required: true, }, }, + computed: { + status() { + return this.deployment?.status; + }, + }, }; </script> <template> - <div></div> + <div> + <deployment-status-badge v-if="status" :status="status" /> + </div> </template> diff --git a/app/assets/javascripts/environments/components/deployment_status_badge.vue b/app/assets/javascripts/environments/components/deployment_status_badge.vue new file mode 100644 index 00000000000..5a026911766 --- /dev/null +++ b/app/assets/javascripts/environments/components/deployment_status_badge.vue @@ -0,0 +1,60 @@ +<script> +import { GlBadge } from '@gitlab/ui'; +import { s__ } from '~/locale'; + +const STATUS_TEXT = { + created: s__('Deployment|Created'), + running: s__('Deployment|Running'), + success: s__('Deployment|Success'), + failed: s__('Deployment|Failed'), + canceled: s__('Deployment|Cancelled'), + skipped: s__('Deployment|Skipped'), + blocked: s__('Deployment|Waiting'), +}; + +const STATUS_VARIANT = { + success: 'success', + running: 'info', + failed: 'danger', + created: 'neutral', + canceled: 'neutral', + skipped: 'neutral', + blocked: 'neutral', +}; + +const STATUS_ICON = { + success: 'status_success', + running: 'status_running', + failed: 'status_failed', + created: 'status_created', + canceled: 'status_canceled', + skipped: 'status_skipped', + blocked: 'status_manual', +}; + +export default { + components: { + GlBadge, + }, + props: { + status: { + type: String, + required: true, + }, + }, + computed: { + icon() { + return STATUS_ICON[this.status]; + }, + text() { + return STATUS_TEXT[this.status]; + }, + variant() { + return STATUS_VARIANT[this.status]; + }, + }, +}; +</script> +<template> + <gl-badge v-if="status" :icon="icon" :variant="variant">{{ text }}</gl-badge> +</template> diff --git a/app/assets/javascripts/integrations/constants.js b/app/assets/javascripts/integrations/constants.js index 7d32fafdf92..b90658fb13c 100644 --- a/app/assets/javascripts/integrations/constants.js +++ b/app/assets/javascripts/integrations/constants.js @@ -26,3 +26,5 @@ export const I18N_SUCCESSFUL_CONNECTION_MESSAGE = s__('Integrations|Connection s export const settingsTabTitle = __('Settings'); export const overridesTabTitle = s__('Integrations|Projects using custom settings'); + +export const INTEGRATION_FORM_SELECTOR = '.js-integration-settings-form'; diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue index ca38c83547b..c3cc35adfa5 100644 --- a/app/assets/javascripts/integrations/edit/components/integration_form.vue +++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue @@ -1,5 +1,5 @@ <script> -import { GlButton, GlModalDirective, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui'; +import { GlButton, GlModalDirective, GlSafeHtmlDirective as SafeHtml, GlForm } from '@gitlab/ui'; import axios from 'axios'; import * as Sentry from '@sentry/browser'; import { mapState, mapActions, mapGetters } from 'vuex'; @@ -9,9 +9,11 @@ import { I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE, I18N_DEFAULT_ERROR_MESSAGE, I18N_SUCCESSFUL_CONNECTION_MESSAGE, + INTEGRATION_FORM_SELECTOR, integrationLevels, } from '~/integrations/constants'; import { refreshCurrentPage } from '~/lib/utils/url_utility'; +import csrf from '~/lib/utils/csrf'; import eventHub from '../event_hub'; import { testIntegrationSettings } from '../api'; import ActiveCheckbox from './active_checkbox.vue'; @@ -35,6 +37,7 @@ export default { ConfirmationModal, ResetConfirmationModal, GlButton, + GlForm, }, directives: { GlModal: GlModalDirective, @@ -42,10 +45,6 @@ export default { }, mixins: [glFeatureFlagsMixin()], props: { - formSelector: { - type: String, - required: true, - }, helpHtml: { type: String, required: false, @@ -84,10 +83,28 @@ export default { disableButtons() { return Boolean(this.isSaving || this.isResetting || this.isTesting); }, + useVueForm() { + return this.glFeatures?.vueIntegrationForm; + }, + formContainerProps() { + return this.useVueForm + ? { + ref: 'integrationForm', + method: 'post', + class: 'gl-mb-3 gl-show-field-errors integration-settings-form', + action: this.propsSource.formPath, + novalidate: !this.integrationActive, + } + : {}; + }, + formContainer() { + return this.useVueForm ? GlForm : 'div'; + }, }, mounted() { - // this form element is defined in Haml - this.form = document.querySelector(this.formSelector); + this.form = this.useVueForm + ? this.$refs.integrationForm.$el + : document.querySelector(INTEGRATION_FORM_SELECTOR); }, methods: { ...mapActions(['setOverride', 'fetchResetIntegration', 'requestJiraIssueTypes']), @@ -152,7 +169,7 @@ export default { }, onToggleIntegrationState(integrationActive) { this.integrationActive = integrationActive; - if (!this.form) { + if (!this.form || this.useVueForm) { return; } @@ -169,11 +186,23 @@ export default { ADD_TAGS: ['use'], // to support icon SVGs FORBID_ATTR: [], // This is trusted input so we can override the default config to allow data-* attributes }, + csrf, }; </script> <template> - <div class="gl-mb-3"> + <component :is="formContainer" v-bind="formContainerProps"> + <template v-if="useVueForm"> + <input type="hidden" name="_method" value="put" /> + <input type="hidden" name="authenticity_token" :value="$options.csrf.token" /> + <input + type="hidden" + name="redirect_to" + :value="propsSource.redirectTo" + data-testid="redirect-to-field" + /> + </template> + <override-dropdown v-if="defaultState !== null" :inherit-from-id="defaultState.id" @@ -282,5 +311,5 @@ export default { </div> </div> </div> - </div> + </component> </template> diff --git a/app/assets/javascripts/integrations/edit/index.js b/app/assets/javascripts/integrations/edit/index.js index 9c9e3edbeb8..fbda8c1e3d0 100644 --- a/app/assets/javascripts/integrations/edit/index.js +++ b/app/assets/javascripts/integrations/edit/index.js @@ -28,9 +28,11 @@ function parseDatasetToProps(data) { cancelPath, testPath, resetPath, + formPath, vulnerabilitiesIssuetype, jiraIssueTransitionAutomatic, jiraIssueTransitionId, + redirectTo, ...booleanAttributes } = data; const { @@ -57,6 +59,7 @@ function parseDatasetToProps(data) { canTest, testPath, resetPath, + formPath, triggerFieldsProps: { initialTriggerCommit: commitEvents, initialTriggerMergeRequest: mergeRequestEvents, @@ -82,10 +85,11 @@ function parseDatasetToProps(data) { inheritFromId: parseInt(inheritFromId, 10), integrationLevel, id: parseInt(id, 10), + redirectTo, }; } -export default function initIntegrationSettingsForm(formSelector) { +export default function initIntegrationSettingsForm() { const customSettingsEl = document.querySelector('.js-vue-integration-settings'); const defaultSettingsEl = document.querySelector('.js-vue-default-integration-settings'); @@ -115,7 +119,6 @@ export default function initIntegrationSettingsForm(formSelector) { return createElement(IntegrationForm, { props: { helpHtml, - formSelector, }, }); }, diff --git a/app/assets/javascripts/pages/admin/integrations/edit/index.js b/app/assets/javascripts/pages/admin/integrations/edit/index.js index 8485b460261..c354ed1c142 100644 --- a/app/assets/javascripts/pages/admin/integrations/edit/index.js +++ b/app/assets/javascripts/pages/admin/integrations/edit/index.js @@ -1,7 +1,7 @@ import initIntegrationSettingsForm from '~/integrations/edit'; import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics'; -initIntegrationSettingsForm('.js-integration-settings-form'); +initIntegrationSettingsForm(); const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring'; const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector); diff --git a/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js b/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js index 8485b460261..c354ed1c142 100644 --- a/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js +++ b/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js @@ -1,7 +1,7 @@ import initIntegrationSettingsForm from '~/integrations/edit'; import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics'; -initIntegrationSettingsForm('.js-integration-settings-form'); +initIntegrationSettingsForm(); const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring'; const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector); diff --git a/app/assets/javascripts/pages/projects/services/edit/index.js b/app/assets/javascripts/pages/projects/services/edit/index.js index a2b18d86240..2048d3dfc37 100644 --- a/app/assets/javascripts/pages/projects/services/edit/index.js +++ b/app/assets/javascripts/pages/projects/services/edit/index.js @@ -2,7 +2,7 @@ import initIntegrationSettingsForm from '~/integrations/edit'; import PrometheusAlerts from '~/prometheus_alerts'; import CustomMetrics from '~/prometheus_metrics/custom_metrics'; -initIntegrationSettingsForm('.js-integration-settings-form'); +initIntegrationSettingsForm(); const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring'; const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector); |