Merge pull request #123 from 67P/feature/122-edit_contributors

Update contributor profiles
This commit was merged in pull request #123.
This commit is contained in:
2019-06-02 01:56:16 +02:00
committed by GitHub
11 changed files with 163 additions and 68 deletions
+7 -2
View File
@@ -1,6 +1,7 @@
import Component from '@ember/component'; import Component from '@ember/component';
import { and, notEmpty } from '@ember/object/computed'; import { and, notEmpty } from '@ember/object/computed';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import { isPresent } from '@ember/utils';
export default Component.extend({ export default Component.extend({
@@ -26,6 +27,12 @@ export default Component.extend({
init () { init () {
this._super(...arguments); this._super(...arguments);
this.setDefaultAttributes();
this.reset();
},
setDefaultAttributes () {
if (isPresent(this.attributes)) { return; }
this.set('attributes', { this.set('attributes', {
account: null, account: null,
@@ -37,8 +44,6 @@ export default Component.extend({
gitea_username: null, gitea_username: null,
wiki_username: null wiki_username: null
}); });
this.reset();
}, },
reset: function() { reset: function() {
+24 -36
View File
@@ -1,62 +1,50 @@
<form {{action "submit" on="submit"}}> <form {{action "submit" on="submit"}}>
<p> <p>
{{input name="account" <label for="c-account">Ethereum account</label>
type="text" {{input name="account" id="c-account"
type="text" value=account
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4" placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
value=account
class=(if isValidAccount "valid" "")}} class=(if isValidAccount "valid" "")}}
</p> </p>
<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="person" selected={{eq kind "person"}}>Person</option>
<option value="organization" selected={{eq kind "organization"}}>Organization</option> <option value="organization" selected={{eq kind "organization"}}>Organization</option>
</select> </select>
</p> </p>
<p> <p>
{{input name="name" <label for="c-name">Name</label>
type="text" {{input name="name" type="text" value=name placeholder="Zero Cool"
placeholder="Name" class=(if isValidName "valid" "") id="c-name"}}
value=name
class=(if isValidName "valid" "")}}
</p> </p>
<p> <p>
{{input name="url" <label for="c-url">URL</label>
type="text" {{input name="url" type="text" value=url placeholder="http://zerocool.bit"
placeholder="URL" class=(if isValidURL "valid" "") id="c-url"}}
value=url
class=(if isValidURL "valid" "")}}
</p> </p>
<p> <p>
{{input name="github_uid" <label for="c-github-uid">GitHub UID</label>
type="text" {{input name="github_uid" type="text" value=github_uid placeholder="2342"
placeholder="GitHub UID (123)" class=(if isValidGithubUID "valid" "") id="c-github-uid"}}
value=github_uid
class=(if isValidGithubUID "valid" "")}}
</p> </p>
<p> <p>
{{input name="github_username" <label for="c-github-username">GitHub username</label>
type="text" {{input name="github_username" type="text" value=github_username placeholder="zerocool"
placeholder="GitHub username" class=(if isValidGithubUsername "valid" "") id="c-github-username"}}
value=github_username
class=(if isValidGithubUsername "valid" "")}}
</p> </p>
<p> <p>
{{input name="gitea_username" <label for="c-gitea-username">Gitea username</label>
type="text" {{input name="gitea_username" type="text" value=gitea_username placeholder="zerocool"
placeholder="Gitea username" class=(if isValidGiteaUsername "valid" "") id="c-gitea-username"}}
value=gitea_username
class=(if isValidGiteaUsername "valid" "")}}
</p> </p>
<p> <p>
{{input name="wiki_username" <label for="c-wiki-username">Wiki username</label>
type="text" {{input name="wiki_username" type="text" value=wiki_username placeholder="ZeroCool"
placeholder="Wiki Username" class=(if isValidWikiUsername "valid" "") id="c-wiki-username"}}
value=wiki_username
class=(if isValidWikiUsername "valid" "")}}
</p> </p>
<p class="actions"> <p class="actions">
{{input type="submit" {{input type="submit" disabled=inProgress
disabled=inProgress
value=(if inProgress "Processing" "Save")}} value=(if inProgress "Processing" "Save")}}
</p> </p>
</form> </form>
@@ -26,6 +26,9 @@
<a href="https://ipfs.io/ipfs/{{c.contributor.ipfsHash}}" target="_blank" rel="noopener">Inspect IPFS profile</a> <a href="https://ipfs.io/ipfs/{{c.contributor.ipfsHash}}" target="_blank" rel="noopener">Inspect IPFS profile</a>
</li> </li>
{{/if}} {{/if}}
<li>
{{link-to "Edit profile" "contributors.edit" c.contributor.id}}
</li>
</ul> </ul>
{{#if c.showMetadata}} {{#if c.showMetadata}}
<pre>{{c.contributor.ipfsData}}</pre> <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 Controller from '@ember/controller';
import { alias } from '@ember/object/computed';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
export default Controller.extend({ export default Controller.extend({
kredits: service(), kredits: service(),
contributors: alias('kredits.contributors'),
actions: { actions: {
save (contributor) { save (contributor) {
return this.kredits.addContributor(contributor) return this.kredits
.then(contributor => { .addContributor(contributor)
this.transitionToRoute('index'); .then(() => this.transitionToRoute('index'))
return contributor;
});
} }
} }
+1
View File
@@ -15,6 +15,7 @@ Router.map(function() {
}); });
this.route('contributors', function() { this.route('contributors', function() {
this.route('new'); 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
@@ -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 contributionsUnconfirmed = this.contributionsUnconfirmed.filterBy('vetoed', false);
const contributionsGrouped = groupBy(contributionsUnconfirmed, 'contributorId'); const contributionsGrouped = groupBy(contributionsUnconfirmed, 'contributorId');
const contributorsWithUnconfirmed = contributionsGrouped.map(c => c.value.toString()); 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 // This is called in the application route's beforeModel(). So it is
// initialized before everything else, and we can rely on the ethProvider and // initialized before everything else, and we can rely on the ethProvider and
// the potential currentUserAccounts to be available // the potential currentUserAccounts to be available
getEthProvider: function() { getEthProvider () {
let ethProvider; let ethProvider;
return new RSVP.Promise(async (resolve) => { return new RSVP.Promise(async (resolve) => {
@@ -190,9 +190,20 @@ export default Service.extend({
return this.kredits.Contributor.add(attributes, { gasLimit: 350000 }) return this.kredits.Contributor.add(attributes, { gasLimit: 350000 })
.then(data => { .then(data => {
console.debug('[kredits] add contributor response', data); console.debug('[kredits] add contributor response', data);
const contributor = Contributor.create(attributes); });
this.contributors.pushObject(contributor); },
return contributor;
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);
}); });
}, },
@@ -293,6 +304,11 @@ export default Service.extend({
// Contract events // 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 this.kredits.Contribution
.on('ContributionVetoed', this.handleContributionVetoed.bind(this)) .on('ContributionVetoed', this.handleContributionVetoed.bind(this))
@@ -305,6 +321,22 @@ export default Service.extend({
.on('Transfer', this.handleTransfer.bind(this)); .on('Transfer', this.handleTransfer.bind(this));
}, },
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) { handleContributionVetoed (contributionId) {
console.debug('[kredits] ContributionVetoed event received for ', contributionId); console.debug('[kredits] ContributionVetoed event received for ', contributionId);
const contribution = this.contributions.findBy('id', contributionId); const contribution = this.contributions.findBy('id', contributionId);
+11
View File
@@ -17,6 +17,12 @@ section#add-proposal {
} }
} }
label {
display: block;
margin-bottom: 0.5rem;
opacity: 0.7;
}
input[type=text], select { input[type=text], select {
width: 100%; width: 100%;
padding: 1rem; padding: 1rem;
@@ -25,9 +31,14 @@ section#add-proposal {
background-color: rgba(22, 21, 40, 0.3); background-color: rgba(22, 21, 40, 0.3);
color: #fff; color: #fff;
font-size: 1.2rem; font-size: 1.2rem;
transition: border-color 0.1s linear;
&:focus, &.valid { &:focus, &.valid {
background-color: rgba(22, 21, 40, 0.6); background-color: rgba(22, 21, 40, 0.6);
} }
&:focus {
border-color: $blue;
}
&::placeholder { &::placeholder {
color: rgba(238, 238, 238, 0.5); 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> </header>
<div class="content"> <div class="content">
{{add-contributor contributors=contributors save=(action "save")}} {{add-contributor save=(action "save")}}
</div> </div>
</section> </section>