Update contributor profiles #123

Merged
raucao merged 2 commits from feature/122-edit_contributors into master 2019-06-01 23:56:17 +00:00
11 changed files with 163 additions and 68 deletions
+7 -2
View File
@@ -1,6 +1,7 @@
import Component from '@ember/component';
import { and, notEmpty } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import { isPresent } from '@ember/utils';
export default Component.extend({
@@ -26,6 +27,12 @@ export default Component.extend({
init () {
this._super(...arguments);
this.setDefaultAttributes();
this.reset();
},
setDefaultAttributes () {
if (isPresent(this.attributes)) { return; }
this.set('attributes', {
account: null,
@@ -37,8 +44,6 @@ export default Component.extend({
gitea_username: null,
wiki_username: null
});
this.reset();
},
reset: function() {
+24 -36
View File
@@ -1,62 +1,50 @@
<form {{action "submit" on="submit"}}>
<p>
{{input name="account"
type="text"
<label for="c-account">Ethereum account</label>
{{input name="account" id="c-account"
type="text" value=account
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
value=account
class=(if isValidAccount "valid" "")}}
</p>
<p>
<select required onchange={{action (mut kind) value="target.value"}}>
<label for="c-kind">Kind</label>
<select required onchange={{action (mut kind) value="target.value"}} id="c-kind">
<option value="person" selected={{eq kind "person"}}>Person</option>
<option value="organization" selected={{eq kind "organization"}}>Organization</option>
</select>
</p>
<p>
{{input name="name"
type="text"
placeholder="Name"
value=name
class=(if isValidName "valid" "")}}
<label for="c-name">Name</label>
{{input name="name" type="text" value=name placeholder="Zero Cool"
class=(if isValidName "valid" "") id="c-name"}}
</p>
<p>
{{input name="url"
type="text"
placeholder="URL"
value=url
class=(if isValidURL "valid" "")}}
<label for="c-url">URL</label>
{{input name="url" type="text" value=url placeholder="http://zerocool.bit"
class=(if isValidURL "valid" "") id="c-url"}}
</p>
<p>
{{input name="github_uid"
type="text"
placeholder="GitHub UID (123)"
value=github_uid
class=(if isValidGithubUID "valid" "")}}
<label for="c-github-uid">GitHub UID</label>
{{input name="github_uid" type="text" value=github_uid placeholder="2342"
class=(if isValidGithubUID "valid" "") id="c-github-uid"}}
</p>
<p>
{{input name="github_username"
type="text"
placeholder="GitHub username"
value=github_username
class=(if isValidGithubUsername "valid" "")}}
<label for="c-github-username">GitHub username</label>
{{input name="github_username" type="text" value=github_username placeholder="zerocool"
class=(if isValidGithubUsername "valid" "") id="c-github-username"}}
</p>
<p>
{{input name="gitea_username"
type="text"
placeholder="Gitea username"
value=gitea_username
class=(if isValidGiteaUsername "valid" "")}}
<label for="c-gitea-username">Gitea username</label>
{{input name="gitea_username" type="text" value=gitea_username placeholder="zerocool"
class=(if isValidGiteaUsername "valid" "") id="c-gitea-username"}}
</p>
<p>
{{input name="wiki_username"
type="text"
placeholder="Wiki Username"
value=wiki_username
class=(if isValidWikiUsername "valid" "")}}
<label for="c-wiki-username">Wiki username</label>
{{input name="wiki_username" type="text" value=wiki_username placeholder="ZeroCool"
class=(if isValidWikiUsername "valid" "") id="c-wiki-username"}}
</p>
<p class="actions">
{{input type="submit"
disabled=inProgress
{{input type="submit" disabled=inProgress
value=(if inProgress "Processing" "Save")}}
</p>
</form>
@@ -26,6 +26,9 @@
<a href="https://ipfs.io/ipfs/{{c.contributor.ipfsHash}}" target="_blank" rel="noopener">Inspect IPFS profile</a>
</li>
{{/if}}
<li>
{{link-to "Edit profile" "contributors.edit" c.contributor.id}}
</li>
</ul>
{{#if c.showMetadata}}
<pre>{{c.contributor.ipfsData}}</pre>
+18
View File
@@ -0,0 +1,18 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
actions: {
save (attributes) {
return this.kredits
.updateContributor(this.model.id, attributes)
.then(() => this.transitionToRoute('index'))
}
}
});
+3 -8
View File
@@ -1,21 +1,16 @@
import Controller from '@ember/controller';
import { alias } from '@ember/object/computed';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
contributors: alias('kredits.contributors'),
actions: {
save (contributor) {
return this.kredits.addContributor(contributor)
.then(contributor => {
this.transitionToRoute('index');
return contributor;
});
return this.kredits
.addContributor(contributor)
.then(() => this.transitionToRoute('index'))
}
}
+1
View File
@@ -15,6 +15,7 @@ Router.map(function() {
});
this.route('contributors', function() {
this.route('new');
this.route('edit', { path: ':id/edit' });
});
});
+29
View File
@@ -0,0 +1,29 @@
import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';
import { alias } from '@ember/object/computed';
export default Route.extend({
kredits: service(),
contributors: alias('kredits.contributors'),
model(params) {
return this.kredits.contributors.findBy('id', params.id);
},
setupController (controller, model) {
this._super(controller, model);
controller.set('attributes', {
account: model.account,
name: model.name,
kind: model.kind,
url: model.url,
github_username: model.github_username,
github_uid: model.github_uid,
gitea_username: model.gitea_username,
wiki_username: model.wiki_username
bumi commented 2019-06-01 10:16:57 +00:00 (Migrated from github.com)
Review

do you think we can use the accounts array here already? with adding more services we at some point would want to directly add entries to the accounts array.

do you think we can use the `accounts` array here already? with adding more services we at some point would want to directly add entries to the accounts array.
raucao commented 2019-06-01 11:01:01 +00:00 (Migrated from github.com)
Review

That should be a separate PR, as it requires quite some changes in the code.

That should be a separate PR, as it requires quite some changes in the code.
});
}
});
+53 -21
View File
@@ -47,7 +47,7 @@ export default Service.extend({
});
}),
kreditsByContributor: computed('contributionsUnconfirmed.@each.vetoed', 'contributors', function() {
kreditsByContributor: computed('contributionsUnconfirmed.@each.vetoed', 'contributors.[]', function() {
const contributionsUnconfirmed = this.contributionsUnconfirmed.filterBy('vetoed', false);
const contributionsGrouped = groupBy(contributionsUnconfirmed, 'contributorId');
const contributorsWithUnconfirmed = contributionsGrouped.map(c => c.value.toString());
@@ -87,7 +87,7 @@ export default Service.extend({
// This is called in the application route's beforeModel(). So it is
// initialized before everything else, and we can rely on the ethProvider and
// the potential currentUserAccounts to be available
getEthProvider: function() {
getEthProvider () {
let ethProvider;
return new RSVP.Promise(async (resolve) => {
@@ -136,7 +136,7 @@ export default Service.extend({
});
},
setup() {
setup () {
return this.getEthProvider().then((providerAndSigner) => {
let kredits = new Kredits(providerAndSigner.ethProvider, providerAndSigner.ethSigner, {
addresses: { Kernel: config.kreditsKernelAddress },
@@ -172,14 +172,14 @@ export default Service.extend({
}),
loadInitialData() {
loadInitialData () {
return this.getContributors()
.then(contributors => this.contributors.pushObjects(contributors))
.then(() => this.getContributions())
.then(contributions => this.contributions.pushObjects(contributions))
},
addContributor(attributes) {
addContributor (attributes) {
if (attributes.github_uid) {
const uidInt = parseInt(attributes.github_uid);
attributes.github_uid = uidInt;
@@ -190,13 +190,24 @@ export default Service.extend({
return this.kredits.Contributor.add(attributes, { gasLimit: 350000 })
.then(data => {
console.debug('[kredits] add contributor response', data);
const contributor = Contributor.create(attributes);
this.contributors.pushObject(contributor);
return contributor;
});
},
getContributors() {
updateContributor (id, attributes) {
if (attributes.github_uid) {
const uidInt = parseInt(attributes.github_uid);
attributes.github_uid = uidInt;
}
console.debug('[kredits] update contributor', attributes);
return this.kredits.Contributor.updateProfile(id, attributes, { gasLimit: 350000 })
.then(data => {
console.debug('[kredits] updateProfile response', data);
});
},
getContributors () {
return this.kredits.Contributor.all()
.then((contributors) => {
return contributors.map((contributor) => {
@@ -205,7 +216,7 @@ export default Service.extend({
});
},
addContribution(attributes) {
addContribution (attributes) {
console.debug('[kredits] add contribution', attributes);
return this.kredits.Contribution.addContribution(attributes, { gasLimit: 300000 })
@@ -220,7 +231,7 @@ export default Service.extend({
});
},
addProposal(attributes) {
addProposal (attributes) {
console.debug('[kredits] add proposal', attributes);
return this.kredits.Proposal.addProposal(attributes)
@@ -231,7 +242,7 @@ export default Service.extend({
});
},
getProposals() {
getProposals () {
return this.kredits.Proposal.all()
.then((proposals) => {
return proposals.map((proposal) => {
@@ -241,7 +252,7 @@ export default Service.extend({
});
},
getContributions() {
getContributions () {
return this.kredits.Contribution.all({page: {size: 200}})
.then(contributions => {
return contributions.map(contribution => {
@@ -251,7 +262,7 @@ export default Service.extend({
});
},
vote(proposalId) {
vote (proposalId) {
console.debug('[kredits] vote for', proposalId);
return this.kredits.Proposal.functions.vote(proposalId)
@@ -261,7 +272,7 @@ export default Service.extend({
});
},
veto(contributionId) {
veto (contributionId) {
console.debug('[kredits] veto against', contributionId);
return this.kredits.Contribution.functions.veto(contributionId, { gasLimit: 300000 })
@@ -292,7 +303,12 @@ export default Service.extend({
},
// Contract events
addContractEventHandlers() {
addContractEventHandlers () {
this.kredits.Contributor
.on('ContributorProfileUpdated', this.handleContributorChange.bind(this))
.on('ContributorAccountUpdated', this.handleContributorChange.bind(this))
.on('ContributorAdded', this.handleContributorChange.bind(this))
this.kredits.Contribution
.on('ContributionVetoed', this.handleContributionVetoed.bind(this))
@@ -305,7 +321,23 @@ export default Service.extend({
.on('Transfer', this.handleTransfer.bind(this));
},
handleContributionVetoed(contributionId) {
async handleContributorChange (contributorId, ...args) {
console.debug('[kredits] Contributor add/update event received for ID', contributorId);
console.debug('[kredits] Event data:', args);
const contributorData = await this.kredits.Contributor.getById(contributorId);
const newContributor = Contributor.create(contributorData);
const oldContributor = this.contributors.findBy('id', contributorId.toString());
if (oldContributor) {
console.debug('[kredits] old contributor', oldContributor);
this.contributors.removeObject(oldContributor);
}
console.debug('[kredits] new contributor', newContributor);
this.contributors.pushObject(newContributor);
},
handleContributionVetoed (contributionId) {
console.debug('[kredits] ContributionVetoed event received for ', contributionId);
const contribution = this.contributions.findBy('id', contributionId);
console.debug('[kredits] contribution', contribution);
@@ -315,7 +347,7 @@ export default Service.extend({
}
},
handleProposalCreated(proposalId) {
handleProposalCreated (proposalId) {
let proposal = this.findProposalById(proposalId);
if (proposal) {
@@ -331,7 +363,7 @@ export default Service.extend({
},
// TODO: We may want to reload that proposal to show the voter as voted
handleProposalVoted(proposalId, voterId, totalVotes) {
handleProposalVoted (proposalId, voterId, totalVotes) {
let proposal = this.findProposalById(proposalId);
if (proposal) {
@@ -339,7 +371,7 @@ export default Service.extend({
}
},
handleProposalExecuted(proposalId, contributorId, amount) {
handleProposalExecuted (proposalId, contributorId, amount) {
let proposal = this.findProposalById(proposalId);
if (proposal.get('isExecuted')) {
@@ -354,7 +386,7 @@ export default Service.extend({
.incrementProperty('balance', amount);
},
handleTransfer(from, to, value) {
handleTransfer (from, to, value) {
value = value.toNumber();
this.contributors
+11
View File
@@ -17,6 +17,12 @@ section#add-proposal {
}
}
label {
display: block;
margin-bottom: 0.5rem;
opacity: 0.7;
}
input[type=text], select {
width: 100%;
padding: 1rem;
@@ -25,9 +31,14 @@ section#add-proposal {
background-color: rgba(22, 21, 40, 0.3);
color: #fff;
font-size: 1.2rem;
transition: border-color 0.1s linear;
&:focus, &.valid {
background-color: rgba(22, 21, 40, 0.6);
}
&:focus {
border-color: $blue;
}
&::placeholder {
color: rgba(238, 238, 238, 0.5);
}
+13
View File
@@ -0,0 +1,13 @@
<main class="center-column">
<section id="add-contributor">
<header>
<h2>Update contributor profile</h2>
</header>
<div class="content">
{{add-contributor attributes=attributes save=(action "save")}}
</div>
</section>
</main>
+1 -1
View File
@@ -6,7 +6,7 @@
</header>
<div class="content">
{{add-contributor contributors=contributors save=(action "save")}}
{{add-contributor save=(action "save")}}
</div>
</section>