diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-19 03:08:59 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-19 03:08:59 +0300 |
commit | 1f9bddaf87f0b6c93a9617bad0ae731baf16d268 (patch) | |
tree | 05201555039e5efa4571594b29b03dba6a9d2329 /app/assets/javascripts/integrations | |
parent | acc1c1c468a8a75b4ab75133e95d41005543bb32 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/integrations')
4 files changed, 209 insertions, 2 deletions
diff --git a/app/assets/javascripts/integrations/constants.js b/app/assets/javascripts/integrations/constants.js index 6b5a828c009..259166c71b7 100644 --- a/app/assets/javascripts/integrations/constants.js +++ b/app/assets/javascripts/integrations/constants.js @@ -104,4 +104,25 @@ export const placeholderForType = { [INTEGRATION_TYPE_MATTERMOST]: __('my-channel'), }; +export const INTEGRATION_FORM_TYPE_JIRA = 'jira'; export const INTEGRATION_FORM_TYPE_SLACK = 'gitlab_slack_application'; + +export const jiraIntegrationAuthFields = { + AUTH_TYPE: 'jira_auth_type', + USERNAME: 'username', + PASSWORD: 'password', +}; +export const jiraAuthTypeFieldProps = [ + { + username: s__('JiraService|Email or username'), + password: s__('JiraService|API token or password'), + passwordHelp: s__( + 'JiraService|API token for Jira Cloud or password for Jira Data Center and Jira Server', + ), + nonEmptyPassword: s__('JiraService|New API token or password'), + }, + { + password: s__('JiraService|Jira personal access token'), + nonEmptyPassword: s__('JiraService|New Jira personal access token'), + }, +]; diff --git a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue index 904e5639cac..0a29906d5aa 100644 --- a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue +++ b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue @@ -97,7 +97,7 @@ export default { return isEmpty(this.value) && this.required; }, options() { - return this.choices.map((choice) => { + return this.choices?.map((choice) => { return { value: choice[1], text: choice[0], diff --git a/app/assets/javascripts/integrations/edit/components/jira_auth_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_auth_fields.vue new file mode 100644 index 00000000000..30a39e48959 --- /dev/null +++ b/app/assets/javascripts/integrations/edit/components/jira_auth_fields.vue @@ -0,0 +1,152 @@ +<script> +import { mapGetters } from 'vuex'; +import { isEmpty } from 'lodash'; +import { GlFormGroup, GlFormRadio, GlFormRadioGroup } from '@gitlab/ui'; +import { __, s__ } from '~/locale'; + +import { jiraIntegrationAuthFields, jiraAuthTypeFieldProps } from '~/integrations/constants'; +import DynamicField from './dynamic_field.vue'; + +const authTypeOptions = [ + { + value: 0, + text: s__('JiraService|Basic'), + }, + { + value: 1, + text: s__('JiraService|Jira personal access token'), + help: s__('JiraService|Recommended. Only available for Jira Data Center and Jira Server.'), + }, +]; + +export default { + name: 'JiraAuthFields', + + components: { + GlFormGroup, + GlFormRadio, + GlFormRadioGroup, + DynamicField, + }, + + props: { + isValidated: { + type: Boolean, + required: false, + default: false, + }, + + fields: { + type: Array, + required: false, + default: () => [], + }, + }, + + data() { + return { + authType: 0, + }; + }, + + computed: { + ...mapGetters(['currentKey', 'isInheriting']), + + isAuthTypeBasic() { + return this.authType === 0; + }, + + isNonEmptyPassword() { + return !isEmpty(this.passwordField?.value); + }, + + authTypeProps() { + return jiraAuthTypeFieldProps[this.authType]; + }, + + authTypeField() { + return this.findFieldByName(jiraIntegrationAuthFields.AUTH_TYPE); + }, + + usernameField() { + return this.findFieldByName(jiraIntegrationAuthFields.USERNAME); + }, + + passwordField() { + return this.findFieldByName(jiraIntegrationAuthFields.PASSWORD); + }, + + usernameProps() { + return { + ...this.usernameField, + ...(this.isAuthTypeBasic ? { required: true } : {}), + title: this.authTypeProps.username, + }; + }, + + passwordProps() { + const extraProps = this.isNonEmptyPassword + ? { title: this.authTypeProps.nonEmptyPassword } + : { title: this.authTypeProps.password, help: this.authTypeProps.passwordHelp }; + + return { + ...this.passwordField, + ...extraProps, + }; + }, + }, + + mounted() { + const authTypeValue = this.authTypeField?.value; + if (authTypeValue) { + this.authType = parseInt(authTypeValue, 10); + } + }, + + methods: { + findFieldByName(name) { + return this.fields.find((field) => field.name === name); + }, + }, + + authTypeOptions, + + i18n: { + authTypeLabel: __('Authentication method'), + }, +}; +</script> + +<template> + <gl-form-group :label="$options.i18n.authTypeLabel" label-for="service[jira_auth_type]"> + <input name="service[jira_auth_type]" type="hidden" :value="authType" /> + <gl-form-radio-group v-model="authType" :disabled="isInheriting"> + <gl-form-radio + v-for="option in $options.authTypeOptions" + :key="option.value" + :value="option.value" + > + <template v-if="option.help" #help> + {{ option.help }} + </template> + {{ option.text }} + </gl-form-radio> + </gl-form-radio-group> + + <div class="gl-ml-6 gl-mt-3"> + <dynamic-field + v-if="isAuthTypeBasic" + :key="`${currentKey}-${usernameProps.name}`" + data-testid="jira-auth-username" + v-bind="usernameProps" + :is-validated="isValidated" + /> + <dynamic-field + :key="`${currentKey}-${passwordProps.name}`" + data-testid="jira-auth-password" + v-bind="passwordProps" + :is-validated="isValidated" + /> + </div> + </gl-form-group> +</template> diff --git a/app/assets/javascripts/integrations/edit/components/sections/connection.vue b/app/assets/javascripts/integrations/edit/components/sections/connection.vue index 364e9324e43..6237f7983a6 100644 --- a/app/assets/javascripts/integrations/edit/components/sections/connection.vue +++ b/app/assets/javascripts/integrations/edit/components/sections/connection.vue @@ -1,5 +1,6 @@ <script> import { mapGetters } from 'vuex'; +import { INTEGRATION_FORM_TYPE_JIRA, jiraIntegrationAuthFields } from '~/integrations/constants'; import ActiveCheckbox from '../active_checkbox.vue'; import DynamicField from '../dynamic_field.vue'; @@ -9,6 +10,10 @@ export default { components: { ActiveCheckbox, DynamicField, + JiraAuthFields: () => + import( + /* webpackChunkName: 'integrationJiraAuthFields' */ '~/integrations/edit/components/jira_auth_fields.vue' + ), }, props: { fields: { @@ -24,6 +29,29 @@ export default { }, computed: { ...mapGetters(['currentKey', 'propsSource']), + + isJiraIntegration() { + return this.propsSource.type === INTEGRATION_FORM_TYPE_JIRA; + }, + + filteredFields() { + if (!this.isJiraIntegration) { + return this.fields; + } + + return this.fields.filter( + (field) => !Object.values(jiraIntegrationAuthFields).includes(field.name), + ); + }, + jiraAuthFields() { + if (!this.isJiraIntegration) { + return []; + } + + return this.fields.filter((field) => + Object.values(jiraIntegrationAuthFields).includes(field.name), + ); + }, }, }; </script> @@ -36,10 +64,16 @@ export default { @toggle-integration-active="$emit('toggle-integration-active', $event)" /> <dynamic-field - v-for="field in fields" + v-for="field in filteredFields" :key="`${currentKey}-${field.name}`" v-bind="field" :is-validated="isValidated" /> + <jira-auth-fields + v-if="isJiraIntegration" + :key="`${currentKey}-jira-auth-fields`" + :is-validated="isValidated" + :fields="jiraAuthFields" + /> </div> </template> |