Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-04-19 15:09:04 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-04-19 15:09:04 +0300
commitc6af94ea4ea649171ff930b6bf94c73a5d03edb9 (patch)
treeceef77238b3a275a3a32b4e9f982b6d2f27e0c6b /app/assets/javascripts/pipeline_editor
parent3257ae3af07a4ad026be3c868e74ff82866fc400 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/pipeline_editor')
-rw-r--r--app/assets/javascripts/pipeline_editor/components/editor/ci_config_merged_preview.vue76
-rw-r--r--app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue46
-rw-r--r--app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue66
3 files changed, 107 insertions, 81 deletions
diff --git a/app/assets/javascripts/pipeline_editor/components/editor/ci_config_merged_preview.vue b/app/assets/javascripts/pipeline_editor/components/editor/ci_config_merged_preview.vue
index d61136cda8d..455990f2791 100644
--- a/app/assets/javascripts/pipeline_editor/components/editor/ci_config_merged_preview.vue
+++ b/app/assets/javascripts/pipeline_editor/components/editor/ci_config_merged_preview.vue
@@ -1,29 +1,19 @@
<script>
-import { GlAlert, GlIcon } from '@gitlab/ui';
+import { GlIcon } from '@gitlab/ui';
import { uniqueId } from 'lodash';
-import { __, s__ } from '~/locale';
-import { DEFAULT, INVALID_CI_CONFIG } from '~/pipelines/constants';
+import { s__ } from '~/locale';
import EditorLite from '~/vue_shared/components/editor_lite.vue';
export default {
i18n: {
viewOnlyMessage: s__('Pipelines|Merged YAML is view only'),
},
- errorTexts: {
- [INVALID_CI_CONFIG]: __('Your CI configuration file is invalid.'),
- [DEFAULT]: __('An unknown error occurred.'),
- },
components: {
EditorLite,
- GlAlert,
GlIcon,
},
inject: ['ciConfigPath'],
props: {
- isValid: {
- type: Boolean,
- required: true,
- },
ciConfigData: {
type: Object,
required: true,
@@ -35,66 +25,30 @@ export default {
};
},
computed: {
- failure() {
- switch (this.failureType) {
- case INVALID_CI_CONFIG:
- return this.$options.errorTexts[INVALID_CI_CONFIG];
- default:
- return this.$options.errorTexts[DEFAULT];
- }
- },
fileGlobalId() {
return `${this.ciConfigPath}-${uniqueId()}`;
},
- hasError() {
- return this.failureType;
- },
mergedYaml() {
return this.ciConfigData.mergedYaml;
},
},
- watch: {
- ciConfigData: {
- immediate: true,
- handler() {
- if (!this.isValid) {
- this.reportFailure(INVALID_CI_CONFIG);
- } else if (this.hasError) {
- this.resetFailure();
- }
- },
- },
- },
- methods: {
- reportFailure(errorType) {
- this.failureType = errorType;
- },
- resetFailure() {
- this.failureType = null;
- },
- },
};
</script>
<template>
<div>
- <gl-alert v-if="hasError" variant="danger" :dismissible="false">
- {{ failure }}
- </gl-alert>
- <div v-else>
- <div class="gl-display-flex gl-align-items-center">
- <gl-icon :size="16" name="lock" class="gl-text-gray-500 gl-mr-3" />
- {{ $options.i18n.viewOnlyMessage }}
- </div>
- <div class="gl-mt-3 gl-border-solid gl-border-gray-100 gl-border-1">
- <editor-lite
- ref="editor"
- :value="mergedYaml"
- :file-name="ciConfigPath"
- :file-global-id="fileGlobalId"
- :editor-options="{ readOnly: true }"
- v-on="$listeners"
- />
- </div>
+ <div class="gl-display-flex gl-align-items-center">
+ <gl-icon :size="16" name="lock" class="gl-text-gray-500 gl-mr-3" />
+ {{ $options.i18n.viewOnlyMessage }}
+ </div>
+ <div class="gl-mt-3 gl-border-solid gl-border-gray-100 gl-border-1">
+ <editor-lite
+ ref="editor"
+ :value="mergedYaml"
+ :file-name="ciConfigPath"
+ :file-global-id="fileGlobalId"
+ :editor-options="{ readOnly: true }"
+ v-on="$listeners"
+ />
</div>
</div>
</template>
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 760d395ff2c..5acb3355b23 100644
--- a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
+++ b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
@@ -1,11 +1,13 @@
<script>
-import { GlAlert, GlLoadingIcon, GlTabs, GlTab } from '@gitlab/ui';
+import { GlAlert, GlLoadingIcon, GlTabs } from '@gitlab/ui';
import { s__ } from '~/locale';
import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import {
CREATE_TAB,
+ EDITOR_APP_STATUS_EMPTY,
EDITOR_APP_STATUS_ERROR,
+ EDITOR_APP_STATUS_INVALID,
EDITOR_APP_STATUS_LOADING,
EDITOR_APP_STATUS_VALID,
LINT_TAB,
@@ -24,6 +26,17 @@ export default {
tabGraph: s__('Pipelines|Visualize'),
tabLint: s__('Pipelines|Lint'),
tabMergedYaml: s__('Pipelines|View merged YAML'),
+ empty: {
+ visualization: s__(
+ 'PipelineEditor|The pipeline visualization is displayed when the CI/CD configuration file has valid syntax.',
+ ),
+ lint: s__(
+ 'PipelineEditor|The CI/CD configuration is continuously validated. Errors and warnings are displayed when the CI/CD configuration file is not empty.',
+ ),
+ merge: s__(
+ 'PipelineEditor|The merged YAML view is displayed when the CI/CD configuration file has valid syntax.',
+ ),
+ },
},
errorTexts: {
loadMergedYaml: s__('Pipelines|Could not load merged YAML content'),
@@ -40,7 +53,6 @@ export default {
EditorTab,
GlAlert,
GlLoadingIcon,
- GlTab,
GlTabs,
PipelineGraph,
TextEditor,
@@ -66,6 +78,12 @@ export default {
// Not an invalid config and with `mergedYaml` data missing
return this.appStatus === EDITOR_APP_STATUS_ERROR;
},
+ isEmpty() {
+ return this.appStatus === EDITOR_APP_STATUS_EMPTY;
+ },
+ isInvalid() {
+ return this.appStatus === EDITOR_APP_STATUS_INVALID;
+ },
isValid() {
return this.appStatus === EDITOR_APP_STATUS_VALID;
},
@@ -91,9 +109,12 @@ export default {
>
<text-editor :value="ciFileContent" v-on="$listeners" />
</editor-tab>
- <gl-tab
+ <editor-tab
v-if="glFeatures.ciConfigVisualizationTab"
class="gl-mb-3"
+ :empty-message="$options.i18n.empty.visualization"
+ :is-empty="isEmpty"
+ :is-invalid="isInvalid"
:title="$options.i18n.tabGraph"
lazy
data-testid="visualization-tab"
@@ -101,9 +122,11 @@ export default {
>
<gl-loading-icon v-if="isLoading" size="lg" class="gl-m-3" />
<pipeline-graph v-else :pipeline-data="ciConfigData" />
- </gl-tab>
+ </editor-tab>
<editor-tab
class="gl-mb-3"
+ :empty-message="$options.i18n.empty.lint"
+ :is-empty="isEmpty"
:title="$options.i18n.tabLint"
data-testid="lint-tab"
@click="setCurrentTab($options.tabConstants.LINT_TAB)"
@@ -111,9 +134,13 @@ export default {
<gl-loading-icon v-if="isLoading" size="lg" class="gl-m-3" />
<ci-lint v-else :is-valid="isValid" :ci-config="ciConfigData" />
</editor-tab>
- <gl-tab
+ <editor-tab
v-if="glFeatures.ciConfigMergedTab"
class="gl-mb-3"
+ :empty-message="$options.i18n.empty.merge"
+ :keep-component-mounted="false"
+ :is-empty="isEmpty"
+ :is-invalid="isInvalid"
:title="$options.i18n.tabMergedYaml"
lazy
data-testid="merged-tab"
@@ -123,12 +150,7 @@ export default {
<gl-alert v-else-if="hasAppError" variant="danger" :dismissible="false">
{{ $options.errorTexts.loadMergedYaml }}
</gl-alert>
- <ci-config-merged-preview
- v-else
- :is-valid="isValid"
- :ci-config-data="ciConfigData"
- v-on="$listeners"
- />
- </gl-tab>
+ <ci-config-merged-preview v-else :ci-config-data="ciConfigData" v-on="$listeners" />
+ </editor-tab>
</gl-tabs>
</template>
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 ce8ee7493fe..7c032441a04 100644
--- a/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue
+++ b/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue
@@ -1,6 +1,6 @@
<script>
-import { GlTab } from '@gitlab/ui';
-
+import { GlAlert, GlTab } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
/**
* Wrapper of <gl-tab> to optionally lazily render this tab's content
* when its shown **without dismounting after its hidden**.
@@ -10,10 +10,10 @@ import { GlTab } from '@gitlab/ui';
* API is the same as <gl-tab>, for example:
*
* <gl-tabs>
- * <editor-tab title="Tab 1" :lazy="true">
+ * <editor-tab title="Tab 1" lazy>
* lazily mounted content (gets mounted if this is first tab)
* </editor-tab>
- * <editor-tab title="Tab 2" :lazy="true">
+ * <editor-tab title="Tab 2" lazy>
* lazily mounted content
* </editor-tab>
* <editor-tab title="Tab 3">
@@ -25,10 +25,26 @@ import { GlTab } from '@gitlab/ui';
* so it's contents are not dismounted.
*
* lazy is "false" by default, as in <gl-tab>.
+ *
+ * It is also possible to pass the `isEmpty` and or `isInvalid` to let
+ * the tab component handle that state on its own. For example:
+ *
+ * * <gl-tabs>
+ * <editor-tab-with-status title="Tab 1" :is-empty="isEmpty" :is-invalid="isInvalid">
+ * ...
+ * </editor-tab-with-status>
+ * Will be the same as normal, except it will only render the slot component
+ * if the status is not empty and not invalid. In any of these 2 cases, it will render
+ * a generic component and avoid mounting whatever it received in the slot.
+ * </gl-tabs>
*/
export default {
+ i18n: {
+ invalid: __('Your CI/CD configuration syntax is invalid. View Lint tab for more details.'),
+ },
components: {
+ GlAlert,
GlTab,
// Use a small renderless component to know when the tab content mounts because:
// - gl-tab always gets mounted, even if lazy is `true`. See:
@@ -40,29 +56,63 @@ export default {
},
inheritAttrs: false,
props: {
+ emptyMessage: {
+ type: String,
+ required: false,
+ default: s__(
+ 'PipelineEditor|This tab will be usable when the CI/CD configuration file is populated with valid syntax.',
+ ),
+ },
+ isEmpty: {
+ type: Boolean,
+ required: false,
+ default: null,
+ },
+ isInvalid: {
+ type: Boolean,
+ required: false,
+ default: null,
+ },
lazy: {
type: Boolean,
required: false,
default: false,
},
+ keepComponentMounted: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
data() {
return {
isLazy: this.lazy,
};
},
+ computed: {
+ slots() {
+ return Object.keys(this.$slots);
+ },
+ },
methods: {
onContentMounted() {
// When a child is first mounted make the entire tab
- // permanently mounted by setting 'lazy' to false.
- this.isLazy = false;
+ // permanently mounted by setting 'lazy' to false unless
+ // explicitly opted out.
+ if (this.keepComponentMounted) {
+ this.isLazy = false;
+ }
},
},
};
</script>
<template>
<gl-tab :lazy="isLazy" v-bind="$attrs" v-on="$listeners">
- <slot v-for="slot in Object.keys($slots)" :name="slot"></slot>
- <mount-spy @hook:mounted="onContentMounted" />
+ <gl-alert v-if="isEmpty" variant="tip">{{ emptyMessage }}</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>
+ <mount-spy @hook:mounted="onContentMounted" />
+ </template>
</gl-tab>
</template>