Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions app/components/common/busy-model-wrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Ember from 'ember';

const { Component } = Ember;

export default Component.extend({
tagName:'',
model: null,

onSaving: 'Saving...',
onDeleting: 'Deleting...'
});
21 changes: 21 additions & 0 deletions app/components/github-repo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Ember from 'ember';

const {
computed: { alias, notEmpty },
Component
} = Ember;

export default Component.extend({
classNames: ['github-repo'],
classNameBindings: ['isConnected:github-repo--connected'],
tagName: 'li',

model: null,

githubRepo: alias('model.githubRepo'),
projectGithubRepo: alias('model.projectGithubRepo'),
isConnected: notEmpty('model.projectGithubRepo'),

isLoading: alias('githubRepo.isLoading'),
name: alias('githubRepo.name')
});
36 changes: 36 additions & 0 deletions app/components/github/connected-installation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Ember from 'ember';

const {
computed,
computed: { alias },
Component,
get,
getProperties
} = Ember;

export default Component.extend({
classNames: ['github-app-installation connected'],

organizationGithubAppInstallation: null,
project: null,

githubAppInstallation: alias('organizationGithubAppInstallation.githubAppInstallation'),

organization: alias('project.organization'),
githubRepos: alias('githubAppInstallation.githubRepos'),

projectGithubRepos: alias('project.projectGithubRepos'),

repos: computed('githubRepos.@each', 'githubRepos.isFulfilled', 'projectGithubRepos.@each', 'projectGithubRepos.isFulfilled', function() {
let { githubRepos, projectGithubRepos }
= getProperties(this, 'githubRepos', 'projectGithubRepos');

return githubRepos.map((githubRepo) => {
let projectGithubRepo = projectGithubRepos.find((projectGithubRepo) => {
return get(githubRepo, 'id') == projectGithubRepo.belongsTo('githubRepo').id();
});

return { githubRepo, projectGithubRepo };
});
})
});
9 changes: 9 additions & 0 deletions app/components/github/unconnected-installation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Ember from 'ember';

const {
Component
} = Ember;

