diff options
Diffstat (limited to 'app/assets/javascripts/pipeline_editor')
13 files changed, 174 insertions, 36 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 d9da238358f..4775836fcc6 100644 --- a/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue +++ b/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue @@ -146,12 +146,10 @@ export default { </gl-sprintf> </gl-form-checkbox> </gl-form-group> - <div - class="gl-display-flex gl-justify-content-space-between gl-p-5 gl-bg-gray-10 gl-border-t-gray-100 gl-border-t-solid gl-border-t-1" - > + <div class="gl-display-flex gl-py-5 gl-border-t-gray-100 gl-border-t-solid gl-border-t-1"> <gl-button type="submit" - class="js-no-auto-disable" + class="js-no-auto-disable gl-mr-3" category="primary" variant="confirm" data-qa-selector="commit_changes_button" diff --git a/app/assets/javascripts/pipeline_editor/components/drawer/cards/first_pipeline_card.vue b/app/assets/javascripts/pipeline_editor/components/drawer/cards/first_pipeline_card.vue index 897bd2dcccf..1f74e89f90c 100644 --- a/app/assets/javascripts/pipeline_editor/components/drawer/cards/first_pipeline_card.vue +++ b/app/assets/javascripts/pipeline_editor/components/drawer/cards/first_pipeline_card.vue @@ -1,6 +1,8 @@ <script> import { GlLink, GlSprintf } from '@gitlab/ui'; import { s__ } from '~/locale'; +import Tracking from '~/tracking'; +import { pipelineEditorTrackingOptions } from '../../../constants'; export default { i18n: { @@ -25,7 +27,14 @@ export default { GlLink, GlSprintf, }, + mixins: [Tracking.mixin()], inject: ['runnerHelpPagePath'], + methods: { + trackHelpPageClick() { + const { label, actions } = pipelineEditorTrackingOptions; + this.track(actions.helpDrawerLinks.runners, { label }); + }, + }, }; </script> <template> @@ -38,7 +47,7 @@ export default { <p class="gl-mb-0"> <gl-sprintf :message="$options.i18n.note"> <template #link="{ content }"> - <gl-link :href="runnerHelpPagePath" target="_blank"> + <gl-link :href="runnerHelpPagePath" target="_blank" @click="trackHelpPageClick()"> {{ content }} </gl-link> </template> diff --git a/app/assets/javascripts/pipeline_editor/components/drawer/cards/pipeline_config_reference_card.vue b/app/assets/javascripts/pipeline_editor/components/drawer/cards/pipeline_config_reference_card.vue index 04140434af2..bc9203b9c5b 100644 --- a/app/assets/javascripts/pipeline_editor/components/drawer/cards/pipeline_config_reference_card.vue +++ b/app/assets/javascripts/pipeline_editor/components/drawer/cards/pipeline_config_reference_card.vue @@ -1,8 +1,20 @@ <script> import { GlLink, GlSprintf } from '@gitlab/ui'; import { s__ } from '~/locale'; +import Tracking from '~/tracking'; +import { + CI_EXAMPLES_LINK, + CI_HELP_LINK, + CI_NEEDS_LINK, + CI_YAML_LINK, + pipelineEditorTrackingOptions, +} from '../../../constants'; export default { + CI_EXAMPLES_LINK, + CI_HELP_LINK, + CI_NEEDS_LINK, + CI_YAML_LINK, i18n: { title: s__('PipelineEditorTutorial|⚙️ Pipeline configuration reference'), firstParagraph: s__('PipelineEditorTutorial|Resources to help with your CI/CD configuration:'), @@ -23,7 +35,14 @@ export default { GlLink, GlSprintf, }, + mixins: [Tracking.mixin()], inject: ['ciExamplesHelpPagePath', 'ciHelpPagePath', 'needsHelpPagePath', 'ymlHelpPagePath'], + methods: { + trackHelpPageClick(key) { + const { label, actions } = pipelineEditorTrackingOptions; + this.track(actions.helpDrawerLinks[key], { label }); + }, + }, }; </script> <template> @@ -34,7 +53,11 @@ export default { <li> <gl-sprintf :message="$options.i18n.browseExamples"> <template #link="{ content }"> - <gl-link :href="ciExamplesHelpPagePath" target="_blank"> + <gl-link + :href="ciExamplesHelpPagePath" + target="_blank" + @click="trackHelpPageClick($options.CI_EXAMPLES_LINK)" + > {{ content }} </gl-link> </template> @@ -43,7 +66,11 @@ export default { <li> <gl-sprintf :message="$options.i18n.viewSyntaxRef"> <template #link="{ content }"> - <gl-link :href="ymlHelpPagePath" target="_blank"> + <gl-link + :href="ymlHelpPagePath" + target="_blank" + @click="trackHelpPageClick($options.CI_YAML_LINK)" + > {{ content }} </gl-link> </template> @@ -52,7 +79,11 @@ export default { <li> <gl-sprintf :message="$options.i18n.learnMore"> <template #link="{ content }"> - <gl-link :href="ciHelpPagePath" target="_blank"> + <gl-link + :href="ciHelpPagePath" + target="_blank" + @click="trackHelpPageClick($options.CI_HELP_LINK)" + > {{ content }} </gl-link> </template> @@ -61,7 +92,11 @@ export default { <li> <gl-sprintf :message="$options.i18n.needs"> <template #link="{ content }"> - <gl-link :href="needsHelpPagePath" target="_blank"> + <gl-link + :href="needsHelpPagePath" + target="_blank" + @click="trackHelpPageClick($options.CI_NEEDS_LINK)" + > {{ content }} </gl-link> </template> diff --git a/app/assets/javascripts/pipeline_editor/components/editor/ci_editor_header.vue b/app/assets/javascripts/pipeline_editor/components/editor/ci_editor_header.vue index 9765d669fc1..65a2a6b56e4 100644 --- a/app/assets/javascripts/pipeline_editor/components/editor/ci_editor_header.vue +++ b/app/assets/javascripts/pipeline_editor/components/editor/ci_editor_header.vue @@ -22,12 +22,21 @@ export default { }, methods: { toggleDrawer() { - this.$emit(this.showDrawer ? 'close-drawer' : 'open-drawer'); + if (this.showDrawer) { + this.$emit('close-drawer'); + } else { + this.$emit('open-drawer'); + this.trackHelpDrawerClick(); + } + }, + trackHelpDrawerClick() { + const { label, actions } = pipelineEditorTrackingOptions; + this.track(actions.openHelpDrawer, { label }); }, trackTemplateBrowsing() { const { label, actions } = pipelineEditorTrackingOptions; - this.track(actions.browse_templates, { label }); + this.track(actions.browseTemplates, { label }); }, }, }; diff --git a/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue b/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue index ead2076ec3b..4398ba67d47 100644 --- a/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue +++ b/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue @@ -246,7 +246,7 @@ export default { </template> <template #default> <gl-dropdown-item v-if="isBranchesLoading" key="loading"> - <gl-loading-icon size="md" /> + <gl-loading-icon size="lg" /> </gl-dropdown-item> </template> </gl-infinite-scroll> diff --git a/app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue b/app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue index 58df98d0fb7..8e95fad1e48 100644 --- a/app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue +++ b/app/assets/javascripts/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue @@ -1,7 +1,6 @@ <script> import { GlButton } from '@gitlab/ui'; import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.query.graphql'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { EDITOR_APP_STATUS_EMPTY, EDITOR_APP_STATUS_LOADING } from '../../constants'; import FileTreePopover from '../popovers/file_tree_popover.vue'; import BranchSwitcher from './branch_switcher.vue'; @@ -12,7 +11,6 @@ export default { FileTreePopover, GlButton, }, - mixins: [glFeatureFlagMixin()], props: { hasUnsavedChanges: { type: Boolean, @@ -43,11 +41,7 @@ export default { return this.appStatus === EDITOR_APP_STATUS_LOADING; }, showFileTreeToggle() { - return ( - this.glFeatures.pipelineEditorFileTree && - !this.isNewCiConfigFile && - this.appStatus !== EDITOR_APP_STATUS_EMPTY - ); + return !this.isNewCiConfigFile && this.appStatus !== EDITOR_APP_STATUS_EMPTY; }, }, methods: { diff --git a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results.vue b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results.vue index 13e254f138a..9a789ccab4d 100644 --- a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results.vue +++ b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results.vue @@ -17,7 +17,7 @@ export default { text: __('Syntax is incorrect.'), }, includesText: __( - 'CI configuration validated, including all configuration added with the %{codeStart}includes%{codeEnd} keyword. %{link}', + 'CI configuration validated, including all configuration added with the %{codeStart}include%{codeEnd} keyword. %{link}', ), warningTitle: __('The form contains the following warning:'), fields: [ 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 da31fc62d09..08d246a9a00 100644 --- a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue +++ b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue @@ -15,13 +15,15 @@ import { MERGED_TAB, TAB_QUERY_PARAM, TABS_INDEX, + VALIDATE_TAB, VISUALIZE_TAB, } from '../constants'; import getAppStatus from '../graphql/queries/client/app_status.query.graphql'; import CiConfigMergedPreview from './editor/ci_config_merged_preview.vue'; import CiEditorHeader from './editor/ci_editor_header.vue'; -import TextEditor from './editor/text_editor.vue'; import CiLint from './lint/ci_lint.vue'; +import CiValidate from './validate/ci_validate.vue'; +import TextEditor from './editor/text_editor.vue'; import EditorTab from './ui/editor_tab.vue'; import WalkthroughPopover from './popovers/walkthrough_popover.vue'; @@ -31,6 +33,7 @@ export default { tabGraph: s__('Pipelines|Visualize'), tabLint: s__('Pipelines|Lint'), tabMergedYaml: s__('Pipelines|View merged YAML'), + tabValidate: s__('Pipelines|Validate'), empty: { visualization: s__( 'PipelineEditor|The pipeline visualization is displayed when the CI/CD configuration file has valid syntax.', @@ -53,12 +56,14 @@ export default { CREATE_TAB, LINT_TAB, MERGED_TAB, + VALIDATE_TAB, VISUALIZE_TAB, }, components: { CiConfigMergedPreview, CiEditorHeader, CiLint, + CiValidate, EditorTab, GlAlert, GlLoadingIcon, @@ -121,9 +126,10 @@ export default { }, created() { const [tabQueryParam] = getParameterValues(TAB_QUERY_PARAM); + const tabName = Object.keys(TABS_INDEX)[tabQueryParam]; - if (tabQueryParam && TABS_INDEX[tabQueryParam]) { - this.setDefaultTab(tabQueryParam); + if (tabName) { + this.setDefaultTab(tabName); } }, methods: { @@ -180,6 +186,17 @@ export default { <pipeline-graph v-else :pipeline-data="ciConfigData" /> </editor-tab> <editor-tab + v-if="glFeatures.simulatePipeline" + class="gl-mb-3" + data-testid="validate-tab" + :title="$options.i18n.tabValidate" + @click="setCurrentTab($options.tabConstants.VALIDATE_TAB)" + > + <gl-loading-icon v-if="isLoading" size="lg" class="gl-m-3" /> + <ci-validate v-else /> + </editor-tab> + <editor-tab + v-else class="gl-mb-3" :empty-message="$options.i18n.empty.lint" :is-empty="isEmpty" diff --git a/app/assets/javascripts/pipeline_editor/components/popovers/file_tree_popover.vue b/app/assets/javascripts/pipeline_editor/components/popovers/file_tree_popover.vue index 6270429535d..efa6a54c638 100644 --- a/app/assets/javascripts/pipeline_editor/components/popovers/file_tree_popover.vue +++ b/app/assets/javascripts/pipeline_editor/components/popovers/file_tree_popover.vue @@ -26,11 +26,8 @@ export default { this.showPopover = localStorage.getItem(FILE_TREE_POPOVER_DISMISSED_KEY) !== 'true'; }, methods: { - closePopover() { - this.showPopover = false; - }, dismissPermanently() { - this.closePopover(); + this.showPopover = false; localStorage.setItem(FILE_TREE_POPOVER_DISMISSED_KEY, 'true'); }, }, @@ -48,7 +45,7 @@ export default { data-qa-selector="file_tree_popover" @close-button-clicked="dismissPermanently" > - <div v-outside="closePopover" class="gl-font-base gl-mb-3"> + <div v-outside="dismissPermanently" class="gl-font-base gl-mb-3"> <gl-sprintf :message="$options.i18n.description"> <template #link="{ content }"> <gl-link :href="includesHelpPagePath" target="_blank">{{ content }}</gl-link> diff --git a/app/assets/javascripts/pipeline_editor/components/validate/ci_validate.vue b/app/assets/javascripts/pipeline_editor/components/validate/ci_validate.vue new file mode 100644 index 00000000000..5f26318497b --- /dev/null +++ b/app/assets/javascripts/pipeline_editor/components/validate/ci_validate.vue @@ -0,0 +1,65 @@ +<script> +import { GlButton, GlDropdown, GlTooltipDirective, GlSprintf } from '@gitlab/ui'; +import { s__, __ } from '~/locale'; + +export const i18n = { + help: __('Help'), + pipelineSource: s__('PipelineEditor|Pipeline Source'), + pipelineSourceDefault: s__('PipelineEditor|Git push event to the default branch'), + pipelineSourceTooltip: s__('PipelineEditor|Other pipeline sources are not available yet.'), + title: s__('PipelineEditor|Validate pipeline under selected conditions'), + contentNote: s__( + 'PipelineEditor|Current content in the Edit tab will be used for the simulation.', + ), + simulationNote: s__( + 'PipelineEditor|Pipeline behavior will be simulated including the %{codeStart}rules%{codeEnd} %{codeStart}only%{codeEnd} %{codeStart}except%{codeEnd} and %{codeStart}needs%{codeEnd} job dependencies.', + ), + cta: s__('PipelineEditor|Validate pipeline'), +}; + +export default { + name: 'CiValidateTab', + components: { + GlButton, + GlDropdown, + GlSprintf, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + inject: ['validateTabIllustrationPath'], + i18n, +}; +</script> + +<template> + <div> + <div class="gl-mt-3"> + <label>{{ $options.i18n.pipelineSource }}</label> + <gl-dropdown + v-gl-tooltip.hover + :title="$options.i18n.pipelineSourceTooltip" + :text="$options.i18n.pipelineSourceDefault" + disabled + data-testid="pipeline-source" + /> + </div> + <div class="gl-display-flex gl-flex-direction-column gl-align-items-center gl-mt-11"> + <img :src="validateTabIllustrationPath" /> + <h1 class="gl-font-size-h1 gl-mb-6">{{ $options.i18n.title }}</h1> + <ul> + <li class="gl-mb-3">{{ $options.i18n.contentNote }}</li> + <li class="gl-mb-3"> + <gl-sprintf :message="$options.i18n.simulationNote"> + <template #code="{ content }"> + <code>{{ content }}</code> + </template> + </gl-sprintf> + </li> + </ul> + <gl-button variant="confirm" class="gl-mt-3" data-qa-selector="simulate_pipeline"> + {{ $options.i18n.cta }} + </gl-button> + </div> + </div> +</template> diff --git a/app/assets/javascripts/pipeline_editor/constants.js b/app/assets/javascripts/pipeline_editor/constants.js index ff7c742f588..8f688e6ba76 100644 --- a/app/assets/javascripts/pipeline_editor/constants.js +++ b/app/assets/javascripts/pipeline_editor/constants.js @@ -32,13 +32,15 @@ export const PIPELINE_FAILURE = 'PIPELINE_FAILURE'; export const CREATE_TAB = 'CREATE_TAB'; export const LINT_TAB = 'LINT_TAB'; export const MERGED_TAB = 'MERGED_TAB'; +export const VALIDATE_TAB = 'VALIDATE_TAB'; export const VISUALIZE_TAB = 'VISUALIZE_TAB'; export const TABS_INDEX = { [CREATE_TAB]: '0', [VISUALIZE_TAB]: '1', [LINT_TAB]: '2', - [MERGED_TAB]: '3', + [VALIDATE_TAB]: '3', + [MERGED_TAB]: '4', }; export const TAB_QUERY_PARAM = 'tab'; @@ -55,10 +57,25 @@ export const FILE_TREE_TIP_DISMISSED_KEY = 'pipeline_editor_file_tree_tip_dismis export const STARTER_TEMPLATE_NAME = 'Getting-Started'; +export const CI_EXAMPLES_LINK = 'CI_EXAMPLES_LINK'; +export const CI_HELP_LINK = 'CI_HELP_LINK'; +export const CI_NEEDS_LINK = 'CI_NEEDS_LINK'; +export const CI_RUNNERS_LINK = 'CI_RUNNERS_LINK'; +export const CI_YAML_LINK = 'CI_YAML_LINK'; + export const pipelineEditorTrackingOptions = { label: 'pipeline_editor', actions: { - browse_templates: 'browse_templates', + browseTemplates: 'browse_templates', + closeHelpDrawer: 'close_help_drawer', + helpDrawerLinks: { + [CI_EXAMPLES_LINK]: 'visit_help_drawer_link_ci_examples', + [CI_HELP_LINK]: 'visit_help_drawer_link_ci_help', + [CI_NEEDS_LINK]: 'visit_help_drawer_link_needs', + [CI_RUNNERS_LINK]: 'visit_help_drawer_link_runners', + [CI_YAML_LINK]: 'visit_help_drawer_link_yaml', + }, + openHelpDrawer: 'open_help_drawer', }, }; diff --git a/app/assets/javascripts/pipeline_editor/index.js b/app/assets/javascripts/pipeline_editor/index.js index e13d9cf9df0..4caa253b85e 100644 --- a/app/assets/javascripts/pipeline_editor/index.js +++ b/app/assets/javascripts/pipeline_editor/index.js @@ -41,6 +41,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => { projectNamespace, runnerHelpPagePath, totalBranches, + validateTabIllustrationPath, ymlHelpPagePath, } = el.dataset; @@ -130,6 +131,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => { projectNamespace, runnerHelpPagePath, totalBranches: parseInt(totalBranches, 10), + validateTabIllustrationPath, ymlHelpPagePath, }, render(h) { diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue index 59022a91322..f26cdd8b017 100644 --- a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue +++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue @@ -1,7 +1,6 @@ <script> import { GlModal } from '@gitlab/ui'; import { __ } from '~/locale'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import CommitSection from './components/commit/commit_section.vue'; import PipelineEditorDrawer from './components/drawer/pipeline_editor_drawer.vue'; import PipelineEditorFileNav from './components/file_nav/pipeline_editor_file_nav.vue'; @@ -34,7 +33,6 @@ export default { PipelineEditorHeader, PipelineEditorTabs, }, - mixins: [glFeatureFlagMixin()], props: { ciConfigData: { type: Object, @@ -76,9 +74,6 @@ export default { includesFiles() { return this.ciConfigData?.includes || []; }, - isFileTreeVisible() { - return this.showFileTree && this.glFeatures.pipelineEditorFileTree; - }, }, mounted() { this.showFileTree = JSON.parse(localStorage.getItem(FILE_TREE_DISPLAY_KEY)) || false; @@ -140,7 +135,7 @@ export default { /> <div class="gl-display-flex gl-w-full gl-sm-flex-direction-column"> <pipeline-editor-file-tree - v-if="isFileTreeVisible" + v-if="showFileTree" class="gl-flex-shrink-0" :includes="includesFiles" /> |