diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 21:13:27 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 21:13:27 +0300 |
commit | 13f6669657483134a697b7ec7b701563165bc9d5 (patch) | |
tree | 4d6e9161ab8d060abcdc2a4c6180c9d8cb868b70 /app/assets/javascripts/pipeline_editor | |
parent | 068b3a417794ab8506b2e149301b3a60c01df078 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/pipeline_editor')
6 files changed, 71 insertions, 17 deletions
diff --git a/app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue b/app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue index 833d784f940..280ad2951a7 100644 --- a/app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue +++ b/app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue @@ -5,6 +5,7 @@ import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.qu import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; import { EDITOR_APP_STATUS_EMPTY, + EDITOR_APP_STATUS_LINT_UNAVAILABLE, EDITOR_APP_STATUS_LOADING, EDITOR_APP_STATUS_VALID, } from '../../constants'; @@ -17,6 +18,7 @@ export const i18n = { loading: s__('Pipelines|Validating GitLab CI configuration…'), invalid: s__('Pipelines|This GitLab CI configuration is invalid.'), invalidWithReason: s__('Pipelines|This GitLab CI configuration is invalid: %{reason}.'), + unavailableValidation: s__('Pipelines|Configuration validation currently not available.'), valid: s__('Pipelines|This GitLab CI configuration is valid.'), }; @@ -29,6 +31,9 @@ export default { TooltipOnTruncate, }, inject: { + lintUnavailableHelpPagePath: { + default: '', + }, ymlHelpPagePath: { default: '', }, @@ -49,9 +54,15 @@ export default { }, }, computed: { + helpPath() { + return this.isLintUnavailable ? this.lintUnavailableHelpPagePath : this.ymlHelpPagePath; + }, isEmpty() { return this.appStatus === EDITOR_APP_STATUS_EMPTY; }, + isLintUnavailable() { + return this.appStatus === EDITOR_APP_STATUS_LINT_UNAVAILABLE; + }, isLoading() { return this.appStatus === EDITOR_APP_STATUS_LOADING; }, @@ -62,6 +73,8 @@ export default { switch (this.appStatus) { case EDITOR_APP_STATUS_EMPTY: return 'check'; + case EDITOR_APP_STATUS_LINT_UNAVAILABLE: + return 'time-out'; case EDITOR_APP_STATUS_VALID: return 'check'; default: @@ -74,6 +87,8 @@ export default { switch (this.appStatus) { case EDITOR_APP_STATUS_EMPTY: return this.$options.i18n.empty; + case EDITOR_APP_STATUS_LINT_UNAVAILABLE: + return this.$options.i18n.unavailableValidation; case EDITOR_APP_STATUS_VALID: return this.$options.i18n.valid; default: @@ -99,7 +114,7 @@ export default { <gl-icon :name="icon" /> <span data-testid="validationMsg">{{ message }}</span> </tooltip-on-truncate> <span v-if="!isEmpty" class="gl-flex-shrink-0 gl-pl-2"> - <gl-link data-testid="learnMoreLink" :href="ymlHelpPagePath"> + <gl-link data-testid="learnMoreLink" :href="helpPath"> {{ $options.i18n.learnMore }} </gl-link> </span> diff --git a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue index 3f50a1225d8..a418668933b 100644 --- a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue +++ b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue @@ -11,6 +11,7 @@ import { EDITOR_APP_STATUS_INVALID, EDITOR_APP_STATUS_LOADING, EDITOR_APP_STATUS_VALID, + EDITOR_APP_STATUS_LINT_UNAVAILABLE, LINT_TAB, MERGED_TAB, TAB_QUERY_PARAM, @@ -106,6 +107,9 @@ export default { isInvalid() { return this.appStatus === EDITOR_APP_STATUS_INVALID; }, + isLintUnavailable() { + return this.appStatus === EDITOR_APP_STATUS_LINT_UNAVAILABLE; + }, isValid() { return this.appStatus === EDITOR_APP_STATUS_VALID; }, @@ -166,6 +170,7 @@ export default { :empty-message="$options.i18n.empty.visualization" :is-empty="isEmpty" :is-invalid="isInvalid" + :is-unavailable="isLintUnavailable" :keep-component-mounted="false" :title="$options.i18n.tabGraph" lazy @@ -179,6 +184,7 @@ export default { class="gl-mb-3" :empty-message="$options.i18n.empty.lint" :is-empty="isEmpty" + :is-unavailable="isLintUnavailable" :title="$options.i18n.tabLint" data-testid="lint-tab" @click="setCurrentTab($options.tabConstants.LINT_TAB)" @@ -192,6 +198,7 @@ export default { :keep-component-mounted="false" :is-empty="isEmpty" :is-invalid="isInvalid" + :is-unavailable="isLintUnavailable" :title="$options.i18n.tabMergedYaml" lazy data-testid="merged-tab" diff --git a/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue b/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue index 7c032441a04..673599da085 100644 --- a/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue +++ b/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue @@ -42,6 +42,9 @@ import { __, s__ } from '~/locale'; export default { i18n: { invalid: __('Your CI/CD configuration syntax is invalid. View Lint tab for more details.'), + unavailable: __( + "We're experiencing difficulties and this tab content is currently unavailable.", + ), }, components: { GlAlert, @@ -66,14 +69,14 @@ export default { isEmpty: { type: Boolean, required: false, - default: null, + default: false, }, isInvalid: { type: Boolean, required: false, - default: null, + default: false, }, - lazy: { + isUnavailable: { type: Boolean, required: false, default: false, @@ -83,6 +86,11 @@ export default { required: false, default: true, }, + lazy: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -109,6 +117,9 @@ export default { <template> <gl-tab :lazy="isLazy" v-bind="$attrs" v-on="$listeners"> <gl-alert v-if="isEmpty" variant="tip">{{ emptyMessage }}</gl-alert> + <gl-alert v-else-if="isUnavailable" variant="danger" :dismissible="false"> + {{ $options.i18n.unavailable }}</gl-alert + > <gl-alert v-else-if="isInvalid" variant="danger">{{ $options.i18n.invalid }}</gl-alert> <template v-else> <slot v-for="slot in slots" :name="slot"></slot> diff --git a/app/assets/javascripts/pipeline_editor/constants.js b/app/assets/javascripts/pipeline_editor/constants.js index a2eaeeef286..bc79b0742e7 100644 --- a/app/assets/javascripts/pipeline_editor/constants.js +++ b/app/assets/javascripts/pipeline_editor/constants.js @@ -6,12 +6,14 @@ export const CI_CONFIG_STATUS_VALID = 'VALID'; // represent the global state of the pipeline editor app. export const EDITOR_APP_STATUS_EMPTY = 'EMPTY'; export const EDITOR_APP_STATUS_INVALID = CI_CONFIG_STATUS_INVALID; +export const EDITOR_APP_STATUS_LINT_UNAVAILABLE = 'LINT_DOWN'; export const EDITOR_APP_STATUS_LOADING = 'LOADING'; export const EDITOR_APP_STATUS_VALID = CI_CONFIG_STATUS_VALID; export const EDITOR_APP_VALID_STATUSES = [ EDITOR_APP_STATUS_EMPTY, EDITOR_APP_STATUS_INVALID, + EDITOR_APP_STATUS_LINT_UNAVAILABLE, EDITOR_APP_STATUS_LOADING, EDITOR_APP_STATUS_VALID, ]; diff --git a/app/assets/javascripts/pipeline_editor/index.js b/app/assets/javascripts/pipeline_editor/index.js index ee93e327b76..04f91cb3d1e 100644 --- a/app/assets/javascripts/pipeline_editor/index.js +++ b/app/assets/javascripts/pipeline_editor/index.js @@ -37,6 +37,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => { emptyStateIllustrationPath, helpPaths, lintHelpPagePath, + lintUnavailableHelpPagePath, needsHelpPagePath, newMergeRequestPath, pipelinePagePath, @@ -124,6 +125,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => { emptyStateIllustrationPath, helpPaths, lintHelpPagePath, + lintUnavailableHelpPagePath, needsHelpPagePath, newMergeRequestPath, pipelinePagePath, diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue index e397054f06a..90f48195c5e 100644 --- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue +++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue @@ -12,8 +12,9 @@ import PipelineEditorMessages from './components/ui/pipeline_editor_messages.vue import { COMMIT_SHA_POLL_INTERVAL, EDITOR_APP_STATUS_EMPTY, - EDITOR_APP_VALID_STATUSES, EDITOR_APP_STATUS_LOADING, + EDITOR_APP_STATUS_LINT_UNAVAILABLE, + EDITOR_APP_VALID_STATUSES, LOAD_FAILURE_UNKNOWN, STARTER_TEMPLATE_NAME, } from './constants'; @@ -51,6 +52,7 @@ export default { failureReasons: [], initialCiFileContent: '', isFetchingCommitSha: false, + isLintUnavailable: false, isNewCiConfigFile: false, lastCommittedContent: '', shouldSkipStartScreen: false, @@ -147,10 +149,19 @@ export default { return { ...ciConfig, stages }; }, result({ data }) { - this.setAppStatus(data?.ciConfig?.status); + if (data?.ciConfig?.status) { + this.setAppStatus(data.ciConfig.status); + if (this.isLintUnavailable) { + this.isLintUnavailable = false; + } + } }, - error(err) { - this.reportFailure(LOAD_FAILURE_UNKNOWN, [String(err)]); + error() { + // We are not using `reportFailure` here because we don't + // need to bring attention to the linter being down. We let + // the user work on their file and if they look at their + // lint status, they will notice that the service is down + this.isLintUnavailable = true; }, watchLoading(isLoading) { if (isLoading) { @@ -247,6 +258,13 @@ export default { this.setAppStatus(EDITOR_APP_STATUS_EMPTY); } }, + isLintUnavailable(flag) { + if (flag) { + // We cannot set this status directly in the `error` + // hook otherwise we get an infinite loop caused by apollo. + this.setAppStatus(EDITOR_APP_STATUS_LINT_UNAVAILABLE); + } + }, }, mounted() { this.loadTemplateFromURL(); @@ -269,14 +287,10 @@ export default { await this.$apollo.queries.initialCiFileContent.refetch(); }, reportFailure(type, reasons = []) { - const isCurrentFailure = this.failureType === type && this.failureReasons[0] === reasons[0]; - - if (!isCurrentFailure) { - this.showFailure = true; - this.failureType = type; - this.failureReasons = reasons; - window.scrollTo({ top: 0, behavior: 'smooth' }); - } + this.showFailure = true; + this.failureType = type; + this.failureReasons = reasons; + window.scrollTo({ top: 0, behavior: 'smooth' }); }, reportSuccess(type) { window.scrollTo({ top: 0, behavior: 'smooth' }); @@ -289,7 +303,10 @@ export default { }, setAppStatus(appStatus) { if (EDITOR_APP_VALID_STATUSES.includes(appStatus)) { - this.$apollo.mutate({ mutation: updateAppStatus, variables: { appStatus } }); + this.$apollo.mutate({ + mutation: updateAppStatus, + variables: { appStatus }, + }); } }, setNewEmptyCiConfigFile() { |