diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-17 21:09:19 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-17 21:09:19 +0300 |
commit | c0ef148ef349f0d13331638ab90f5d9e9d2175ba (patch) | |
tree | fd826213aa30339d8fee4bcc1bf35c6e40639823 /app/assets/javascripts | |
parent | c982bb363b3a0390a274197f410a1609a4667760 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts')
15 files changed, 223 insertions, 70 deletions
diff --git a/app/assets/javascripts/blob/blob_file_dropzone.js b/app/assets/javascripts/blob/blob_file_dropzone.js index e72c5c90986..445602a8765 100644 --- a/app/assets/javascripts/blob/blob_file_dropzone.js +++ b/app/assets/javascripts/blob/blob_file_dropzone.js @@ -3,6 +3,7 @@ import Dropzone from 'dropzone'; import $ from 'jquery'; import { sprintf, __ } from '~/locale'; +import { trackUploadFileFormSubmitted } from '~/projects/upload_file_experiment'; import { HIDDEN_CLASS } from '../lib/utils/constants'; import csrf from '../lib/utils/csrf'; import { visitUrl } from '../lib/utils/url_utility'; @@ -83,6 +84,9 @@ export default class BlobFileDropzone { submitButton.on('click', (e) => { e.preventDefault(); e.stopPropagation(); + + trackUploadFileFormSubmitted(); + if (dropzone[0].dropzone.getQueuedFiles().length === 0) { // eslint-disable-next-line no-alert alert(__('Please select a file')); diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js index 173c82ef9b0..6d9b56b4bb8 100644 --- a/app/assets/javascripts/blob_edit/blob_bundle.js +++ b/app/assets/javascripts/blob_edit/blob_bundle.js @@ -4,6 +4,7 @@ import $ from 'jquery'; import initPopover from '~/blob/suggest_gitlab_ci_yml'; import { deprecatedCreateFlash as createFlash } from '~/flash'; import { disableButtonIfEmptyField, setCookie } from '~/lib/utils/common_utils'; +import { initUploadFileTrigger } from '~/projects/upload_file_experiment'; import Tracking from '~/tracking'; import BlobFileDropzone from '../blob/blob_file_dropzone'; import NewCommitForm from '../new_commit_form'; @@ -47,6 +48,7 @@ export const initUploadForm = () => { new NewCommitForm(uploadBlobForm); disableButtonIfEmptyField(uploadBlobForm.find('.js-commit-message'), '.btn-upload-file'); + initUploadFileTrigger(); } }; diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js index 920ffde3e32..a71bf0d874d 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js +++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js @@ -34,7 +34,6 @@ export default () => { helpPagePath: pipelineTableViewEl.dataset.helpPagePath, emptyStateSvgPath: pipelineTableViewEl.dataset.emptyStateSvgPath, errorStateSvgPath: pipelineTableViewEl.dataset.errorStateSvgPath, - autoDevopsHelpPath: pipelineTableViewEl.dataset.helpAutoDevopsPath, }, }); }, diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.vue b/app/assets/javascripts/commit/pipelines/pipelines_table.vue index 787152d00ef..926f5b82b66 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_table.vue +++ b/app/assets/javascripts/commit/pipelines/pipelines_table.vue @@ -29,10 +29,6 @@ export default { type: String, required: true, }, - autoDevopsHelpPath: { - type: String, - required: true, - }, errorStateSvgPath: { type: String, required: true, @@ -212,7 +208,6 @@ export default { <pipelines-table-component :pipelines="state.pipelines" :update-graph-dropdown="updateGraphDropdown" - :auto-devops-help-path="autoDevopsHelpPath" :view-type="viewType" > <template #table-header-actions> diff --git a/app/assets/javascripts/experiment_tracking.js b/app/assets/javascripts/experiment_tracking.js new file mode 100644 index 00000000000..4611af3f857 --- /dev/null +++ b/app/assets/javascripts/experiment_tracking.js @@ -0,0 +1,25 @@ +import { get } from 'lodash'; +import Tracking from '~/tracking'; + +const TRACKING_CONTEXT_SCHEMA = 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0'; + +export default class ExperimentTracking { + constructor(experimentName, { label } = {}) { + this.label = label; + this.experimentData = get(window, ['gon', 'global', 'experiment', experimentName]); + } + + event(action) { + if (!this.experimentData) { + return false; + } + + return Tracking.event(document.body.dataset.page, action, { + label: this.label, + context: { + schema: TRACKING_CONTEXT_SCHEMA, + data: this.experimentData, + }, + }); + } +} diff --git a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue index af4e9acf4ba..22a767cfaae 100644 --- a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue +++ b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue @@ -1,7 +1,16 @@ <script> -import { GlFormGroup, GlFormCheckbox, GlFormRadio } from '@gitlab/ui'; +import { + GlFormGroup, + GlFormCheckbox, + GlFormRadio, + GlFormInput, + GlLink, + GlSprintf, +} from '@gitlab/ui'; import { mapGetters } from 'vuex'; +import { helpPagePath } from '~/helpers/help_page_helper'; import { s__ } from '~/locale'; +import eventHub from '../event_hub'; const commentDetailOptions = [ { @@ -18,12 +27,41 @@ const commentDetailOptions = [ }, ]; +const ISSUE_TRANSITION_AUTO = 'auto'; +const ISSUE_TRANSITION_CUSTOM = 'custom'; + +const issueTransitionOptions = [ + { + value: ISSUE_TRANSITION_AUTO, + label: s__('JiraService|Move to Done'), + help: s__( + 'JiraService|Automatically transitions Jira issues to the "Done" category. %{linkStart}Learn more%{linkEnd}', + ), + link: helpPagePath('user/project/integrations/jira.html', { + anchor: 'automatic-issue-transitions', + }), + }, + { + value: ISSUE_TRANSITION_CUSTOM, + label: s__('JiraService|Use custom transitions'), + help: s__( + 'JiraService|Set a custom final state by using transition IDs. %{linkStart}Learn about transition IDs%{linkEnd}', + ), + link: helpPagePath('user/project/integrations/jira.html', { + anchor: 'custom-issue-transitions', + }), + }, +]; + export default { name: 'JiraTriggerFields', components: { GlFormGroup, GlFormCheckbox, GlFormRadio, + GlFormInput, + GlLink, + GlSprintf, }, props: { initialTriggerCommit: { @@ -43,21 +81,52 @@ export default { required: false, default: 'standard', }, + initialJiraIssueTransitionId: { + type: String, + required: false, + default: '', + }, }, data() { return { + validated: false, triggerCommit: this.initialTriggerCommit, triggerMergeRequest: this.initialTriggerMergeRequest, enableComments: this.initialEnableComments, commentDetail: this.initialCommentDetail, + jiraIssueTransitionId: this.initialJiraIssueTransitionId, + issueTransitionMode: this.initialJiraIssueTransitionId.length + ? ISSUE_TRANSITION_CUSTOM + : ISSUE_TRANSITION_AUTO, commentDetailOptions, + issueTransitionOptions, }; }, computed: { ...mapGetters(['isInheriting']), - showEnableComments() { + showTriggerSettings() { return this.triggerCommit || this.triggerMergeRequest; }, + validIssueTransitionId() { + return !this.validated || this.jiraIssueTransitionId.length > 0; + }, + }, + created() { + eventHub.$on('validateForm', this.validateForm); + }, + beforeDestroy() { + eventHub.$off('validateForm', this.validateForm); + }, + methods: { + validateForm() { + this.validated = true; + }, + showCustomIssueTransitions(currentOption) { + return ( + this.issueTransitionMode === ISSUE_TRANSITION_CUSTOM && + currentOption === ISSUE_TRANSITION_CUSTOM + ); + }, }, }; </script> @@ -89,7 +158,7 @@ export default { </gl-form-group> <gl-form-group - v-show="showEnableComments" + v-show="showTriggerSettings" :label="s__('Integrations|Comment settings:')" label-for="service[comment_on_event_enabled]" class="gl-pl-6" @@ -106,7 +175,7 @@ export default { </gl-form-group> <gl-form-group - v-show="showEnableComments && enableComments" + v-show="showTriggerSettings && enableComments" :label="s__('Integrations|Comment detail:')" label-for="service[comment_detail]" class="gl-pl-9" @@ -126,5 +195,51 @@ export default { </template> </gl-form-radio> </gl-form-group> + + <gl-form-group + v-show="showTriggerSettings" + :label="s__('JiraService|Transition Jira issues to their final state:')" + class="gl-pl-6" + data-testid="issue-transition-settings" + > + <input type="hidden" name="service[jira_issue_transition_id]" value="" /> + + <gl-form-radio + v-for="issueTransitionOption in issueTransitionOptions" + :key="issueTransitionOption.value" + v-model="issueTransitionMode" + :value="issueTransitionOption.value" + :disabled="isInheriting" + :data-qa-selector="`service_issue_transition_mode_${issueTransitionOption.value}`" + > + {{ issueTransitionOption.label }} + + <template v-if="showCustomIssueTransitions(issueTransitionOption.value)"> + <gl-form-input + v-model="jiraIssueTransitionId" + name="service[jira_issue_transition_id]" + type="text" + class="gl-my-3" + data-qa-selector="service_jira_issue_transition_id_field" + :placeholder="s__('JiraService|For example, 12, 24')" + :disabled="isInheriting" + :required="true" + :state="validIssueTransitionId" + /> + + <span class="invalid-feedback"> + {{ s__('This field is required.') }} + </span> + </template> + + <template #help> + <gl-sprintf :message="issueTransitionOption.help"> + <template #link="{ content }"> + <gl-link :href="issueTransitionOption.link" target="_blank">{{ content }}</gl-link> + </template> + </gl-sprintf> + </template> + </gl-form-radio> + </gl-form-group> </div> </template> diff --git a/app/assets/javascripts/integrations/edit/index.js b/app/assets/javascripts/integrations/edit/index.js index ab9bdd9ca2e..1ae353ab6e3 100644 --- a/app/assets/javascripts/integrations/edit/index.js +++ b/app/assets/javascripts/integrations/edit/index.js @@ -28,6 +28,7 @@ function parseDatasetToProps(data) { testPath, resetPath, vulnerabilitiesIssuetype, + jiraIssueTransitionId, ...booleanAttributes } = data; const { @@ -59,6 +60,7 @@ function parseDatasetToProps(data) { initialTriggerMergeRequest: mergeRequestEvents, initialEnableComments: enableComments, initialCommentDetail: commentDetail, + initialJiraIssueTransitionId: jiraIssueTransitionId, }, jiraIssuesProps: { showJiraIssuesIntegration, diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 4dab796d8a4..64c49b4276e 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -364,7 +364,6 @@ export default class MergeRequestTabs { helpPagePath: pipelineTableViewEl.dataset.helpPagePath, emptyStateSvgPath: pipelineTableViewEl.dataset.emptyStateSvgPath, errorStateSvgPath: pipelineTableViewEl.dataset.errorStateSvgPath, - autoDevopsHelpPath: pipelineTableViewEl.dataset.helpAutoDevopsPath, canCreatePipelineInTargetProject: Boolean( mrWidgetData?.can_create_pipeline_in_target_project, ), diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js index 0494dad6e33..e5ec9976ac5 100644 --- a/app/assets/javascripts/pages/projects/show/index.js +++ b/app/assets/javascripts/pages/projects/show/index.js @@ -24,9 +24,12 @@ new UserCallout({ }); // Project show page loads different overview content based on user preferences -const treeSlider = document.getElementById('js-tree-list'); -if (treeSlider) { + +if (document.querySelector('.js-upload-blob-form')) { initUploadForm(); +} + +if (document.getElementById('js-tree-list')) { initTree(); } diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue index 823ada133d2..a61ffe8f0fc 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue @@ -1,5 +1,6 @@ <script> import { GlLink, GlPopover, GlSprintf, GlTooltipDirective, GlBadge } from '@gitlab/ui'; +import { helpPagePath } from '~/helpers/help_page_helper'; import { SCHEDULE_ORIGIN } from '../../constants'; export default { @@ -26,10 +27,6 @@ export default { type: String, required: true, }, - autoDevopsHelpPath: { - type: String, - required: true, - }, }, computed: { user() { @@ -44,6 +41,12 @@ export default { this.pipeline?.project?.full_path !== `/${this.targetProjectFullPath}`, ); }, + autoDevopsTagId() { + return `pipeline-url-autodevops-${this.pipeline.id}`; + }, + autoDevopsHelpPath() { + return helpPagePath('topics/autodevops/index.md'); + }, }, }; </script> @@ -103,38 +106,43 @@ export default { data-testid="pipeline-url-failure" >{{ __('error') }}</gl-badge > - <gl-link - v-if="pipeline.flags.auto_devops" - :id="`pipeline-url-autodevops-${pipeline.id}`" - tabindex="0" - data-testid="pipeline-url-autodevops" - role="button" - ><gl-badge variant="info" size="sm">{{ __('Auto DevOps') }}</gl-badge></gl-link - > - <gl-popover - :target="`pipeline-url-autodevops-${pipeline.id}`" - triggers="focus" - placement="top" - > - <template #title> - <div class="gl-font-weight-normal gl-line-height-normal"> - <gl-sprintf - :message=" - __( - 'This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}', - ) - " - > - <template #strong="{ content }"> - <b>{{ content }}</b> - </template> - </gl-sprintf> - </div> - </template> - <gl-link :href="autoDevopsHelpPath" target="_blank" rel="noopener noreferrer nofollow">{{ - __('Learn more about Auto DevOps') - }}</gl-link> - </gl-popover> + <template v-if="pipeline.flags.auto_devops"> + <gl-link + :id="autoDevopsTagId" + tabindex="0" + data-testid="pipeline-url-autodevops" + role="button" + > + <gl-badge variant="info" size="sm"> + {{ __('Auto DevOps') }} + </gl-badge> + </gl-link> + <gl-popover :target="autoDevopsTagId" triggers="focus" placement="top"> + <template #title> + <div class="gl-font-weight-normal gl-line-height-normal"> + <gl-sprintf + :message=" + __( + 'This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}', + ) + " + > + <template #strong="{ content }"> + <b>{{ content }}</b> + </template> + </gl-sprintf> + </div> + </template> + <gl-link + :href="autoDevopsHelpPath" + data-testid="pipeline-url-autodevops-link" + target="_blank" + > + {{ __('Learn more about Auto DevOps') }} + </gl-link> + </gl-popover> + </template> + <gl-badge v-if="pipeline.flags.stuck" variant="warning" diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue index 48009a9fcb8..30a099fd1c7 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue @@ -68,10 +68,6 @@ export default { type: String, required: true, }, - autoDevopsHelpPath: { - type: String, - required: true, - }, hasGitlabCi: { type: Boolean, required: true, @@ -362,7 +358,6 @@ export default { :pipelines="state.pipelines" :pipeline-schedule-url="pipelineScheduleUrl" :update-graph-dropdown="updateGraphDropdown" - :auto-devops-help-path="autoDevopsHelpPath" :view-type="viewType" /> </div> diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue index 24c67184e56..fdc8c3e1866 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue @@ -32,10 +32,6 @@ export default { required: false, default: false, }, - autoDevopsHelpPath: { - type: String, - required: true, - }, viewType: { type: String, required: true, @@ -102,7 +98,6 @@ export default { :pipeline="model" :pipeline-schedule-url="pipelineScheduleUrl" :update-graph-dropdown="updateGraphDropdown" - :auto-devops-help-path="autoDevopsHelpPath" :view-type="viewType" :canceling-pipeline="cancelingPipeline" /> diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue index 572abe2a24a..68deca313eb 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue @@ -47,10 +47,6 @@ export default { required: false, default: false, }, - autoDevopsHelpPath: { - type: String, - required: true, - }, viewType: { type: String, required: true, @@ -194,11 +190,7 @@ export default { </div> </div> - <pipeline-url - :pipeline="pipeline" - :pipeline-schedule-url="pipelineScheduleUrl" - :auto-devops-help-path="autoDevopsHelpPath" - /> + <pipeline-url :pipeline="pipeline" :pipeline-schedule-url="pipelineScheduleUrl" /> <pipeline-triggerer :pipeline="pipeline" /> <div class="table-section section-wrap section-20"> diff --git a/app/assets/javascripts/pipelines/pipelines_index.js b/app/assets/javascripts/pipelines/pipelines_index.js index 7bcc51e18e5..a7dea2cf103 100644 --- a/app/assets/javascripts/pipelines/pipelines_index.js +++ b/app/assets/javascripts/pipelines/pipelines_index.js @@ -27,7 +27,6 @@ export const initPipelinesIndex = (selector = '#pipelines-list-vue') => { emptyStateSvgPath, errorStateSvgPath, noPipelinesSvgPath, - autoDevopsHelpPath, newPipelinePath, canCreatePipeline, hasGitlabCi, @@ -60,7 +59,6 @@ export const initPipelinesIndex = (selector = '#pipelines-list-vue') => { emptyStateSvgPath, errorStateSvgPath, noPipelinesSvgPath, - autoDevopsHelpPath, newPipelinePath, canCreatePipeline: parseBoolean(canCreatePipeline), hasGitlabCi: parseBoolean(hasGitlabCi), diff --git a/app/assets/javascripts/projects/upload_file_experiment.js b/app/assets/javascripts/projects/upload_file_experiment.js new file mode 100644 index 00000000000..c2a68043489 --- /dev/null +++ b/app/assets/javascripts/projects/upload_file_experiment.js @@ -0,0 +1,21 @@ +import ExperimentTracking from '~/experiment_tracking'; + +function trackEvent(eventName) { + const Tracking = new ExperimentTracking('empty_repo_upload', { label: 'blob-upload-modal' }); + + Tracking.event(eventName); +} + +export function initUploadFileTrigger() { + const uploadFileTriggerEl = document.querySelector('.js-upload-file-experiment-trigger'); + + if (uploadFileTriggerEl) { + uploadFileTriggerEl.addEventListener('click', () => { + trackEvent('click_upload_modal_trigger'); + }); + } +} + +export function trackUploadFileFormSubmitted() { + trackEvent('click_upload_modal_form_submit'); +} |