diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
commit | b76ae638462ab0f673e5915986070518dd3f9ad3 (patch) | |
tree | bdab0533383b52873be0ec0eb4d3c66598ff8b91 /app/assets/javascripts/jira_connect | |
parent | 434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff) |
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'app/assets/javascripts/jira_connect')
20 files changed, 314 insertions, 12 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..66fcb8e10eb --- /dev/null +++ b/app/assets/javascripts/jira_connect/branches/components/new_branch_form.vue @@ -0,0 +1,174 @@ +<script> +import { GlFormGroup, GlButton, GlFormInput, GlForm, GlAlert } from '@gitlab/ui'; +import { + CREATE_BRANCH_ERROR_GENERIC, + CREATE_BRANCH_ERROR_WITH_CONTEXT, + 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, +}; + +export default { + name: 'JiraConnectNewBranch', + components: { + GlFormGroup, + GlButton, + GlFormInput, + GlForm, + GlAlert, + ProjectDropdown, + SourceBranchDropdown, + }, + inject: ['initialBranchName'], + 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.$emit('success'); + } + } catch (e) { + this.onError({ + message: CREATE_BRANCH_ERROR_GENERIC, + }); + } + + this.createBranchLoading = false; + }, + }, + i18n: { + I18N_NEW_BRANCH_LABEL_DROPDOWN, + I18N_NEW_BRANCH_LABEL_BRANCH, + I18N_NEW_BRANCH_LABEL_SOURCE, + I18N_NEW_BRANCH_SUBMIT_BUTTON_TEXT, + }, +}; +</script> +<template> + <gl-form @submit.prevent="onSubmit"> + <gl-alert + v-if="showAlert" + class="gl-mb-5" + :variant="alertParams.variant" + :title="alertParams.title" + @dismiss="onAlertDismiss" + > + {{ alertParams.message }} + </gl-alert> + <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> +</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..751f3e9639d 100644 --- a/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue +++ b/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue @@ -41,7 +41,7 @@ export default { }; }, update(data) { - return data?.projects?.nodes.filter((project) => !project.repository.empty) ?? []; + return data?.projects?.nodes.filter((project) => !project.repository?.empty) ?? []; }, result() { this.initialProjectsLoading = false; @@ -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..ab9d3b2c110 100644 --- a/app/assets/javascripts/jira_connect/branches/constants.js +++ b/app/assets/javascripts/jira_connect/branches/constants.js @@ -1,2 +1,25 @@ +import { __, s__ } from '~/locale'; + export const BRANCHES_PER_PAGE = 20; export const PROJECTS_PER_PAGE = 20; + +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 I18N_PAGE_TITLE_WITH_BRANCH_NAME = s__( + 'JiraConnect|Create branch for Jira issue %{jiraIssue}', +); +export const I18N_PAGE_TITLE_DEFAULT = __('New branch'); +export const I18N_NEW_BRANCH_SUCCESS_TITLE = s__( + 'JiraConnect|New branch was successfully created.', +); +export const I18N_NEW_BRANCH_SUCCESS_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..95bd4f5c675 --- /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 JiraConnectNewBranchPage from '~/jira_connect/branches/pages/index.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, successStateSvgPath } = el.dataset; + + const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient( + {}, + { + assumeImmutableResults: true, + }, + ), + }); + + return new Vue({ + el, + apolloProvider, + provide: { + initialBranchName, + successStateSvgPath, + }, + render(createElement) { + return createElement(JiraConnectNewBranchPage); + }, + }); +} diff --git a/app/assets/javascripts/jira_connect/branches/pages/index.vue b/app/assets/javascripts/jira_connect/branches/pages/index.vue new file mode 100644 index 00000000000..d72dec6cdee --- /dev/null +++ b/app/assets/javascripts/jira_connect/branches/pages/index.vue @@ -0,0 +1,60 @@ +<script> +import { GlEmptyState } from '@gitlab/ui'; +import { sprintf } from '~/locale'; +import NewBranchForm from '../components/new_branch_form.vue'; +import { + I18N_PAGE_TITLE_WITH_BRANCH_NAME, + I18N_PAGE_TITLE_DEFAULT, + I18N_NEW_BRANCH_SUCCESS_TITLE, + I18N_NEW_BRANCH_SUCCESS_MESSAGE, +} from '../constants'; + +export default { + components: { + GlEmptyState, + NewBranchForm, + }, + inject: ['initialBranchName', 'successStateSvgPath'], + data() { + return { + showForm: true, + }; + }, + computed: { + pageTitle() { + return this.initialBranchName + ? sprintf(this.$options.i18n.I18N_PAGE_TITLE_WITH_BRANCH_NAME, { + jiraIssue: this.initialBranchName, + }) + : this.$options.i18n.I18N_PAGE_TITLE_DEFAULT; + }, + }, + methods: { + onNewBranchFormSuccess() { + // light-weight toggle to hide the form and show the success state + this.showForm = false; + }, + }, + i18n: { + I18N_PAGE_TITLE_WITH_BRANCH_NAME, + I18N_PAGE_TITLE_DEFAULT, + I18N_NEW_BRANCH_SUCCESS_TITLE, + I18N_NEW_BRANCH_SUCCESS_MESSAGE, + }, +}; +</script> +<template> + <div> + <div class="gl-border-1 gl-border-b-solid gl-border-gray-100 gl-mb-5 gl-mt-7"> + <h1 data-testid="page-title" class="page-title">{{ pageTitle }}</h1> + </div> + + <new-branch-form v-if="showForm" @success="onNewBranchFormSuccess" /> + <gl-empty-state + v-else + :title="$options.i18n.I18N_NEW_BRANCH_SUCCESS_TITLE" + :description="$options.i18n.I18N_NEW_BRANCH_SUCCESS_MESSAGE" + :svg-path="successStateSvgPath" + /> + </div> +</template> diff --git a/app/assets/javascripts/jira_connect/.eslintrc.yml b/app/assets/javascripts/jira_connect/subscriptions/.eslintrc.yml index 053f8c6b285..053f8c6b285 100644 --- a/app/assets/javascripts/jira_connect/.eslintrc.yml +++ b/app/assets/javascripts/jira_connect/subscriptions/.eslintrc.yml diff --git a/app/assets/javascripts/jira_connect/api.js b/app/assets/javascripts/jira_connect/subscriptions/api.js index abf2c070e68..14947b6c835 100644 --- a/app/assets/javascripts/jira_connect/api.js +++ b/app/assets/javascripts/jira_connect/subscriptions/api.js @@ -1,5 +1,5 @@ import axios from 'axios'; -import { getJwt } from '~/jira_connect/utils'; +import { getJwt } from './utils'; export const addSubscription = async (addPath, namespace) => { const jwt = await getJwt(); diff --git a/app/assets/javascripts/jira_connect/components/app.vue b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue index ff4dfb23687..413424be28d 100644 --- a/app/assets/javascripts/jira_connect/components/app.vue +++ b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue @@ -1,7 +1,7 @@ <script> import { GlAlert, GlButton, GlLink, GlModal, GlModalDirective, GlSprintf } from '@gitlab/ui'; import { mapState, mapMutations } from 'vuex'; -import { retrieveAlert, getLocation } from '~/jira_connect/utils'; +import { retrieveAlert, getLocation } from '~/jira_connect/subscriptions/utils'; import { __ } from '~/locale'; import { SET_ALERT } from '../store/mutation_types'; import GroupsList from './groups_list.vue'; diff --git a/app/assets/javascripts/jira_connect/components/group_item_name.vue b/app/assets/javascripts/jira_connect/subscriptions/components/group_item_name.vue index e6c172dae9e..e6c172dae9e 100644 --- a/app/assets/javascripts/jira_connect/components/group_item_name.vue +++ b/app/assets/javascripts/jira_connect/subscriptions/components/group_item_name.vue diff --git a/app/assets/javascripts/jira_connect/components/groups_list.vue b/app/assets/javascripts/jira_connect/subscriptions/components/groups_list.vue index 55233bb6326..5a49d7c1a90 100644 --- a/app/assets/javascripts/jira_connect/components/groups_list.vue +++ b/app/assets/javascripts/jira_connect/subscriptions/components/groups_list.vue @@ -1,7 +1,10 @@ <script> import { GlLoadingIcon, GlPagination, GlAlert, GlSearchBoxByType } from '@gitlab/ui'; -import { fetchGroups } from '~/jira_connect/api'; -import { DEFAULT_GROUPS_PER_PAGE, MINIMUM_SEARCH_TERM_LENGTH } from '~/jira_connect/constants'; +import { fetchGroups } from '~/jira_connect/subscriptions/api'; +import { + DEFAULT_GROUPS_PER_PAGE, + MINIMUM_SEARCH_TERM_LENGTH, +} from '~/jira_connect/subscriptions/constants'; import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; import { s__ } from '~/locale'; import GroupsListItem from './groups_list_item.vue'; diff --git a/app/assets/javascripts/jira_connect/components/groups_list_item.vue b/app/assets/javascripts/jira_connect/subscriptions/components/groups_list_item.vue index ad046920dd1..ed7585e8a88 100644 --- a/app/assets/javascripts/jira_connect/components/groups_list_item.vue +++ b/app/assets/javascripts/jira_connect/subscriptions/components/groups_list_item.vue @@ -1,8 +1,8 @@ <script> import { GlButton } from '@gitlab/ui'; import { helpPagePath } from '~/helpers/help_page_helper'; -import { addSubscription } from '~/jira_connect/api'; -import { persistAlert, reloadPage } from '~/jira_connect/utils'; +import { addSubscription } from '~/jira_connect/subscriptions/api'; +import { persistAlert, reloadPage } from '~/jira_connect/subscriptions/utils'; import { s__ } from '~/locale'; import GroupItemName from './group_item_name.vue'; diff --git a/app/assets/javascripts/jira_connect/components/subscriptions_list.vue b/app/assets/javascripts/jira_connect/subscriptions/components/subscriptions_list.vue index a606e2edbbb..7062fb370ed 100644 --- a/app/assets/javascripts/jira_connect/components/subscriptions_list.vue +++ b/app/assets/javascripts/jira_connect/subscriptions/components/subscriptions_list.vue @@ -2,8 +2,8 @@ import { GlButton, GlEmptyState, GlTable } from '@gitlab/ui'; import { isEmpty } from 'lodash'; import { mapMutations } from 'vuex'; -import { removeSubscription } from '~/jira_connect/api'; -import { reloadPage } from '~/jira_connect/utils'; +import { removeSubscription } from '~/jira_connect/subscriptions/api'; +import { reloadPage } from '~/jira_connect/subscriptions/utils'; import { __, s__ } from '~/locale'; import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import { SET_ALERT } from '../store/mutation_types'; diff --git a/app/assets/javascripts/jira_connect/constants.js b/app/assets/javascripts/jira_connect/subscriptions/constants.js index 8dff83eabb5..8dff83eabb5 100644 --- a/app/assets/javascripts/jira_connect/constants.js +++ b/app/assets/javascripts/jira_connect/subscriptions/constants.js diff --git a/app/assets/javascripts/jira_connect/index.js b/app/assets/javascripts/jira_connect/subscriptions/index.js index bc0d21c6c9a..f1262be0174 100644 --- a/app/assets/javascripts/jira_connect/index.js +++ b/app/assets/javascripts/jira_connect/subscriptions/index.js @@ -1,13 +1,13 @@ -import '../webpack'; +import '../../webpack'; import setConfigs from '@gitlab/ui/dist/config'; import Vue from 'vue'; -import { getLocation, sizeToParent } from '~/jira_connect/utils'; import GlFeatureFlagsPlugin from '~/vue_shared/gl_feature_flags_plugin'; import Translate from '~/vue_shared/translate'; import JiraConnectApp from './components/app.vue'; import createStore from './store'; +import { getLocation, sizeToParent } from './utils'; const store = createStore(); diff --git a/app/assets/javascripts/jira_connect/store/index.js b/app/assets/javascripts/jira_connect/subscriptions/store/index.js index de830e3891a..de830e3891a 100644 --- a/app/assets/javascripts/jira_connect/store/index.js +++ b/app/assets/javascripts/jira_connect/subscriptions/store/index.js diff --git a/app/assets/javascripts/jira_connect/store/mutation_types.js b/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js index 15f36b824d9..15f36b824d9 100644 --- a/app/assets/javascripts/jira_connect/store/mutation_types.js +++ b/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js diff --git a/app/assets/javascripts/jira_connect/store/mutations.js b/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js index 2a25e0fe25f..2a25e0fe25f 100644 --- a/app/assets/javascripts/jira_connect/store/mutations.js +++ b/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js diff --git a/app/assets/javascripts/jira_connect/store/state.js b/app/assets/javascripts/jira_connect/subscriptions/store/state.js index c807df03f00..c807df03f00 100644 --- a/app/assets/javascripts/jira_connect/store/state.js +++ b/app/assets/javascripts/jira_connect/subscriptions/store/state.js diff --git a/app/assets/javascripts/jira_connect/utils.js b/app/assets/javascripts/jira_connect/subscriptions/utils.js index ecd1a31339a..ecd1a31339a 100644 --- a/app/assets/javascripts/jira_connect/utils.js +++ b/app/assets/javascripts/jira_connect/subscriptions/utils.js |