summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipeline_editor
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/pipeline_editor')
-rw-r--r--app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue1
-rw-r--r--app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue10
-rw-r--r--app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue4
-rw-r--r--app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue22
-rw-r--r--app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue8
-rw-r--r--app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue17
-rw-r--r--app/assets/javascripts/pipeline_editor/constants.js2
-rw-r--r--app/assets/javascripts/pipeline_editor/index.js2
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue43
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue2
10 files changed, 85 insertions, 26 deletions
diff --git a/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue b/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue
index 9f82d4a5395..ca78f194a82 100644
--- a/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue
+++ b/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue
@@ -142,6 +142,7 @@ export default {
class="js-no-auto-disable"
category="primary"
variant="confirm"
+ data-qa-selector="commit_changes_button"
:disabled="submitDisabled"
:loading="isSaving"
>
diff --git a/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue b/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
index 92fa411d5af..bfbf24c6b13 100644
--- a/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
+++ b/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
@@ -15,12 +15,10 @@ export default {
onCiConfigUpdate(content) {
this.$emit('updateCiConfig', content);
},
- registerCiSchema() {
+ registerCiSchema({ detail: { instance } }) {
if (this.glFeatures.schemaLinting) {
- const editorInstance = this.$refs.editor.getEditor();
-
- editorInstance.use({ definition: CiSchemaExtension });
- editorInstance.registerCiSchema();
+ instance.use({ definition: CiSchemaExtension });
+ instance.registerCiSchema();
}
},
},
@@ -33,7 +31,7 @@ export default {
ref="editor"
:file-name="ciConfigPath"
v-bind="$attrs"
- @[$options.readyEvent]="registerCiSchema"
+ @[$options.readyEvent]="registerCiSchema($event)"
@input="onCiConfigUpdate"
v-on="$listeners"
/>
diff --git a/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue b/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
index 16ad648afca..72b492a5877 100644
--- a/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
+++ b/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
@@ -153,7 +153,9 @@ export default {
<span class="gl-font-weight-bold">
<gl-sprintf :message="$options.i18n.pipelineInfo">
<template #id="{ content }">
- <span data-testid="pipeline-id"> {{ content }}{{ pipelineId }} </span>
+ <span data-testid="pipeline-id" data-qa-selector="pipeline_id_content">
+ {{ content }}{{ pipelineId }}
+ </span>
</template>
<template #status>{{ status.text }}</template>
<template #commit>
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..23f1592cac1 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:
@@ -96,10 +111,13 @@ export default {
<span v-else class="gl-display-inline-flex gl-white-space-nowrap gl-max-w-full">
<tooltip-on-truncate :title="message" class="gl-text-truncate">
- <gl-icon :name="icon" /> <span data-testid="validationMsg">{{ message }}</span>
+ <gl-icon :name="icon" />
+ <span data-qa-selector="validation_message_content" 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..c75b1d4bb11 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;
},
@@ -142,6 +146,7 @@ export default {
<template>
<gl-tabs
class="file-editor gl-mb-3"
+ data-qa-selector="file_editor_container"
:query-param-name="$options.query.TAB_QUERY_PARAM"
sync-active-tab-with-query-params
>
@@ -166,6 +171,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 +185,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 +199,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() {
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
index 8e8f31a4acc..96680080f0c 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
@@ -90,7 +90,7 @@ export default {
</script>
<template>
- <div class="gl-pr-9 gl-transition-medium gl-w-full">
+ <div class="gl-pr-10 gl-transition-medium gl-w-full">
<gl-modal
v-if="showSwitchBranchModal"
visible