Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-19 03:08:59 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-19 03:08:59 +0300
commit1f9bddaf87f0b6c93a9617bad0ae731baf16d268 (patch)
tree05201555039e5efa4571594b29b03dba6a9d2329 /app/assets/javascripts/integrations
parentacc1c1c468a8a75b4ab75133e95d41005543bb32 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/integrations')
-rw-r--r--app/assets/javascripts/integrations/constants.js21
-rw-r--r--app/assets/javascripts/integrations/edit/components/dynamic_field.vue2
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_auth_fields.vue152
-rw-r--r--app/assets/javascripts/integrations/edit/components/sections/connection.vue36
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>