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>2020-07-20 15:26:25 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-20 15:26:25 +0300
commita09983ae35713f5a2bbb100981116d31ce99826e (patch)
tree2ee2af7bd104d57086db360a7e6d8c9d5d43667a /app/assets/javascripts/integrations
parent18c5ab32b738c0b6ecb4d0df3994000482f34bd8 (diff)
Add latest changes from gitlab-org/gitlab@13-2-stable-ee
Diffstat (limited to 'app/assets/javascripts/integrations')
-rw-r--r--app/assets/javascripts/integrations/edit/components/active_toggle.vue12
-rw-r--r--app/assets/javascripts/integrations/edit/components/dynamic_field.vue22
-rw-r--r--app/assets/javascripts/integrations/edit/components/integration_form.vue82
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue151
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue58
-rw-r--r--app/assets/javascripts/integrations/edit/components/override_dropdown.vue63
-rw-r--r--app/assets/javascripts/integrations/edit/components/trigger_fields.vue7
-rw-r--r--app/assets/javascripts/integrations/edit/index.js97
-rw-r--r--app/assets/javascripts/integrations/edit/store/actions.js4
-rw-r--r--app/assets/javascripts/integrations/edit/store/getters.js6
-rw-r--r--app/assets/javascripts/integrations/edit/store/index.js17
-rw-r--r--app/assets/javascripts/integrations/edit/store/mutation_types.js2
-rw-r--r--app/assets/javascripts/integrations/edit/store/mutations.js7
-rw-r--r--app/assets/javascripts/integrations/edit/store/state.js9
-rw-r--r--app/assets/javascripts/integrations/integration_settings_form.js5
15 files changed, 456 insertions, 86 deletions
diff --git a/app/assets/javascripts/integrations/edit/components/active_toggle.vue b/app/assets/javascripts/integrations/edit/components/active_toggle.vue
index dc89e139320..a3087c8958e 100644
--- a/app/assets/javascripts/integrations/edit/components/active_toggle.vue
+++ b/app/assets/javascripts/integrations/edit/components/active_toggle.vue
@@ -1,4 +1,5 @@
<script>
+import { mapGetters } from 'vuex';
import eventHub from '../event_hub';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { GlFormGroup, GlToggle } from '@gitlab/ui';
@@ -21,6 +22,9 @@ export default {
activated: this.initialActivated,
};
},
+ computed: {
+ ...mapGetters(['isInheriting']),
+ },
mounted() {
// Initialize view
this.$nextTick(() => {
@@ -42,6 +46,7 @@ export default {
v-model="activated"
name="service[active]"
class="gl-display-block gl-line-height-0"
+ :disabled="isInheriting"
@change="onToggle"
/>
</gl-form-group>
@@ -50,7 +55,12 @@ export default {
<div class="form-group row" role="group">
<label for="service[active]" class="col-form-label col-sm-2">{{ __('Active') }}</label>
<div class="col-sm-10 pt-1">
- <gl-toggle v-model="activated" name="service[active]" @change="onToggle" />
+ <gl-toggle
+ v-model="activated"
+ name="service[active]"
+ :disabled="isInheriting"
+ @change="onToggle"
+ />
</div>
</div>
</div>
diff --git a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue
index 29318d6aaa8..6053d11e6da 100644
--- a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue
+++ b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue
@@ -1,4 +1,5 @@
<script>
+import { mapGetters } from 'vuex';
import eventHub from '../event_hub';
import { capitalize, lowerCase, isEmpty } from 'lodash';
import { __, sprintf } from '~/locale';
@@ -59,6 +60,7 @@ export default {
};
},
computed: {
+ ...mapGetters(['isInheriting']),
isCheckbox() {
return this.type === 'checkbox';
},
@@ -106,10 +108,12 @@ export default {
return {
id: this.fieldId,
name: this.fieldName,
+ state: this.valid,
+ readonly: this.isInheriting,
};
},
valid() {
- return !this.required || !isEmpty(this.model) || !this.validated;
+ return !this.required || !isEmpty(this.model) || this.isNonEmptyPassword || !this.validated;
},
},
created() {
@@ -135,15 +139,21 @@ export default {
:label-for="fieldId"
:invalid-feedback="__('This field is required.')"
:state="valid"
- :description="help"
>
+ <template #description>
+ <span v-html="help"></span>
+ </template>
+
<template v-if="isCheckbox">
- <input :name="fieldName" type="hidden" value="false" />
- <gl-form-checkbox v-model="model" v-bind="sharedProps">
+ <input :name="fieldName" type="hidden" :value="model || false" />
+ <gl-form-checkbox :id="fieldId" v-model="model" :disabled="isInheriting">
{{ humanizedTitle }}
</gl-form-checkbox>
</template>
- <gl-form-select v-else-if="isSelect" v-model="model" v-bind="sharedProps" :options="options" />
+ <template v-else-if="isSelect">
+ <input type="hidden" :name="fieldName" :value="model" />
+ <gl-form-select :id="fieldId" v-model="model" :options="options" :disabled="isInheriting" />
+ </template>
<gl-form-textarea
v-else-if="isTextarea"
v-model="model"
@@ -159,6 +169,7 @@ export default {
autocomplete="new-password"
:placeholder="placeholder"
:required="passwordRequired"
+ :data-qa-selector="`${fieldId}_field`"
/>
<gl-form-input
v-else
@@ -167,6 +178,7 @@ export default {
:type="type"
:placeholder="placeholder"
:required="required"
+ :data-qa-selector="`${fieldId}_field`"
/>
</gl-form-group>
</template>
diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue
index ef7a4d44b20..5088664c3bd 100644
--- a/app/assets/javascripts/integrations/edit/components/integration_form.vue
+++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue
@@ -1,58 +1,74 @@
<script>
+import { mapState, mapActions, mapGetters } from 'vuex';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+
+import OverrideDropdown from './override_dropdown.vue';
import ActiveToggle from './active_toggle.vue';
import JiraTriggerFields from './jira_trigger_fields.vue';
+import JiraIssuesFields from './jira_issues_fields.vue';
import TriggerFields from './trigger_fields.vue';
import DynamicField from './dynamic_field.vue';
export default {
name: 'IntegrationForm',
components: {
+ OverrideDropdown,
ActiveToggle,
JiraTriggerFields,
+ JiraIssuesFields,
TriggerFields,
DynamicField,
},
- props: {
- activeToggleProps: {
- type: Object,
- required: true,
- },
- showActive: {
- type: Boolean,
- required: true,
- },
- triggerFieldsProps: {
- type: Object,
- required: true,
- },
- triggerEvents: {
- type: Array,
- required: false,
- default: () => [],
- },
- fields: {
- type: Array,
- required: false,
- default: () => [],
- },
- type: {
- type: String,
- required: true,
- },
- },
+ mixins: [glFeatureFlagsMixin()],
computed: {
+ ...mapGetters(['currentKey', 'propsSource']),
+ ...mapState(['adminState', 'override']),
isJira() {
- return this.type === 'jira';
+ return this.propsSource.type === 'jira';
},
+ showJiraIssuesFields() {
+ return this.isJira && this.glFeatures.jiraIssuesIntegration;
+ },
+ },
+ methods: {
+ ...mapActions(['setOverride']),
},
};
</script>
<template>
<div>
- <active-toggle v-if="showActive" v-bind="activeToggleProps" />
- <jira-trigger-fields v-if="isJira" v-bind="triggerFieldsProps" />
- <trigger-fields v-else-if="triggerEvents.length" :events="triggerEvents" :type="type" />
- <dynamic-field v-for="field in fields" :key="field.name" v-bind="field" />
+ <override-dropdown
+ v-if="adminState !== null"
+ :inherit-from-id="adminState.id"
+ :override="override"
+ @change="setOverride"
+ />
+ <active-toggle
+ v-if="propsSource.showActive"
+ :key="`${currentKey}-active-toggle`"
+ v-bind="propsSource.activeToggleProps"
+ />
+ <jira-trigger-fields
+ v-if="isJira"
+ :key="`${currentKey}-jira-trigger-fields`"
+ v-bind="propsSource.triggerFieldsProps"
+ />
+ <trigger-fields
+ v-else-if="propsSource.triggerEvents.length"
+ :key="`${currentKey}-trigger-fields`"
+ :events="propsSource.triggerEvents"
+ :type="propsSource.type"
+ />
+ <dynamic-field
+ v-for="field in propsSource.fields"
+ :key="`${currentKey}-${field.name}`"
+ v-bind="field"
+ />
+ <jira-issues-fields
+ v-if="showJiraIssuesFields"
+ :key="`${currentKey}-jira-issues-fields`"
+ v-bind="propsSource.jiraIssuesProps"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue
new file mode 100644
index 00000000000..5444cd5a712
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue
@@ -0,0 +1,151 @@
+<script>
+import eventHub from '../event_hub';
+import {
+ GlFormGroup,
+ GlFormCheckbox,
+ GlFormInput,
+ GlSprintf,
+ GlLink,
+ GlButton,
+ GlCard,
+} from '@gitlab/ui';
+
+export default {
+ name: 'JiraIssuesFields',
+ components: {
+ GlFormGroup,
+ GlFormCheckbox,
+ GlFormInput,
+ GlSprintf,
+ GlLink,
+ GlButton,
+ GlCard,
+ },
+ props: {
+ showJiraIssuesIntegration: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ initialEnableJiraIssues: {
+ type: Boolean,
+ required: false,
+ default: null,
+ },
+ initialProjectKey: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ upgradePlanPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ editProjectPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ enableJiraIssues: this.initialEnableJiraIssues,
+ projectKey: this.initialProjectKey,
+ validated: false,
+ };
+ },
+ computed: {
+ validProjectKey() {
+ return !this.enableJiraIssues || Boolean(this.projectKey) || !this.validated;
+ },
+ },
+ created() {
+ eventHub.$on('validateForm', this.validateForm);
+ },
+ beforeDestroy() {
+ eventHub.$off('validateForm', this.validateForm);
+ },
+ methods: {
+ validateForm() {
+ this.validated = true;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-form-group
+ :label="s__('JiraService|View Jira issues in GitLab')"
+ label-for="jira-issue-settings"
+ >
+ <div id="jira-issue-settings">
+ <p>
+ {{
+ s__(
+ 'JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only.',
+ )
+ }}
+ </p>
+ <template v-if="showJiraIssuesIntegration">
+ <input name="service[issues_enabled]" type="hidden" :value="enableJiraIssues || false" />
+ <gl-form-checkbox v-model="enableJiraIssues">
+ {{ s__('JiraService|Enable Jira issues') }}
+ <template #help>
+ {{
+ s__(
+ 'JiraService|Warning: All GitLab users that have access to this GitLab project will be able to view all issues from the Jira project specified below.',
+ )
+ }}
+ </template>
+ </gl-form-checkbox>
+ </template>
+ <gl-card v-else class="gl-mt-7">
+ <strong>{{ __('This is a Premium feature') }}</strong>
+ <p>{{ __('Upgrade your plan to enable this feature of the Jira Integration.') }}</p>
+ <gl-button
+ v-if="upgradePlanPath"
+ category="primary"
+ variant="info"
+ :href="upgradePlanPath"
+ target="_blank"
+ >
+ {{ __('Upgrade your plan') }}
+ </gl-button>
+ </gl-card>
+ </div>
+ </gl-form-group>
+ <template v-if="showJiraIssuesIntegration">
+ <gl-form-group
+ :label="s__('JiraService|Jira project key')"
+ label-for="service_project_key"
+ :invalid-feedback="__('This field is required.')"
+ :state="validProjectKey"
+ >
+ <gl-form-input
+ id="service_project_key"
+ v-model="projectKey"
+ name="service[project_key]"
+ :placeholder="s__('JiraService|e.g. AB')"
+ :required="enableJiraIssues"
+ :state="validProjectKey"
+ :disabled="!enableJiraIssues"
+ />
+ </gl-form-group>
+ <p>
+ <gl-sprintf
+ :message="
+ s__(
+ 'JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used.',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link :href="editProjectPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ </template>
+ </div>
+</template>
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 64e5789764f..1d3354c6651 100644
--- a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
@@ -1,5 +1,6 @@
<script>
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { mapGetters } from 'vuex';
import { s__ } from '~/locale';
import { GlFormGroup, GlFormCheckbox, GlFormRadio } from '@gitlab/ui';
@@ -55,6 +56,7 @@ export default {
};
},
computed: {
+ ...mapGetters(['isInheriting']),
showEnableComments() {
return this.triggerCommit || this.triggerMergeRequest;
},
@@ -73,13 +75,17 @@ export default {
)
"
>
- <input name="service[commit_events]" type="hidden" value="false" />
- <gl-form-checkbox v-model="triggerCommit" name="service[commit_events]">
+ <input name="service[commit_events]" type="hidden" :value="triggerCommit || false" />
+ <gl-form-checkbox v-model="triggerCommit" :disabled="isInheriting">
{{ __('Commit') }}
</gl-form-checkbox>
- <input name="service[merge_requests_events]" type="hidden" value="false" />
- <gl-form-checkbox v-model="triggerMergeRequest" name="service[merge_requests_events]">
+ <input
+ name="service[merge_requests_events]"
+ type="hidden"
+ :value="triggerMergeRequest || false"
+ />
+ <gl-form-checkbox v-model="triggerMergeRequest" :disabled="isInheriting">
{{ __('Merge request') }}
</gl-form-checkbox>
</gl-form-group>
@@ -89,8 +95,12 @@ export default {
:label="s__('Integrations|Comment settings:')"
data-testid="comment-settings"
>
- <input name="service[comment_on_event_enabled]" type="hidden" value="false" />
- <gl-form-checkbox v-model="enableComments" name="service[comment_on_event_enabled]">
+ <input
+ name="service[comment_on_event_enabled]"
+ type="hidden"
+ :value="enableComments || false"
+ />
+ <gl-form-checkbox v-model="enableComments" :disabled="isInheriting">
{{ s__('Integrations|Enable comments') }}
</gl-form-checkbox>
</gl-form-group>
@@ -100,12 +110,18 @@ export default {
:label="s__('Integrations|Comment detail:')"
data-testid="comment-detail"
>
+ <input
+ v-if="isInheriting"
+ name="service[comment_detail]"
+ type="hidden"
+ :value="commentDetail"
+ />
<gl-form-radio
v-for="commentDetailOption in commentDetailOptions"
:key="commentDetailOption.value"
v-model="commentDetail"
:value="commentDetailOption.value"
- name="service[comment_detail]"
+ :disabled="isInheriting"
>
{{ commentDetailOption.label }}
<template #help>
@@ -126,13 +142,17 @@ export default {
}}
</label>
- <input name="service[commit_events]" type="hidden" value="false" />
- <gl-form-checkbox v-model="triggerCommit" name="service[commit_events]">
+ <input name="service[commit_events]" type="hidden" :value="triggerCommit || false" />
+ <gl-form-checkbox v-model="triggerCommit" :disabled="isInheriting">
{{ __('Commit') }}
</gl-form-checkbox>
- <input name="service[merge_requests_events]" type="hidden" value="false" />
- <gl-form-checkbox v-model="triggerMergeRequest" name="service[merge_requests_events]">
+ <input
+ name="service[merge_requests_events]"
+ type="hidden"
+ :value="triggerMergeRequest || false"
+ />
+ <gl-form-checkbox v-model="triggerMergeRequest" :disabled="isInheriting">
{{ __('Merge request') }}
</gl-form-checkbox>
@@ -144,8 +164,12 @@ export default {
<label>
{{ s__('Integrations|Comment settings:') }}
</label>
- <input name="service[comment_on_event_enabled]" type="hidden" value="false" />
- <gl-form-checkbox v-model="enableComments" name="service[comment_on_event_enabled]">
+ <input
+ name="service[comment_on_event_enabled]"
+ type="hidden"
+ :value="enableComments || false"
+ />
+ <gl-form-checkbox v-model="enableComments" :disabled="isInheriting">
{{ s__('Integrations|Enable comments') }}
</gl-form-checkbox>
@@ -153,12 +177,18 @@ export default {
<label>
{{ s__('Integrations|Comment detail:') }}
</label>
+ <input
+ v-if="isInheriting"
+ name="service[comment_detail]"
+ type="hidden"
+ :value="commentDetail"
+ />
<gl-form-radio
v-for="commentDetailOption in commentDetailOptions"
:key="commentDetailOption.value"
v-model="commentDetail"
:value="commentDetailOption.value"
- name="service[comment_detail]"
+ :disabled="isInheriting"
>
{{ commentDetailOption.label }}
<template #help>
diff --git a/app/assets/javascripts/integrations/edit/components/override_dropdown.vue b/app/assets/javascripts/integrations/edit/components/override_dropdown.vue
new file mode 100644
index 00000000000..0ae2f267434
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/components/override_dropdown.vue
@@ -0,0 +1,63 @@
+<script>
+import { s__ } from '~/locale';
+import { GlNewDropdown, GlNewDropdownItem } from '@gitlab/ui';
+
+const dropdownOptions = [
+ {
+ value: false,
+ text: s__('Integrations|Use instance level settings'),
+ },
+ {
+ value: true,
+ text: s__('Integrations|Use custom settings'),
+ },
+];
+
+export default {
+ dropdownOptions,
+ name: 'OverrideDropdown',
+ components: {
+ GlNewDropdown,
+ GlNewDropdownItem,
+ },
+ props: {
+ inheritFromId: {
+ type: Number,
+ required: true,
+ },
+ override: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ selected: dropdownOptions.find(x => x.value === this.override),
+ };
+ },
+ methods: {
+ onClick(option) {
+ this.selected = option;
+ this.$emit('change', option.value);
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ class="gl-display-flex gl-justify-content-space-between gl-align-items-baseline gl-py-4 gl-mt-5 gl-mb-6 gl-border-t-1 gl-border-t-solid gl-border-b-1 gl-border-b-solid gl-border-gray-100"
+ >
+ <span>{{ s__('Integrations|This integration has multiple settings available.') }}</span>
+ <input name="service[inherit_from_id]" :value="override ? '' : inheritFromId" type="hidden" />
+ <gl-new-dropdown :text="selected.text">
+ <gl-new-dropdown-item
+ v-for="option in $options.dropdownOptions"
+ :key="option.value"
+ @click="onClick(option)"
+ >
+ {{ option.text }}
+ </gl-new-dropdown-item>
+ </gl-new-dropdown>
+ </div>
+</template>
diff --git a/app/assets/javascripts/integrations/edit/components/trigger_fields.vue b/app/assets/javascripts/integrations/edit/components/trigger_fields.vue
index 531490ae40c..bb1e0d9d360 100644
--- a/app/assets/javascripts/integrations/edit/components/trigger_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/trigger_fields.vue
@@ -1,4 +1,5 @@
<script>
+import { mapGetters } from 'vuex';
import { startCase } from 'lodash';
import { __ } from '~/locale';
import { GlFormGroup, GlFormCheckbox, GlFormInput } from '@gitlab/ui';
@@ -32,6 +33,7 @@ export default {
},
},
computed: {
+ ...mapGetters(['isInheriting']),
placeholder() {
return placeholderForType[this.type];
},
@@ -57,8 +59,8 @@ export default {
>
<div id="trigger-fields" class="gl-pt-3">
<gl-form-group v-for="event in events" :key="event.title" :description="event.description">
- <input :name="checkboxName(event.name)" type="hidden" value="false" />
- <gl-form-checkbox v-model="event.value" :name="checkboxName(event.name)">
+ <input :name="checkboxName(event.name)" type="hidden" :value="event.value || false" />
+ <gl-form-checkbox v-model="event.value" :disabled="isInheriting">
{{ startCase(event.title) }}
</gl-form-checkbox>
<gl-form-input
@@ -66,6 +68,7 @@ export default {
v-model="event.field.value"
:name="fieldName(event.field.name)"
:placeholder="placeholder"
+ :readonly="isInheriting"
/>
</gl-form-group>
</div>
diff --git a/app/assets/javascripts/integrations/edit/index.js b/app/assets/javascripts/integrations/edit/index.js
index 21b5ca17951..ea5463832ce 100644
--- a/app/assets/javascripts/integrations/edit/index.js
+++ b/app/assets/javascripts/integrations/edit/index.js
@@ -1,49 +1,86 @@
import Vue from 'vue';
+import { createStore } from './store';
import { parseBoolean } from '~/lib/utils/common_utils';
import IntegrationForm from './components/integration_form.vue';
-export default el => {
- if (!el) {
- return null;
- }
-
- function parseBooleanInData(data) {
- const result = {};
- Object.entries(data).forEach(([key, value]) => {
- result[key] = parseBoolean(value);
- });
- return result;
- }
+function parseBooleanInData(data) {
+ const result = {};
+ Object.entries(data).forEach(([key, value]) => {
+ result[key] = parseBoolean(value);
+ });
+ return result;
+}
- const { type, commentDetail, triggerEvents, fields, ...booleanAttributes } = el.dataset;
+function parseDatasetToProps(data) {
+ const {
+ id,
+ type,
+ commentDetail,
+ projectKey,
+ upgradePlanPath,
+ editProjectPath,
+ triggerEvents,
+ fields,
+ inheritFromId,
+ ...booleanAttributes
+ } = data;
const {
showActive,
activated,
commitEvents,
mergeRequestEvents,
enableComments,
+ showJiraIssuesIntegration,
+ enableJiraIssues,
} = parseBooleanInData(booleanAttributes);
+ return {
+ activeToggleProps: {
+ initialActivated: activated,
+ },
+ showActive,
+ type,
+ triggerFieldsProps: {
+ initialTriggerCommit: commitEvents,
+ initialTriggerMergeRequest: mergeRequestEvents,
+ initialEnableComments: enableComments,
+ initialCommentDetail: commentDetail,
+ },
+ jiraIssuesProps: {
+ showJiraIssuesIntegration,
+ initialEnableJiraIssues: enableJiraIssues,
+ initialProjectKey: projectKey,
+ upgradePlanPath,
+ editProjectPath,
+ },
+ triggerEvents: JSON.parse(triggerEvents),
+ fields: JSON.parse(fields),
+ inheritFromId: parseInt(inheritFromId, 10),
+ id: parseInt(id, 10),
+ };
+}
+
+export default (el, adminEl) => {
+ if (!el) {
+ return null;
+ }
+
+ const props = parseDatasetToProps(el.dataset);
+
+ const initialState = {
+ adminState: null,
+ customState: props,
+ };
+
+ if (adminEl) {
+ initialState.adminState = Object.freeze(parseDatasetToProps(adminEl.dataset));
+ }
+
return new Vue({
el,
+ store: createStore(initialState),
render(createElement) {
- return createElement(IntegrationForm, {
- props: {
- activeToggleProps: {
- initialActivated: activated,
- },
- showActive,
- type,
- triggerFieldsProps: {
- initialTriggerCommit: commitEvents,
- initialTriggerMergeRequest: mergeRequestEvents,
- initialEnableComments: enableComments,
- initialCommentDetail: commentDetail,
- },
- triggerEvents: JSON.parse(triggerEvents),
- fields: JSON.parse(fields),
- },
- });
+ return createElement(IntegrationForm);
},
});
};
diff --git a/app/assets/javascripts/integrations/edit/store/actions.js b/app/assets/javascripts/integrations/edit/store/actions.js
new file mode 100644
index 00000000000..3decdaab55d
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/store/actions.js
@@ -0,0 +1,4 @@
+import * as types from './mutation_types';
+
+// eslint-disable-next-line import/prefer-default-export
+export const setOverride = ({ commit }, override) => commit(types.SET_OVERRIDE, override);
diff --git a/app/assets/javascripts/integrations/edit/store/getters.js b/app/assets/javascripts/integrations/edit/store/getters.js
new file mode 100644
index 00000000000..b68bd668980
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/store/getters.js
@@ -0,0 +1,6 @@
+export const isInheriting = state => (state.adminState === null ? false : !state.override);
+
+export const propsSource = (state, getters) =>
+ getters.isInheriting ? state.adminState : state.customState;
+
+export const currentKey = (state, getters) => (getters.isInheriting ? 'admin' : 'custom');
diff --git a/app/assets/javascripts/integrations/edit/store/index.js b/app/assets/javascripts/integrations/edit/store/index.js
new file mode 100644
index 00000000000..eea5e48780d
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/store/index.js
@@ -0,0 +1,17 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import * as actions from './actions';
+import * as getters from './getters';
+import mutations from './mutations';
+import createState from './state';
+
+Vue.use(Vuex);
+
+// eslint-disable-next-line import/prefer-default-export
+export const createStore = (initialState = {}) =>
+ new Vuex.Store({
+ actions,
+ getters,
+ mutations,
+ state: createState(initialState),
+ });
diff --git a/app/assets/javascripts/integrations/edit/store/mutation_types.js b/app/assets/javascripts/integrations/edit/store/mutation_types.js
new file mode 100644
index 00000000000..274afe3fb49
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/store/mutation_types.js
@@ -0,0 +1,2 @@
+// eslint-disable-next-line import/prefer-default-export
+export const SET_OVERRIDE = 'SET_OVERRIDE';
diff --git a/app/assets/javascripts/integrations/edit/store/mutations.js b/app/assets/javascripts/integrations/edit/store/mutations.js
new file mode 100644
index 00000000000..8757d415197
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/store/mutations.js
@@ -0,0 +1,7 @@
+import * as types from './mutation_types';
+
+export default {
+ [types.SET_OVERRIDE](state, override) {
+ state.override = override;
+ },
+};
diff --git a/app/assets/javascripts/integrations/edit/store/state.js b/app/assets/javascripts/integrations/edit/store/state.js
new file mode 100644
index 00000000000..95c1a2be500
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/store/state.js
@@ -0,0 +1,9 @@
+export default ({ adminState = null, customState = {} } = {}) => {
+ const override = adminState !== null ? adminState.id !== customState.inheritFromId : false;
+
+ return {
+ override,
+ adminState,
+ customState,
+ };
+};
diff --git a/app/assets/javascripts/integrations/integration_settings_form.js b/app/assets/javascripts/integrations/integration_settings_form.js
index 8844cbebe85..837409a91ca 100644
--- a/app/assets/javascripts/integrations/integration_settings_form.js
+++ b/app/assets/javascripts/integrations/integration_settings_form.js
@@ -22,7 +22,10 @@ export default class IntegrationSettingsForm {
init() {
// Init Vue component
- initForm(document.querySelector('.js-vue-integration-settings'));
+ initForm(
+ document.querySelector('.js-vue-integration-settings'),
+ document.querySelector('.js-vue-admin-integration-settings'),
+ );
eventHub.$on('toggle', active => {
this.formActive = active;
this.handleServiceToggle();