export default Component.extend({
classNames: ['github-app-installation unconnected']
});
9 changes: 5 additions & 4 deletions app/components/project-skills-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ export default Component.extend({
* @property skills
*/
skills: computed('projectSkills.@each', 'excludedSkills.@each', function() {
// NOTE: In a perfect case, we would use `Ember.computed.setDif`
// However, project.projectSkills.@each.skill is fetched assinchronously, so
// each item in `projectSkills` is a `DS.PromiseObject` instead of a
// `DS.Model`, so we have to compare by id instead.
// NOTE: In a perfect case, we would use `Ember.computed.setDiff`
// However, project.projectSkills.@each.skill is fetched
// asynchronously, so each item in `projectSkills` is a
// `DS.PromiseObject` instead of a `DS.Model`, so we have to
// compare by id instead.
let { projectSkills, excludedSkills } = getProperties(this, 'projectSkills', 'excludedSkills');
return projectSkills.filter((skill) => {
return !excludedSkills || !excludedSkills.isAny('id', get(skill, 'id'));
Expand Down
68 changes: 61 additions & 7 deletions app/controllers/project/settings/integrations.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,80 @@
import Ember from 'ember';
import ENV from 'code-corps-ember/config/environment';

const {
Controller,
computed: { alias, mapBy },
computed,
get,
getProperties,
inject: { service }
} = Ember;

export default Controller.extend({
githubAppUrl: ENV.github.appUrl,
store: service(),

organization: alias('project.organization'),
organizationGithubAppInstallations: alias('organization.organizationGithubAppInstallations'),

userInstallations: alias('user.githubAppInstallations'),
connectedInstallations: mapBy('organizationGithubAppInstallations', 'githubAppInstallation'),

unconnectedInstallations: computed('userInstallations', 'connectedInstallations', function() {
let { userInstallations, connectedInstallations }
= getProperties(this, 'userInstallations', 'connectedInstallations');

let connectedInstallationIds
= connectedInstallations.map((installation) => get(installation, 'id'));

return userInstallations.filter((installation) => {
return connectedInstallationIds.indexOf(get(installation, 'id')) === -1;
});
}),

actions: {
/**
* Action which calls to create a new GitHub App installation record
* and an organization GitHub App Installation record for the current
* project
* Connects an organization to a githubAppInstallation by creating a
* through record called orgaizationGithubAppInstallation
*
* Triggered when user clicks a button to install the GitHub App
*
* @method createGithubAppInstallation
* @param {DS.Model} project A project record to initialize a new installation.
* @method connect
* @param {DS.Model} organization The organization to connect an installation with
* @param {DS.Model} githubAppInstallation The installation to connect an organization with
*/
createGithubAppInstallation(/* project */) {
// .createRecord();
connect(organization, githubAppInstallation) {
let store = get(this, 'store');
let record = store.createRecord(
'organizationGithubAppInstallation',
{ organization, githubAppInstallation }
);

return record.save();
},

/**
* Disconnects an organization from a githubAppInstallation by deleting the
* specified organizationGithubAppInstallation
*
* Triggered when user clicks a button to "remove" the GitHub App
*
* @method disconnect
* @param {DS.Model} organizationGithubAppInstallation The link record that gets deleted
*/
disconnect(organizationGithubAppInstallation) {
return organizationGithubAppInstallation.destroyRecord();
},

connectRepo(githubRepo, project) {
let projectGithubRepo = get(this, 'store').createRecord(
'project-github-repo', { project, githubRepo }
);
return projectGithubRepo.save();
},

disconnectRepo(projectGithubRepo) {
return projectGithubRepo.destroyRecord();
}
}
});
5 changes: 4 additions & 1 deletion app/models/github-app-installation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';

export default Model.extend({
githubAccountAvatarUrl: attr(),
githubAccountId: attr(),
githubAccountLogin: attr(),
githubAccountType: attr(),
githubId: attr(),
insertedAt: attr(),
installed: attr(),
Expand All @@ -11,6 +15,5 @@ export default Model.extend({

githubRepos: hasMany('github-repo', { async: true }),
organizationGithubAppInstallations: hasMany('organization-github-app-installation', { async: true }),
project: belongsTo('project', { async: true }),
user: belongsTo('user', { async: true })
});
5 changes: 3 additions & 2 deletions app/models/github-repo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo } from 'ember-data/relationships';
import { belongsTo, hasMany } from 'ember-data/relationships';

export default Model.extend({
githubAccountAvatarUrl: attr(),
Expand All @@ -12,5 +12,6 @@ export default Model.extend({
name: attr(),
updatedAt: attr(),

githubAppInstallation: belongsTo('github-app-installation', { async: true })
githubAppInstallation: belongsTo('github-app-installation', { async: true }),
projectGithubRepos: hasMany('project-github-repo', { async: true })
});
1 change: 1 addition & 0 deletions app/models/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default Model.extend({
name: attr(),
slug: attr(),

organizationGithubAppInstallations: hasMany('organization-github-app-installation', { async: true }),
owner: belongsTo('user', { async: true }),
projects: hasMany('project', { async: true }),
stripeConnectAccount: belongsTo('stripe-connect-account', { async: true })
Expand Down
2 changes: 2 additions & 0 deletions app/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export default Model.extend({

stateTransition: attr(),

githubAppInstallations: hasMany('github-app-installation', { async: true }),

projectUsers: hasMany('project-user', { async: true }),

stripeConnectSubscriptions: hasMany('stripe-connect-subscription', { async: true }),
Expand Down
7 changes: 3 additions & 4 deletions app/routes/project/settings/integrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ export default Route.extend({

model() {
let project = this.modelFor('project');
let organization = get(project, 'organization');
let user = get(this, 'currentUser.user');

return RSVP.hash({ project, organization, user });
return RSVP.hash({ project, user });
},

setupController(controller, { project, organization, user }) {
setProperties(controller, { project, organization, user });
setupController(controller, { project, user }) {
setProperties(controller, { project, user });
}
});
2 changes: 1 addition & 1 deletion app/styles/_icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ $github-light: 16px 16px $spriteURL 0 -369px $spritex2URL;
$github-dark: 16px 16px $spriteURL -16px -369px $spritex2URL;
$repo: 12px 16px $spriteURL 0 -385px $spritex2URL;
$repo-blue: 12px 16px $spriteURL -12px -385px $spritex2URL;
$sync: 18px 16px $spriteURL -24px -385px $spritex2URL;
$sync: 28px 16px $spriteURL -24px -385px $spritex2URL;

.box-icon {
@include sprite($box);
Expand Down
2 changes: 2 additions & 0 deletions app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@
//
// COMPONENTS - GITHUB
//
@import "components/github-app-installation";
@import "components/github-repo";
@import "components/github-connect-state";

//
Expand Down
42 changes: 42 additions & 0 deletions app/styles/components/github-app-installation.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.github-app-installation {
border: 1px solid $gray--lightest;
border-radius: 4px;
margin-bottom: 20px;

&__details {
display: flex;
justify-content: space-between;
padding: 10px 20px;

> div {
display: flex;
}

h4 {
font-weight: 700;
line-height: 40px;
margin: 0 0 0 10px;
}

img {
border-radius: 4px;
height: 40px;
width: 40px;
}

a, span {
color: $text--lightest;
font-size: $body-font-size-small;
line-height: 40px;

&:hover {
color: $red;
}
}
}

&__repos {
border-top: 1px solid $gray--lightest;
padding: 10px 20px;
}
}
52 changes: 52 additions & 0 deletions app/styles/components/github-repo.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.github-repo {
display: flex;
justify-content: space-between;
line-height: 30px;
margin-bottom: 10px;
vertical-align: middle;

&__name {
&:before {
content: "";
display: inline-block;
margin: 0 10px 0 0;
vertical-align: middle;
@include sprite($repo);
}
}

&__actions {
display: flex;
font-size: $body-font-size-small;
}

&__remove-link {
color: $text--lightest;
&:hover {
color: $red;
}
}
}

.github-repo--connected {
.github-repo__name {
color: $blue;

&:before {
@include sprite($repo-blue);
}
}

.github-repo__sync {
color: $blue;
margin-right: 10px;

&:before {
content: "";
display: inline-block;
margin: -1px 5px 0 0;
vertical-align: middle;
@include sprite($sync);
}
}
}
9 changes: 9 additions & 0 deletions app/templates/components/common/busy-model-wrapper.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{{#if model.isSaving}}
{{#if model.isDeleted}}
<span>{{onDeleting}}</span>
{{else}}
<span>{{onSaving}}</span>
{{/if}}
{{else}}
{{yield}}
{{/if}}
14 changes: 14 additions & 0 deletions app/templates/components/github-repo.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{#if (and githubRepo.isLoaded (or (not isConnected) projectGithubRepo.isLoaded))}}
<div class="github-repo__name" data-test-github-repo-name>{{name}}</div>
<div class="github-repo__actions" data-test-github-repo-actions>
{{#common/busy-model-wrapper
model=projectGithubRepo
onSaving='Connecting...'
onDeleting='Disconnecting...'
}}
{{yield}}
{{/common/busy-model-wrapper}}
</div>
{{else}}
Loading...
{{/if}}
Loading