diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 21:08:46 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 21:08:46 +0300 |
commit | 1bf106b17275c87cf8baa199599f113f154a52fe (patch) | |
tree | d2d27696ddb236922b165fb41cafc975914fd24b /app | |
parent | b21276806d34b8cc0ec7ac7854ec62f70d408b3c (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
10 files changed, 274 insertions, 19 deletions
diff --git a/app/assets/javascripts/jira_connect/branches/components/new_branch_form.vue b/app/assets/javascripts/jira_connect/branches/components/new_branch_form.vue new file mode 100644 index 00000000000..b2cc3a315cc --- /dev/null +++ b/app/assets/javascripts/jira_connect/branches/components/new_branch_form.vue @@ -0,0 +1,201 @@ +<script> +import { GlFormGroup, GlButton, GlFormInput, GlForm, GlAlert } from '@gitlab/ui'; +import { + CREATE_BRANCH_ERROR_GENERIC, + CREATE_BRANCH_ERROR_WITH_CONTEXT, + CREATE_BRANCH_SUCCESS_ALERT, + I18N_NEW_BRANCH_PAGE_TITLE, + I18N_NEW_BRANCH_LABEL_DROPDOWN, + I18N_NEW_BRANCH_LABEL_BRANCH, + I18N_NEW_BRANCH_LABEL_SOURCE, + I18N_NEW_BRANCH_SUBMIT_BUTTON_TEXT, +} from '../constants'; +import createBranchMutation from '../graphql/mutations/create_branch.mutation.graphql'; +import ProjectDropdown from './project_dropdown.vue'; +import SourceBranchDropdown from './source_branch_dropdown.vue'; + +const DEFAULT_ALERT_VARIANT = 'danger'; +const DEFAULT_ALERT_PARAMS = { + title: '', + message: '', + variant: DEFAULT_ALERT_VARIANT, + primaryButtonLink: '', + primaryButtonText: '', +}; + +export default { + name: 'JiraConnectNewBranch', + components: { + GlFormGroup, + GlButton, + GlFormInput, + GlForm, + GlAlert, + ProjectDropdown, + SourceBranchDropdown, + }, + props: { + initialBranchName: { + type: String, + required: false, + default: '', + }, + }, + data() { + return { + selectedProject: null, + selectedSourceBranchName: null, + branchName: this.initialBranchName, + createBranchLoading: false, + alertParams: { + ...DEFAULT_ALERT_PARAMS, + }, + }; + }, + computed: { + selectedProjectId() { + return this.selectedProject?.id; + }, + showAlert() { + return Boolean(this.alertParams?.message); + }, + disableSubmitButton() { + return !(this.selectedProject && this.selectedSourceBranchName && this.branchName); + }, + }, + methods: { + displayAlert({ title, message, variant = DEFAULT_ALERT_VARIANT } = {}) { + this.alertParams = { + title, + message, + variant, + }; + }, + onAlertDismiss() { + this.alertParams = { + ...DEFAULT_ALERT_PARAMS, + }; + }, + onProjectSelect(project) { + this.selectedProject = project; + this.selectedSourceBranchName = null; // reset branch selection + }, + onSourceBranchSelect(branchName) { + this.selectedSourceBranchName = branchName; + }, + onError({ title, message } = {}) { + this.displayAlert({ + message, + title, + }); + }, + onSubmit() { + this.createBranch(); + }, + async createBranch() { + this.createBranchLoading = true; + + try { + const { data } = await this.$apollo.mutate({ + mutation: createBranchMutation, + variables: { + name: this.branchName, + ref: this.selectedSourceBranchName, + projectPath: this.selectedProject.fullPath, + }, + }); + const { errors } = data.createBranch; + if (errors.length > 0) { + this.onError({ + title: CREATE_BRANCH_ERROR_WITH_CONTEXT, + message: errors[0], + }); + } else { + this.displayAlert({ + ...CREATE_BRANCH_SUCCESS_ALERT, + variant: 'success', + }); + } + } catch (e) { + this.onError({ + message: CREATE_BRANCH_ERROR_GENERIC, + }); + } + + this.createBranchLoading = false; + }, + }, + i18n: { + I18N_NEW_BRANCH_PAGE_TITLE, + I18N_NEW_BRANCH_LABEL_DROPDOWN, + I18N_NEW_BRANCH_LABEL_BRANCH, + I18N_NEW_BRANCH_LABEL_SOURCE, + I18N_NEW_BRANCH_SUBMIT_BUTTON_TEXT, + }, +}; +</script> + +<template> + <div> + <div class="gl-border-1 gl-border-b-solid gl-border-gray-100 gl-mb-5 gl-mt-7"> + <h1 class="page-title"> + {{ $options.i18n.I18N_NEW_BRANCH_PAGE_TITLE }} + </h1> + </div> + + <gl-alert + v-if="showAlert" + class="gl-mb-5" + :variant="alertParams.variant" + :title="alertParams.title" + @dismiss="onAlertDismiss" + > + {{ alertParams.message }} + </gl-alert> + + <gl-form @submit.prevent="onSubmit"> + <gl-form-group + :label="$options.i18n.I18N_NEW_BRANCH_LABEL_DROPDOWN" + label-for="project-select" + > + <project-dropdown + id="project-select" + :selected-project="selectedProject" + @change="onProjectSelect" + @error="onError" + /> + </gl-form-group> + + <gl-form-group + :label="$options.i18n.I18N_NEW_BRANCH_LABEL_BRANCH" + label-for="branch-name-input" + > + <gl-form-input id="branch-name-input" v-model="branchName" type="text" required /> + </gl-form-group> + + <gl-form-group + :label="$options.i18n.I18N_NEW_BRANCH_LABEL_SOURCE" + label-for="source-branch-select" + > + <source-branch-dropdown + id="source-branch-select" + :selected-project="selectedProject" + :selected-branch-name="selectedSourceBranchName" + @change="onSourceBranchSelect" + @error="onError" + /> + </gl-form-group> + + <div class="form-actions"> + <gl-button + :loading="createBranchLoading" + type="submit" + variant="confirm" + :disabled="disableSubmitButton" + > + {{ $options.i18n.I18N_NEW_BRANCH_SUBMIT_BUTTON_TEXT }} + </gl-button> + </div> + </gl-form> + </div> +</template> diff --git a/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue b/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue index c1f57be7f97..2accb46db60 100644 --- a/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue +++ b/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue @@ -60,7 +60,7 @@ export default { }, }, methods: { - async onProjectSelect(project) { + onProjectSelect(project) { this.$emit('change', project); }, onError({ message } = {}) { diff --git a/app/assets/javascripts/jira_connect/branches/constants.js b/app/assets/javascripts/jira_connect/branches/constants.js index 987c8d356b4..7095f123a9e 100644 --- a/app/assets/javascripts/jira_connect/branches/constants.js +++ b/app/assets/javascripts/jira_connect/branches/constants.js @@ -1,2 +1,20 @@ +import { __, s__ } from '~/locale'; + export const BRANCHES_PER_PAGE = 20; export const PROJECTS_PER_PAGE = 20; + +export const I18N_NEW_BRANCH_PAGE_TITLE = __('New branch'); +export const I18N_NEW_BRANCH_LABEL_DROPDOWN = __('Project'); +export const I18N_NEW_BRANCH_LABEL_BRANCH = __('Branch name'); +export const I18N_NEW_BRANCH_LABEL_SOURCE = __('Source branch'); +export const I18N_NEW_BRANCH_SUBMIT_BUTTON_TEXT = __('Create branch'); + +export const CREATE_BRANCH_ERROR_GENERIC = s__( + 'JiraConnect|Failed to create branch. Please try again.', +); +export const CREATE_BRANCH_ERROR_WITH_CONTEXT = s__('JiraConnect|Failed to create branch.'); + +export const CREATE_BRANCH_SUCCESS_ALERT = { + title: s__('JiraConnect|New branch was successfully created.'), + message: s__('JiraConnect|You can now close this window and return to Jira.'), +}; diff --git a/app/assets/javascripts/jira_connect/branches/graphql/mutations/create_branch.mutation.graphql b/app/assets/javascripts/jira_connect/branches/graphql/mutations/create_branch.mutation.graphql new file mode 100644 index 00000000000..7e9cbda8317 --- /dev/null +++ b/app/assets/javascripts/jira_connect/branches/graphql/mutations/create_branch.mutation.graphql @@ -0,0 +1,6 @@ +mutation createBranch($name: String!, $projectPath: ID!, $ref: String!) { + createBranch(input: { name: $name, projectPath: $projectPath, ref: $ref }) { + clientMutationId + errors + } +} diff --git a/app/assets/javascripts/jira_connect/branches/index.js b/app/assets/javascripts/jira_connect/branches/index.js new file mode 100644 index 00000000000..b8fe255e310 --- /dev/null +++ b/app/assets/javascripts/jira_connect/branches/index.js @@ -0,0 +1,36 @@ +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import JiraConnectNewBranchForm from '~/jira_connect/branches/components/new_branch_form.vue'; +import createDefaultClient from '~/lib/graphql'; + +Vue.use(VueApollo); + +export default async function initJiraConnectBranches() { + const el = document.querySelector('.js-jira-connect-create-branch'); + if (!el) { + return null; + } + + const { initialBranchName } = el.dataset; + + const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient( + {}, + { + assumeImmutableResults: true, + }, + ), + }); + + return new Vue({ + el, + apolloProvider, + render(createElement) { + return createElement(JiraConnectNewBranchForm, { + props: { + initialBranchName, + }, + }); + }, + }); +} diff --git a/app/assets/javascripts/jobs/store/utils.js b/app/assets/javascripts/jobs/store/utils.js index 36391a4d433..3f6ab77e26c 100644 --- a/app/assets/javascripts/jobs/store/utils.js +++ b/app/assets/javascripts/jobs/store/utils.js @@ -132,7 +132,7 @@ export const logLinesParserLegacy = (lines = [], accumulator = []) => ); export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLines = []) => { - let currentLine = previousTraceState?.prevLineCount ?? 0; + let currentLineCount = previousTraceState?.prevLineCount ?? 0; let currentHeader = previousTraceState?.currentHeader; let isPreviousLineHeader = previousTraceState?.isPreviousLineHeader ?? false; const parsedLines = prevParsedLines.length > 0 ? prevParsedLines : []; @@ -141,27 +141,27 @@ export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLi for (let i = 0; i < lines.length; i += 1) { const line = lines[i]; // First run we can use the current index, later runs we have to retrieve the last number of lines - currentLine = previousTraceState?.prevLineCount ? currentLine + 1 : i + 1; + currentLineCount = previousTraceState?.prevLineCount ? currentLineCount + 1 : i + 1; if (line.section_header && !isPreviousLineHeader) { // If there's no previous line header that means we're at the root of the log isPreviousLineHeader = true; - parsedLines.push(parseHeaderLine(line, currentLine)); + parsedLines.push(parseHeaderLine(line, currentLineCount)); currentHeader = { index: parsedLines.length - 1 }; } else if (line.section_header && isPreviousLineHeader) { // If there's a current section, we can't push to the parsedLines array sectionsQueue.push(currentHeader); - currentHeader = parseHeaderLine(line, currentLine); // Let's parse the incoming header line + currentHeader = parseHeaderLine(line, currentLineCount); // Let's parse the incoming header line } else if (line.section && !line.section_duration) { // We're inside a collapsible section and want to parse a standard line if (currentHeader?.index) { // If the current section header is only an index, add the line as part of the lines // array of the current collapsible section - parsedLines[currentHeader.index].lines.push(parseLine(line, currentLine)); + parsedLines[currentHeader.index].lines.push(parseLine(line, currentLineCount)); } else { // Otherwise add it to the innermost collapsible section lines array - currentHeader.lines.push(parseLine(line, currentLine)); + currentHeader.lines.push(parseLine(line, currentLineCount)); } } else if (line.section && line.section_duration) { // NOTE: This marks the end of a section_header @@ -187,7 +187,7 @@ export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLi currentHeader = previousSection; } } else { - parsedLines.push(parseLine(line, currentLine)); + parsedLines.push(parseLine(line, currentLineCount)); } } @@ -197,7 +197,7 @@ export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLi isPreviousLineHeader, currentHeader, sectionsQueue, - prevLineCount: lines.length, + prevLineCount: currentLineCount, }, }; }; diff --git a/app/assets/javascripts/token_access/components/token_access.vue b/app/assets/javascripts/token_access/components/token_access.vue index 24565c441d8..e739ec37739 100644 --- a/app/assets/javascripts/token_access/components/token_access.vue +++ b/app/assets/javascripts/token_access/components/token_access.vue @@ -187,12 +187,7 @@ export default { /> </template> <template #footer> - <gl-button - variant="confirm" - :disabled="isProjectPathEmpty" - data-testid="add-project-button" - @click="addProject" - > + <gl-button variant="confirm" :disabled="isProjectPathEmpty" @click="addProject"> {{ $options.i18n.addProject }} </gl-button> <gl-button @click="clearTargetProjectPath">{{ $options.i18n.cancel }}</gl-button> diff --git a/app/assets/javascripts/token_access/components/token_projects_table.vue b/app/assets/javascripts/token_access/components/token_projects_table.vue index 777eda1c4d7..b6c9330c754 100644 --- a/app/assets/javascripts/token_access/components/token_projects_table.vue +++ b/app/assets/javascripts/token_access/components/token_projects_table.vue @@ -73,7 +73,6 @@ export default { variant="danger" icon="remove" :aria-label="__('Remove access')" - data-testid="remove-project-button" @click="removeProject(item.fullPath)" /> </template> diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb index 303ee431a4d..6482d02761e 100644 --- a/app/controllers/registrations/welcome_controller.rb +++ b/app/controllers/registrations/welcome_controller.rb @@ -41,7 +41,7 @@ module Registrations end def update_params - params.require(:user).permit(:role, :other_role, :setup_for_company, :email_opted_in) + params.require(:user).permit(:role, :other_role, :setup_for_company) end def requires_confirmation?(user) diff --git a/app/views/devise/shared/_email_opted_in.html.haml b/app/views/devise/shared/_email_opted_in.html.haml index 6896ef21536..3817f9f651d 100644 --- a/app/views/devise/shared/_email_opted_in.html.haml +++ b/app/views/devise/shared/_email_opted_in.html.haml @@ -1,6 +1,6 @@ -- is_hidden = local_assigns.fetch(:hidden, Gitlab.dev_env_or_com?) +- return unless Gitlab.dev_env_or_com? -.gl-mb-3.js-email-opt-in{ class: is_hidden ? 'hidden' : '' } +.gl-mb-3.js-email-opt-in.hidden .gl-font-weight-bold.gl-mb-3 = _('Email updates (optional)') = f.check_box :email_opted_in |