From accc2645a1a8e807fff936edd97762c164fc9367 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Date: Tue, 23 Nov 2021 19:29:24 +0530 Subject: [PATCH 1/7] added jira cloud integration --- app/components/jira-cloud-account.js | 93 +++++++++++++++ app/components/jira-project.js | 107 +++++++++--------- app/models/jira-repo.js | 5 +- app/models/organization-jiraproject.js | 5 +- .../authenticated/organization/settings.hbs | 25 ++-- .../components/jira-cloud-account.emblem | 25 ++++ 6 files changed, 193 insertions(+), 67 deletions(-) create mode 100644 app/components/jira-cloud-account.js create mode 100644 app/templates/components/jira-cloud-account.emblem diff --git a/app/components/jira-cloud-account.js b/app/components/jira-cloud-account.js new file mode 100644 index 000000000..951597a93 --- /dev/null +++ b/app/components/jira-cloud-account.js @@ -0,0 +1,93 @@ +import Component from '@ember/component'; +import { inject as service } from '@ember/service'; +import ENV from 'irene/config/environment'; +import { on } from '@ember/object/evented'; +import { t } from 'ember-intl'; +// import triggerAnalytics from 'irene/utils/trigger-analytics'; +import { task } from 'ember-concurrency'; + +const JiraCloudAccountComponent = Component.extend({ + + intl: service(), + ajax: service('ajax'), + notify: service('notifications'), + organization: service('organization'), + isRevokingJIRA: false, + isJIRAConnected: false, + tJiraWillBeRevoked: t("jiraWillBeRevoked"), + tGithubErrorIntegration: t("githubErrorIntegration"), + + redirectAPI: task(function* () { + return yield this.get("ajax").request( + `/api/integrations/jira-cloud/${this.get('organization.selected.id')}/redirect/` + ) + }), + + integrateJiraCloud: task(function* () { + let data = yield this.get('redirectAPI').perform() + window.location.href = data.url; + }).evented(), + + integrateJiraCloudErrored: on('integrateJiraCloud:errored', function () { + this.get("notify").error(this.get('tGithubErrorIntegration')); + }), + + removeIntegrationUri: task(function* () { + let url = [ + '/api/organizations', + this.get('organization.selected.id'), ENV.endpoints.integrateJira + ].join('/') + return yield this.get("ajax").delete(url) + }), + + didInsertElement() { + this._super(...arguments); + this.get('checkJIRA').perform(); + }, + + checkJIRA: task(function* () { + try { + let url = [ + '/api/organizations', + this.get('organization.selected.id'), ENV.endpoints.integrateJira + ].join('/') + const data = yield this.get("ajax").request(url); + if (data.type == "jira_cloud_oauth") { + this.set("isJIRAConnected", true); + } + } catch (error) { + if (error.status == 404) { + this.set("isJIRAConnected", false); + } + } + }).drop(), + + removeIntegration: task(function* () { + yield this.get('removeIntegrationUri').perform() + }).evented(), + + removeIntegrationErrored: on('removeIntegration:errored', function (_, err) { + this.get("notify").error(err.payload.detail); + }), + + removeIntegrationSucceded: on('removeIntegration:succeeded', function () { + this.get("notify").success(this.get("tJiraWillBeRevoked")); + this.send("closeRevokeJIRAConfirmBox"); + }), + + confirmCallback() { + this.get('removeIntegration').perform(); + }, + + actions: { + openRevokeJIRAConfirmBox() { + this.set("showRevokeJIRAConfirmBox", true); + }, + + closeRevokeJIRAConfirmBox() { + this.set("showRevokeJIRAConfirmBox", false); + } + } +}); + +export default JiraCloudAccountComponent; diff --git a/app/components/jira-project.js b/app/components/jira-project.js index ab3ff47a2..544ebe27e 100644 --- a/app/components/jira-project.js +++ b/app/components/jira-project.js @@ -17,7 +17,7 @@ const JiraProjectComponent = Component.extend({ tProjectRemoved: t("projectRemoved"), tRepoNotIntegrated: t("repoNotIntegrated"), tFetchJIRAProjectFailed: t("fetchProjectFailed"), - thresholds: computed(function(){ + thresholds: computed(function () { return ENUMS.THRESHOLD.CHOICES.filter(c => c.key !== 'UNKNOWN').map(c => c.value) }), selectedThreshold: ENUMS.THRESHOLD.LOW, @@ -30,52 +30,52 @@ const JiraProjectComponent = Component.extend({ hasJIRAProject: computed.gt('jiraProjects.length', 0), - setCurrentJiraRepo: task(function *(){ + setCurrentJiraRepo: task(function* () { return yield this.get("store").findRecord( 'jira-repo', this.get('project.id')); }).evented(), - setCurrentJiraRepoErrored: on('setCurrentJiraRepo:errored', function(_, err){ - if (err.errors[0].detail && err.errors[0].detail==="JIRA not integrated"){ + setCurrentJiraRepoErrored: on('setCurrentJiraRepo:errored', function (_, err) { + if (err.errors[0].detail && err.errors[0].detail === "JIRA not integrated") { this.set('noIntegration', true); return } - if (err.errors[0].detail && err.errors[0].detail==="JIRA integration failed"){ + if (err.errors[0].detail && err.errors[0].detail === "JIRA integration failed") { this.set('reconnect', true); return } this.get("notify").error(this.get('tFetchJIRAProjectFailed')); }), - setCurrentJiraRepoSucceded: on('setCurrentJiraRepo:succeeded', function(instance){ - this.set('currentJiraProject', instance.value) - this.set('selectedRepo',{ - key: instance.value.get('project_key'), - name: instance.value.get('project_name') - }) + setCurrentJiraRepoSucceded: on('setCurrentJiraRepo:succeeded', function (instance) { + this.set('currentJiraProject', instance.value) + this.set('selectedRepo', { + key: instance.value.get('project_key'), + name: instance.value.get('project_name') + }) }), didInsertElement() { -this._super(...arguments); + this._super(...arguments); this.get('fetchJIRAProjects').perform(); this.get('setCurrentJiraRepo').perform(); }, - fetchJIRAProjects: task(function* (){ + fetchJIRAProjects: task(function* () { this.set('noAccess', false); this.set('noIntegration', false); this.set('jiraProjects', null); - try{ + try { const jiraprojects = yield this.get('store').query( - 'organizationJiraproject', {} + 'organizationJiraproject', {} ); this.set('jiraProjects', jiraprojects); } catch (error) { - if(error.errors) { + if (error.errors) { const status = error.errors[0].status; - if(status == 403) { + if (status == 403) { this.set('noAccess', true); return - } else if(status == 404) { + } else if (status == 404) { this.set('noIntegration', true); return } @@ -84,15 +84,15 @@ this._super(...arguments); } }), - deleteRepo: task(function *(){ + deleteRepo: task(function* () { return yield this.get('currentJiraProject').destroyRecord() }).evented(), - deleteRepoErrored: on('deleteRepo:errored', function(_, err){ + deleteRepoErrored: on('deleteRepo:errored', function (_, err) { this.get("notify").error(err.payload.detail); this.send("closeDeleteJIRAConfirmBox"); }), - deleteRepoSucceded: on('deleteRepo:succeeded', function(instance){ + deleteRepoSucceded: on('deleteRepo:succeeded', function (instance) { const tProjectRemoved = this.get("tProjectRemoved"); this.get('store')._removeFromIdMap(instance.value._internalModel) this.get('currentJiraProject').unloadRecord(); @@ -103,76 +103,79 @@ this._super(...arguments); this.set('selectedThreshold', 1); }), - confirmCallback(){ + confirmCallback() { this.get('deleteRepo').perform(); }, - selectProject: task( function *(){ + selectProject: task(function* () { let jiraProject = this.get('currentJiraProject'); - if (jiraProject){ + if (jiraProject) { jiraProject.setProperties( { project_key: this.get('selectedRepo.key'), project_name: this.get('selectedRepo.name'), - risk_threshold: this.get('selectedThreshold') + risk_threshold: this.get('selectedThreshold'), + jira_cloud_id: this.get('selectedRepo.jira_cloud_id') } ); - }else{ + } else { + jiraProject = this.get('store').createRecord( - 'jira-repo',{ - id: this.get('project.id'), - project_key: this.get('selectedRepo.key'), - project_name:this.get('selectedRepo.name'), - risk_threshold: this.get('selectedThreshold'), - project: this.get('project') - } + 'jira-repo', { + id: this.get('project.id'), + project_key: this.get('selectedRepo.key'), + project_name: this.get('selectedRepo.name'), + risk_threshold: this.get('selectedThreshold'), + project: this.get('project'), + jira_cloud_id: this.get('selectedRepo.jira_cloud_id') + } ) } - try{ + try { yield jiraProject.save(); - this.set("currentJiraProject",jiraProject); + this.set("currentJiraProject", jiraProject); this.get("notify").success(this.get('tIntegratedJIRA')); - yield this.set("showEditJiraModal", false ) - }catch(error){ + yield this.set("showEditJiraModal", false) + } catch (error) { yield jiraProject.rollbackAttributes(); yield this.get('store')._removeFromIdMap(jiraProject._internalModel) throw error } }).evented(), - selectProjectErrored: on('selectProject:errored', function(_, error){ - if (error.errors[0].detail==="JIRA not integrated"){ - this.set("showEditJiraModal", false ) + selectProjectErrored: on('selectProject:errored', function (_, error) { + if (error.errors[0].detail === "JIRA not integrated") { + this.set("showEditJiraModal", false) this.set('jiraProjects', null); this.set('noIntegration', true); this.set("currentJiraProject", null); this.get("notify").error(error.errors[0].detail); return } - if (error.errors[0].source.pointer==="/data/attributes/project_key" || - error.errors[0].source.pointer==="/data/attributes/project_key"){ - this.get("notify").error(this.get('tInvalidRepo')) - return - } - if (error.errors[0].source.pointer==="/data/attributes/risk_threshold"){ + if (error.errors[0].source.pointer === "/data/attributes/project_key" || + error.errors[0].source.pointer === "/data/attributes/project_key") { + this.get("notify").error(this.get('tInvalidRepo')) + return + } + if (error.errors[0].source.pointer === "/data/attributes/risk_threshold") { this.get("notify").error(this.get('tInvalidRisk')) return } this.get("notify").error(error.errors[0].detail) }), - editJiraRepoModal: task(function *(){ - yield this.set("showEditJiraModal", true ) + editJiraRepoModal: task(function* () { + yield this.set("showEditJiraModal", true) }), - closeJiraRepoModal: task(function *(){ - yield this.set("showEditJiraModal", false ) + closeJiraRepoModal: task(function* () { + yield this.set("showEditJiraModal", false) }), - selectRepo: task(function *(repo){ + selectRepo: task(function* (repo) { yield this.set('selectedRepo', repo.toJSON()); }), - selectThreshold: task(function *(threshold){ + selectThreshold: task(function* (threshold) { yield this.set('selectedThreshold', threshold); }), diff --git a/app/models/jira-repo.js b/app/models/jira-repo.js index 061559bff..aeb59981e 100644 --- a/app/models/jira-repo.js +++ b/app/models/jira-repo.js @@ -1,8 +1,9 @@ -import Model, { attr, belongsTo } from '@ember-data/model'; +import Model, { attr, belongsTo } from '@ember-data/model'; export default Model.extend({ project: belongsTo('project'), project_key: attr("string"), project_name: attr("string"), - risk_threshold: attr('number') + risk_threshold: attr('number'), + jira_cloud_id: attr("string", { defaultValue: null }), }); diff --git a/app/models/organization-jiraproject.js b/app/models/organization-jiraproject.js index 8fbc33ce7..55c335535 100644 --- a/app/models/organization-jiraproject.js +++ b/app/models/organization-jiraproject.js @@ -1,6 +1,7 @@ -import Model, { attr } from '@ember-data/model'; +import Model, { attr } from '@ember-data/model'; export default Model.extend({ key: attr('string'), - name: attr('string') + name: attr('string'), + jira_cloud_id: attr("string", { defaultValue: null }), }); diff --git a/app/templates/authenticated/organization/settings.hbs b/app/templates/authenticated/organization/settings.hbs index b5140bbf8..18e56d6f8 100644 --- a/app/templates/authenticated/organization/settings.hbs +++ b/app/templates/authenticated/organization/settings.hbs @@ -1,12 +1,9 @@ {{page-title 'Settings'}}
- + {{#if @model.organization.features.sso}} - -
+ +
{{/if}}
@@ -28,16 +25,22 @@
+
+
+
+ {{t 'jiraIntegration'}} +
+ +
+
+
{{t 'githubIntegration'}}
- +
diff --git a/app/templates/components/jira-cloud-account.emblem b/app/templates/components/jira-cloud-account.emblem new file mode 100644 index 000000000..3cdfa8e29 --- /dev/null +++ b/app/templates/components/jira-cloud-account.emblem @@ -0,0 +1,25 @@ +if isJIRAConnected + .integration.integration-jira + .integration-logo-container + img.integration-logo src="/images/jira-icon.png" + .integration-account-container + .integration-account + div + .text-lightgray.padding-b-q + | https://jira.com + button.is-primary.mp-jira-revoke click="openRevokeJIRAConfirmBox" + = t "disconnect" +else + if reconnect + h6 + = t "integrationFailed" + a.button.is-primary.mp-jira-integrate click={( perform integrateJiraCloud)} disabled=integrateJiraCloud.isRunning + = t "reconnect" + else + a.button.is-primary.mp-jira-integrate click={( perform integrateJiraCloud)} disabled=integrateJiraCloud.isRunning + = t "integrateJIRA" + if integrateJiraCloud.isRunning + = fa-icon "fa-spinner fa-spin" + = yield + += confirm-box isActive=showRevokeJIRAConfirmBox title=(t 'confirmBox.revokeJira') delegate=this disabled=isRevokingJIRA From c24050e5cc890bdb9deaa8dfbb51672e42a89417 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Date: Wed, 24 Nov 2021 11:16:03 +0530 Subject: [PATCH 2/7] removed duplicated code + event tracking + error msg string --- app/components/jira-cloud-account.js | 26 +++++++++++++------------- config/environment.js | 5 +++++ translations/en.json | 1 + 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/components/jira-cloud-account.js b/app/components/jira-cloud-account.js index 951597a93..692f5c5ec 100644 --- a/app/components/jira-cloud-account.js +++ b/app/components/jira-cloud-account.js @@ -3,7 +3,7 @@ import { inject as service } from '@ember/service'; import ENV from 'irene/config/environment'; import { on } from '@ember/object/evented'; import { t } from 'ember-intl'; -// import triggerAnalytics from 'irene/utils/trigger-analytics'; +import triggerAnalytics from 'irene/utils/trigger-analytics'; import { task } from 'ember-concurrency'; const JiraCloudAccountComponent = Component.extend({ @@ -15,7 +15,14 @@ const JiraCloudAccountComponent = Component.extend({ isRevokingJIRA: false, isJIRAConnected: false, tJiraWillBeRevoked: t("jiraWillBeRevoked"), - tGithubErrorIntegration: t("githubErrorIntegration"), + tJiraErrorIntegration: t("jiraErrorIntegration"), + + integrateJiraURL: computed('organization.selected.id', '', function () { + return [ + '/api/organizations', + this.get('organization.selected.id'), ENV.endpoints.integrateJira + ].join('/') + }), redirectAPI: task(function* () { return yield this.get("ajax").request( @@ -24,20 +31,17 @@ const JiraCloudAccountComponent = Component.extend({ }), integrateJiraCloud: task(function* () { + triggerAnalytics('feature', ENV.csb.integrateJIRACloud); let data = yield this.get('redirectAPI').perform() window.location.href = data.url; }).evented(), integrateJiraCloudErrored: on('integrateJiraCloud:errored', function () { - this.get("notify").error(this.get('tGithubErrorIntegration')); + this.get("notify").error(this.get('tJiraErrorIntegration')); }), removeIntegrationUri: task(function* () { - let url = [ - '/api/organizations', - this.get('organization.selected.id'), ENV.endpoints.integrateJira - ].join('/') - return yield this.get("ajax").delete(url) + return yield this.get("ajax").delete(this.get("integrateJiraURL")) }), didInsertElement() { @@ -47,11 +51,7 @@ const JiraCloudAccountComponent = Component.extend({ checkJIRA: task(function* () { try { - let url = [ - '/api/organizations', - this.get('organization.selected.id'), ENV.endpoints.integrateJira - ].join('/') - const data = yield this.get("ajax").request(url); + const data = yield this.get("ajax").request(this.get("integrateJiraURL")); if (data.type == "jira_cloud_oauth") { this.set("isJIRAConnected", true); } diff --git a/config/environment.js b/config/environment.js index ea9712183..49974f42f 100644 --- a/config/environment.js +++ b/config/environment.js @@ -469,6 +469,11 @@ module.exports = function (environment) { module: 'Report', product: 'Appknox', }, + integrateJIRACloud: { + feature: 'Integrate JIRA Cloud', + module: 'Report', + product: 'Appknox', + }, changePassword: { feature: 'Change Password', module: 'Setup', diff --git a/translations/en.json b/translations/en.json index a44db8c76..20ca9d5c1 100644 --- a/translations/en.json +++ b/translations/en.json @@ -356,6 +356,7 @@ "jaHTMLReport": "JA HTML Report", "jenkinsPipeline": "Jenkins Pipeline", "jira": "Jira", + "jiraErrorIntegration": "Intergration failed, please contact support", "jiraHost": "Jira Host", "jiraIntegrated": "JIRA integrated", "jiraIntegration": "JIRA Integration", From d87af75218e9ac62dd659dc3e348e8e263f4c693 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Date: Wed, 1 Dec 2021 18:41:27 +0530 Subject: [PATCH 3/7] added japenese tx message + refactor --- app/components/jira-account.js | 44 ++++++++++--------- app/components/jira-cloud-account.js | 3 ++ app/components/jira-project.js | 4 +- app/models/jira-repo.js | 2 +- app/models/organization-jiraproject.js | 2 +- .../components/jira-cloud-account.emblem | 2 +- translations/ja.json | 1 + 7 files changed, 32 insertions(+), 26 deletions(-) diff --git a/app/components/jira-account.js b/app/components/jira-account.js index 2a70cd84e..5b3fb6bf9 100644 --- a/app/components/jira-account.js +++ b/app/components/jira-account.js @@ -39,10 +39,10 @@ const JiraAccountComponent = Component.extend({ this.set('changeset', changeset); }, didInsertElement() { -this._super(...arguments); + this._super(...arguments); this.get('checkJIRA').perform(); }, - baseURL: computed('organization.selected.id', '', function(){ + baseURL: computed('organization.selected.id', '', function () { return [ '/api/organizations', this.get('organization.selected.id'), ENV.endpoints.integrateJira @@ -52,34 +52,36 @@ this._super(...arguments); this.get('revokeJIRA').perform(); }, - checkJIRA: task(function *() { + checkJIRA: task(function* () { try { const data = yield this.get("ajax").request(this.get('baseURL')); - this.set("isJIRAConnected", true); - this.set("connectedHost", data.host); - this.set("connectedUsername", data.username); - } catch(error) { - if(error.status == 404) { + if (data.type == "jira") { + this.set("isJIRAConnected", true); + this.set("connectedHost", data.host); + this.set("connectedUsername", data.username); + } + } catch (error) { + if (error.status == 404) { this.set("isJIRAConnected", false); } } }).drop(), - revokeJIRA: task(function*(){ + revokeJIRA: task(function* () { try { this.send("closeRevokeJIRAConfirmBox"); yield this.get("ajax").delete(this.get('baseURL')); const tJiraWillBeRevoked = this.get("tJiraWillBeRevoked"); this.get("notify").success(tJiraWillBeRevoked); this.get('checkJIRA').perform(); - } catch(error) { + } catch (error) { this.get("notify").error("Sorry something went wrong, please try again"); } }).drop(), - integrateJIRA: task(function *(changeset){ + integrateJIRA: task(function* (changeset) { const tJiraIntegrated = this.get("tJiraIntegrated"); yield changeset.validate() - if(!changeset.get('isValid')) { - if(changeset.get('errors') && changeset.get('errors')[0].validation) { + if (!changeset.get('isValid')) { + if (changeset.get('errors') && changeset.get('errors')[0].validation) { this.get("notify").error( changeset.get('errors')[0].validation[0], ENV.notifications @@ -88,24 +90,24 @@ this._super(...arguments); return; } const host = changeset.get('host').trim(); - const username = changeset.get('username').trim(); - const password = changeset.get('password'); + const username = changeset.get('username').trim(); + const password = changeset.get('password'); const data = { host, username, password }; try { - yield this.get("ajax").post(this.get('baseURL'), {data}) + yield this.get("ajax").post(this.get('baseURL'), { data }) this.get('checkJIRA').perform(); this.get("notify").success(tJiraIntegrated); - triggerAnalytics('feature',ENV.csb.integrateJIRA); - } catch(error) { - if(error.payload) { - if(error.payload.host) { + triggerAnalytics('feature', ENV.csb.integrateJIRA); + } catch (error) { + if (error.payload) { + if (error.payload.host) { this.get("notify").error(error.payload.host[0], ENV.notifications) } - if(error.payload.username || error.payload.password) { + if (error.payload.username || error.payload.password) { this.get("notify").error(this.get('tInValidCredentials')) } } diff --git a/app/components/jira-cloud-account.js b/app/components/jira-cloud-account.js index 692f5c5ec..3ac490ef0 100644 --- a/app/components/jira-cloud-account.js +++ b/app/components/jira-cloud-account.js @@ -1,5 +1,6 @@ import Component from '@ember/component'; import { inject as service } from '@ember/service'; +import { computed } from '@ember/object'; import ENV from 'irene/config/environment'; import { on } from '@ember/object/evented'; import { t } from 'ember-intl'; @@ -14,6 +15,7 @@ const JiraCloudAccountComponent = Component.extend({ organization: service('organization'), isRevokingJIRA: false, isJIRAConnected: false, + connectedHost: null, tJiraWillBeRevoked: t("jiraWillBeRevoked"), tJiraErrorIntegration: t("jiraErrorIntegration"), @@ -54,6 +56,7 @@ const JiraCloudAccountComponent = Component.extend({ const data = yield this.get("ajax").request(this.get("integrateJiraURL")); if (data.type == "jira_cloud_oauth") { this.set("isJIRAConnected", true); + this.set("connectedHost", data.connected_hosts) } } catch (error) { if (error.status == 404) { diff --git a/app/components/jira-project.js b/app/components/jira-project.js index 544ebe27e..985135821 100644 --- a/app/components/jira-project.js +++ b/app/components/jira-project.js @@ -114,7 +114,7 @@ const JiraProjectComponent = Component.extend({ project_key: this.get('selectedRepo.key'), project_name: this.get('selectedRepo.name'), risk_threshold: this.get('selectedThreshold'), - jira_cloud_id: this.get('selectedRepo.jira_cloud_id') + jira_cloud_project_hash: this.get('selectedRepo.jira_cloud_project_hash') } ); } else { @@ -126,7 +126,7 @@ const JiraProjectComponent = Component.extend({ project_name: this.get('selectedRepo.name'), risk_threshold: this.get('selectedThreshold'), project: this.get('project'), - jira_cloud_id: this.get('selectedRepo.jira_cloud_id') + jira_cloud_project_hash: this.get('selectedRepo.jira_cloud_project_hash') } ) } diff --git a/app/models/jira-repo.js b/app/models/jira-repo.js index aeb59981e..25d110009 100644 --- a/app/models/jira-repo.js +++ b/app/models/jira-repo.js @@ -5,5 +5,5 @@ export default Model.extend({ project_key: attr("string"), project_name: attr("string"), risk_threshold: attr('number'), - jira_cloud_id: attr("string", { defaultValue: null }), + jira_cloud_project_hash: attr("string", { defaultValue: null }), }); diff --git a/app/models/organization-jiraproject.js b/app/models/organization-jiraproject.js index 55c335535..551a80bcb 100644 --- a/app/models/organization-jiraproject.js +++ b/app/models/organization-jiraproject.js @@ -3,5 +3,5 @@ import Model, { attr } from '@ember-data/model'; export default Model.extend({ key: attr('string'), name: attr('string'), - jira_cloud_id: attr("string", { defaultValue: null }), + jira_cloud_project_hash: attr("string", { defaultValue: null }), }); diff --git a/app/templates/components/jira-cloud-account.emblem b/app/templates/components/jira-cloud-account.emblem index 3cdfa8e29..dbf44f093 100644 --- a/app/templates/components/jira-cloud-account.emblem +++ b/app/templates/components/jira-cloud-account.emblem @@ -6,7 +6,7 @@ if isJIRAConnected .integration-account div .text-lightgray.padding-b-q - | https://jira.com + | #{connectedHost} button.is-primary.mp-jira-revoke click="openRevokeJIRAConfirmBox" = t "disconnect" else diff --git a/translations/ja.json b/translations/ja.json index 4f9dc67f1..4a7d28e6e 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -356,6 +356,7 @@ "jaHTMLReport": "JA HTML Report", "jenkinsPipeline": "Jenkins Pipeline", "jira": "JIRA", + "jiraErrorIntegration": "Intergration failed, please contact support", "jiraHost": "JIRAホスト", "jiraIntegrated": "JIRAと連携されました", "jiraIntegration": "JIRA連携", From d7177217b75d39911120e2aa9102d513b27584c3 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Date: Mon, 6 Dec 2021 09:26:16 +0530 Subject: [PATCH 4/7] refactor to use jira project hash --- app/components/jira-cloud-account.js | 3 ++- app/components/jira-project.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/components/jira-cloud-account.js b/app/components/jira-cloud-account.js index 3ac490ef0..24f576505 100644 --- a/app/components/jira-cloud-account.js +++ b/app/components/jira-cloud-account.js @@ -56,7 +56,7 @@ const JiraCloudAccountComponent = Component.extend({ const data = yield this.get("ajax").request(this.get("integrateJiraURL")); if (data.type == "jira_cloud_oauth") { this.set("isJIRAConnected", true); - this.set("connectedHost", data.connected_hosts) + this.set("connectedHost", data.accounts) } } catch (error) { if (error.status == 404) { @@ -67,6 +67,7 @@ const JiraCloudAccountComponent = Component.extend({ removeIntegration: task(function* () { yield this.get('removeIntegrationUri').perform() + this.get('checkJIRA').perform(); }).evented(), removeIntegrationErrored: on('removeIntegration:errored', function (_, err) { diff --git a/app/components/jira-project.js b/app/components/jira-project.js index 985135821..4abf990ed 100644 --- a/app/components/jira-project.js +++ b/app/components/jira-project.js @@ -51,7 +51,8 @@ const JiraProjectComponent = Component.extend({ this.set('currentJiraProject', instance.value) this.set('selectedRepo', { key: instance.value.get('project_key'), - name: instance.value.get('project_name') + name: instance.value.get('project_name'), + jira_cloud_project_hash: instance.value.get('jira_cloud_project_hash') }) }), From 9923bee644fddc299e5c236a175a937d92e03928 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Date: Mon, 6 Dec 2021 09:27:54 +0530 Subject: [PATCH 5/7] added feature flag IRENE_SHOW_JIRA_CLOUD to show/hide connect jira button --- app/routes/authenticated/organization/settings.js | 3 +++ app/templates/authenticated/organization/settings.hbs | 5 +++-- config/environment.js | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/routes/authenticated/organization/settings.js b/app/routes/authenticated/organization/settings.js index 65f7bd4ff..bd776dd35 100644 --- a/app/routes/authenticated/organization/settings.js +++ b/app/routes/authenticated/organization/settings.js @@ -1,5 +1,6 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; +import ENV from 'irene/config/environment'; export default class AuthenticatedOrganizationSettingsRoute extends Route { @service me; @@ -12,6 +13,7 @@ export default class AuthenticatedOrganizationSettingsRoute extends Route { )}/github`; let integratedUser = null; let reconnect = null; + let showJiraCloud = ENV.showJiraCloud; try { let data = await this.get('ajax').request(url); if (data) { @@ -29,6 +31,7 @@ export default class AuthenticatedOrganizationSettingsRoute extends Route { user: await this.modelFor('authenticated'), organization: await this.get('organization.selected'), me: this.me, + showJiraCloud: showJiraCloud, }; } } diff --git a/app/templates/authenticated/organization/settings.hbs b/app/templates/authenticated/organization/settings.hbs index 18e56d6f8..b73d2d7fb 100644 --- a/app/templates/authenticated/organization/settings.hbs +++ b/app/templates/authenticated/organization/settings.hbs @@ -25,16 +25,17 @@
+ {{#if @model.showJiraCloud }}
{{t 'jiraIntegration'}}
- +
+ {{/if}}
diff --git a/config/environment.js b/config/environment.js index 49974f42f..26f535082 100644 --- a/config/environment.js +++ b/config/environment.js @@ -13,6 +13,7 @@ const possibleENVS = [ 'WHITELABEL_LOGO', 'WHITELABEL_THEME', 'WHITELABEL_FAVICON', + 'IRENE_SHOW_JIRA_CLOUD' ]; const ENVHandlerCONST = { @@ -31,6 +32,7 @@ const ENVHandlerCONST = { WHITELABEL_NAME: '', WHITELABEL_LOGO: '', WHITELABEL_THEME: 'dark', + IRENE_SHOW_JIRA_CLOUD: false }, processENV: Object.keys(process.env).reduce((acc, key) => { @@ -144,6 +146,7 @@ module.exports = function (environment) { var devicefarmHost = handler.getEnv('IRENE_DEVICEFARM_HOST'); var isEnterprise = handler.getBoolean('ENTERPRISE'); var showLicense = handler.getBoolean('IRENE_SHOW_LICENSE'); + var showJiraCloud = handler.getBoolean('IRENE_SHOW_JIRA_CLOUD'); var ENV = { ENVHandlerCONST: ENVHandlerCONST, version: Date.now(), @@ -151,6 +154,7 @@ module.exports = function (environment) { isAppknox: false, isEnterprise: isEnterprise, showLicense: showLicense, + showJiraCloud: showJiraCloud, exportApplicationGlobal: true, devknoxPrice: 9, // This should also change in `mycroft/settings.py` platform: -1, From 81ef3df0e024425a1bfd21163c4f5e1a386f22eb Mon Sep 17 00:00:00 2001 From: Suresh Kumar Date: Mon, 6 Dec 2021 11:42:34 +0530 Subject: [PATCH 6/7] added translate messages for cloud integration --- app/templates/authenticated/organization/settings.hbs | 2 +- app/templates/components/jira-cloud-account.emblem | 2 +- translations/en.json | 4 +++- translations/ja.json | 4 +++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/templates/authenticated/organization/settings.hbs b/app/templates/authenticated/organization/settings.hbs index b73d2d7fb..f5818b430 100644 --- a/app/templates/authenticated/organization/settings.hbs +++ b/app/templates/authenticated/organization/settings.hbs @@ -29,7 +29,7 @@
- {{t 'jiraIntegration'}} + {{t 'jiraCloudIntegration'}}
diff --git a/app/templates/components/jira-cloud-account.emblem b/app/templates/components/jira-cloud-account.emblem index dbf44f093..446609057 100644 --- a/app/templates/components/jira-cloud-account.emblem +++ b/app/templates/components/jira-cloud-account.emblem @@ -22,4 +22,4 @@ else = fa-icon "fa-spinner fa-spin" = yield -= confirm-box isActive=showRevokeJIRAConfirmBox title=(t 'confirmBox.revokeJira') delegate=this disabled=isRevokingJIRA += confirm-box isActive=showRevokeJIRAConfirmBox title=(t 'confirmBox.removeIntegration') delegate=this disabled=isRevokingJIRA diff --git a/translations/en.json b/translations/en.json index 20ca9d5c1..f8302374a 100644 --- a/translations/en.json +++ b/translations/en.json @@ -126,7 +126,8 @@ "revokePersonalToken": "Are you sure you want to delete this personal access token?", "removeUserRole": "Are you sure you want to remove this role?", "deleteInvitation": "Are you sure you want to delete this invitation?", - "resendInvitation": "Are you sure you want to resend this invitation?" + "resendInvitation": "Are you sure you want to resend this invitation?", + "removeIntegration": "Are you sure you want to revoke Jira Cloud Integration?" }, "confirmPassword": "Confirm Password", "confirmTransfer": "Confirm Transfer", @@ -360,6 +361,7 @@ "jiraHost": "Jira Host", "jiraIntegrated": "JIRA integrated", "jiraIntegration": "JIRA Integration", + "jiraCloudIntegration": "JIRA Cloud Integration", "jiraNoProject": "Linked JIRA account doesn't have any projects", "jiraPageConfigure": "page to configure JIRA integration", "jiraWillBeRevoked": "Your JIRA authorization will be revoked in a moment", diff --git a/translations/ja.json b/translations/ja.json index 4a7d28e6e..96e4f82e5 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -126,7 +126,8 @@ "revokePersonalToken": "パーソナルアクセストークンを削除してよろしいですか?", "removeUserRole": "Are you sure you want to remove this role?", "deleteInvitation": "Are you sure you want to delete this invitation?", - "resendInvitation": "Are you sure you want to resend this invitation?" + "resendInvitation": "Are you sure you want to resend this invitation?", + "removeIntegration": "Are you sure you want to revoke Jira Cloud Integration?" }, "confirmPassword": "新しいパスワード(確認)", "confirmTransfer": "Confirm Transfer", @@ -360,6 +361,7 @@ "jiraHost": "JIRAホスト", "jiraIntegrated": "JIRAと連携されました", "jiraIntegration": "JIRA連携", + "jiraCloudIntegration": "JIRA Cloud Integration", "jiraNoProject": "Linked JIRA account doesn't have any projects", "jiraPageConfigure": "JIRA連携設定ページ", "jiraWillBeRevoked": "JIRA認証は直ちに取り消されます", From 33f23143afb432359d6f43e52496329d37fe3c6a Mon Sep 17 00:00:00 2001 From: Suresh Kumar Date: Mon, 6 Dec 2021 11:44:37 +0530 Subject: [PATCH 7/7] show jira cloud integration section by default --- config/environment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environment.js b/config/environment.js index 26f535082..d85e60a10 100644 --- a/config/environment.js +++ b/config/environment.js @@ -32,7 +32,7 @@ const ENVHandlerCONST = { WHITELABEL_NAME: '', WHITELABEL_LOGO: '', WHITELABEL_THEME: 'dark', - IRENE_SHOW_JIRA_CLOUD: false + IRENE_SHOW_JIRA_CLOUD: true }, processENV: Object.keys(process.env).reduce((acc, key) => {