Update contributor profiles

* Adds a new page for updating profiles
* Refactors the add-contributor component to allow for updating
  existing contributors
* Adds input labels to the contributor form and improves placeholders
* Adds event handlers for all contract contributor changes and uses them
  for updating the UI

refs #122
This commit is contained in:
2019-05-29 16:14:11 +02:00
parent 58bd729acb
commit 1c1f772ff5
11 changed files with 147 additions and 52 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
});
}
});
+37 -5
View File
@@ -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) => {
@@ -293,6 +304,11 @@ export default Service.extend({
// Contract events
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);
+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>