Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c30637ec7e | |||
| f152fb1382 | |||
| 0e66765f1d | |||
| cb4d20cf81 | |||
| 1945074db6 | |||
| 575c1a11c2 | |||
| 47b8421d35 | |||
| 38d853a272 | |||
| 0320d6149f | |||
| ba9b3530fa | |||
| e78832e2c8 | |||
| 804060ad34 | |||
| 840519a437 | |||
| 7c54ebcbd0 | |||
| d07c0d67bf | |||
| a0ee2f7bb8 | |||
| d070288e17 | |||
| 681f80f6ab | |||
| eb5c87308a |
@@ -22,7 +22,8 @@ You will need the following things properly installed on your computer.
|
|||||||
|
|
||||||
## Running / Development
|
## Running / Development
|
||||||
|
|
||||||
* `ember serve`
|
|
||||||
|
* `ember serve` - by default kredits-web connects to the Ethreum Kovan network
|
||||||
* Visit your app at [http://localhost:4200](http://localhost:4200).
|
* Visit your app at [http://localhost:4200](http://localhost:4200).
|
||||||
* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
|
* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
|
||||||
|
|
||||||
@@ -56,13 +57,13 @@ _(You need collaborator permissions on the 5apps Deploy project.)_
|
|||||||
## Working with locally deployed contracts
|
## Working with locally deployed contracts
|
||||||
|
|
||||||
The smart contracts and their JavaScript wrapper library are developed in the
|
The smart contracts and their JavaScript wrapper library are developed in the
|
||||||
[truffle-kredits](https://github.com/67P/truffle-kredits) repo/package.
|
[kredits-contracts](https://github.com/67P/kredits-contracts) repo/package.
|
||||||
|
|
||||||
You can run `kredits-web` on your machine, against a local, simulated Ethereum
|
You can run `kredits-web` on your machine, against a local, simulated Ethereum
|
||||||
network, provided e.g. by [ganache](http://truffleframework.com/ganache/) or
|
network, provided e.g. by [ganache](http://truffleframework.com/ganache/) or
|
||||||
[ganache-cli](https://github.com/trufflesuite/ganache-cli).
|
[ganache-cli](https://github.com/trufflesuite/ganache-cli).
|
||||||
|
|
||||||
[truffle-kredits](https://github.com/67P/truffle-kredits) holds all the tools
|
[kredits-contracts](https://github.com/67P/kredits-contracts) holds all the tools
|
||||||
to start and set up such a simulated network, as well as to deploy smart
|
to start and set up such a simulated network, as well as to deploy smart
|
||||||
contracts to it.
|
contracts to it.
|
||||||
|
|
||||||
@@ -75,22 +76,22 @@ Run a local IPFS deamon in offline mode.
|
|||||||
* Make sure CORS headers are configured. See [IPFS](#ipfs) for more info.
|
* Make sure CORS headers are configured. See [IPFS](#ipfs) for more info.
|
||||||
* `ipfs daemon --offline`
|
* `ipfs daemon --offline`
|
||||||
|
|
||||||
#### 2. truffle-kredits
|
#### 2. kredits-contracts
|
||||||
|
|
||||||
Get your local Ethereum development node running.
|
Get your local Ethereum development node running.
|
||||||
|
|
||||||
* Clone [truffle-kredits](https://github.com/67P/truffle-kredits)
|
* Clone [kredits-contracts](https://github.com/67P/kredits-contracts)
|
||||||
* `npm install`
|
* `npm install`
|
||||||
* `npm run ganache` - which is basically: `ganache-cli -p 7545 -i 100` (we use the non-default port for local networks and a fixed network id)
|
* `npm run ganache` - which is basically: `ganache-cli -p 7545 -i 100` (we use the non-default port for local networks and a fixed network id)
|
||||||
* `npm run bootstrap` - bootstrap runs fresh migrations, adds some seed data and writes the address/abi information to JSON that will be used by kredits-web
|
* `npm run bootstrap` - bootstrap runs fresh migrations, adds some seed data and writes the address/abi information to JSON that will be used by kredits-web
|
||||||
* `npm link` - make the `truffle-kredits` module linkable as `kredits-contracts` on your machine
|
* `npm link` - make the `kredits-contracts` module linkable as `kredits-contracts` on your machine
|
||||||
|
|
||||||
#### 3. kredits-web
|
#### 3. kredits-web
|
||||||
|
|
||||||
With IPFS and Ethereum/ganache running, you can now start this Ember app.
|
With IPFS and Ethereum/ganache running, you can now start this Ember app.
|
||||||
|
|
||||||
* `npm link kredits-contracts` - link the local `truffle-kredits` package (it will become `kredits-contracts` soon)
|
* `npm link kredits-contracts` - link the local `kredits-contracts` package
|
||||||
* `npm start`
|
* `npm run start:local` - NETWORK_ID=100 and WEB3_PROVIDER_URL=http://localhost:7545 must be set for local settings
|
||||||
|
|
||||||
#### IPFS
|
#### IPFS
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
|
import { inject } from '@ember/service';
|
||||||
|
import { empty } from '@ember/object/computed';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
kredits: inject(),
|
||||||
|
|
||||||
tagName: 'ul',
|
tagName: 'ul',
|
||||||
classNames: ['proposal-list'],
|
classNames: ['proposal-list'],
|
||||||
|
|
||||||
|
selectedProposals: [],
|
||||||
|
submitButtonDisabled: empty('selectedProposals'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
confirm() {
|
||||||
confirm(proposalId) {
|
this.confirmProposals(this.selectedProposals)
|
||||||
if (this.contractInteractionEnabled) {
|
.then(() => {
|
||||||
this.confirmProposal(proposalId);
|
this.selectedProposals = [];
|
||||||
} else {
|
});
|
||||||
window.alert('Only members can vote on proposals. Please ask someone to set you up.');
|
},
|
||||||
}
|
|
||||||
}
|
toggleSelect(proposalId, selected) {
|
||||||
|
if (selected) {
|
||||||
}
|
this.selectedProposals.removeObject(proposalId);
|
||||||
|
} else {
|
||||||
|
this.selectedProposals.addObject(proposalId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import Component from '@ember/component';
|
||||||
|
import tag from 'ember-awesome-macros/tag';
|
||||||
|
import { computed } from '@ember/object';
|
||||||
|
import { reads } from '@ember/object/computed';
|
||||||
|
import { inject } from '@ember/service';
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
kredits: inject(),
|
||||||
|
|
||||||
|
tagName: 'li',
|
||||||
|
classNames: ['proposal-list-item'],
|
||||||
|
|
||||||
|
attributeBindings: ['data-proposal-id', 'title'],
|
||||||
|
|
||||||
|
title: tag`(${'proposal.kind'}) ${'proposal.description'}`,
|
||||||
|
'data-proposal-id': reads('proposal.id'),
|
||||||
|
|
||||||
|
canBeVoted: computed('voterIds.[]', 'kredits.currentUser', function() {
|
||||||
|
let { isExecuted, voterIds } = this.proposal;
|
||||||
|
let { currentUser } = this.kredits;
|
||||||
|
voterIds = voterIds.map((id) => id.toString());
|
||||||
|
|
||||||
|
return currentUser.isCore && !isExecuted && !voterIds.includes(currentUser.id);
|
||||||
|
}),
|
||||||
|
|
||||||
|
selected: computed('selectedProposals.[]', function() {
|
||||||
|
return this.selectedProposals.includes(this.proposal.id);
|
||||||
|
})
|
||||||
|
});
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<span class="category {{proposal.kind}}">♥</span>
|
||||||
|
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
|
||||||
|
for <span class="recipient">{{proposal.contributor.name}}</span>
|
||||||
|
<span class="votes">({{proposal.votesCount}}/{{proposal.votesNeeded}} votes)</span>
|
||||||
|
|
||||||
|
{{#if canBeVoted}}
|
||||||
|
<button {{action toggleSelect proposal.id selected}} class="{{if selected 'selected' ''}}">+1</button>
|
||||||
|
{{/if}}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
{{#each proposals as |proposal|}}
|
{{#each proposals as |proposal|}}
|
||||||
<li data-proposal-id={{proposal.id}} title="({{proposal.kind}}) {{proposal.description}}">
|
{{proposal-list/item
|
||||||
<span class="category {{proposal.kind}}">♥</span>
|
proposal=proposal
|
||||||
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
|
selectedProposals=selectedProposals
|
||||||
for <span class="recipient">{{proposal.contributor.name}}</span>
|
toggleSelect=(action 'toggleSelect')
|
||||||
<span class="votes">({{proposal.votesCount}}/{{proposal.votesNeeded}} votes)</span>
|
}}
|
||||||
|
|
||||||
{{#unless proposal.isExecuted}}
|
|
||||||
<button {{action "confirm" proposal.id}}>+1</button>
|
|
||||||
{{/unless}}
|
|
||||||
</li>
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
|
{{#if confirmProposals}}
|
||||||
|
<p class="actions">
|
||||||
|
<input type="submit" disabled={{submitButtonDisabled}}
|
||||||
|
value="Confirm selected" {{action 'confirm'}}>
|
||||||
|
</p>
|
||||||
|
{{/if}}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
import { alias, filter, filterBy, sort } from '@ember/object/computed';
|
import { alias, filter, filterBy, sort } from '@ember/object/computed';
|
||||||
import { inject as injectService } from '@ember/service';
|
import { inject as injectService } from '@ember/service';
|
||||||
|
import RSVP from 'rsvp';
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
kredits: injectService(),
|
kredits: injectService(),
|
||||||
@@ -20,10 +21,17 @@ export default Controller.extend({
|
|||||||
proposalsOpenSorted: sort('proposalsOpen', 'proposalsSorting'),
|
proposalsOpenSorted: sort('proposalsOpen', 'proposalsSorting'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
confirmProposal(proposalId) {
|
confirmProposals(proposalIds) {
|
||||||
this.kredits.vote(proposalId).then(transaction => {
|
if (this.kredits.currentUser.isCore) {
|
||||||
|
return this.kredits.batchVote(proposalIds)
|
||||||
|
.then((transaction) => {
|
||||||
window.confirm('Vote submitted to Ethereum blockhain: '+transaction.hash);
|
window.confirm('Vote submitted to Ethereum blockhain: '+transaction.hash);
|
||||||
|
return transaction;
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
window.alert('Only members can vote on proposals. Please ask someone to set you up.');
|
||||||
|
return RSVP.reject();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
save(contributor) {
|
save(contributor) {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ const Router = EmberRouter.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Router.map(function() {
|
Router.map(function() {
|
||||||
this.route('spinner');
|
|
||||||
this.route('proposals', function() {
|
this.route('proposals', function() {
|
||||||
this.route('new');
|
this.route('new');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
import Route from '@ember/routing/route';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
});
|
|
||||||
+25
-16
@@ -4,7 +4,7 @@ import RSVP from 'rsvp';
|
|||||||
|
|
||||||
import Service from '@ember/service';
|
import Service from '@ember/service';
|
||||||
import { computed } from '@ember/object';
|
import { computed } from '@ember/object';
|
||||||
import { alias, notEmpty } from '@ember/object/computed';
|
import { notEmpty } from '@ember/object/computed';
|
||||||
import { isEmpty } from '@ember/utils';
|
import { isEmpty } from '@ember/utils';
|
||||||
|
|
||||||
import config from 'kredits-web/config/environment';
|
import config from 'kredits-web/config/environment';
|
||||||
@@ -16,8 +16,6 @@ export default Service.extend({
|
|||||||
|
|
||||||
currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded.
|
currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded.
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
currentUserIsContributor: notEmpty('currentUser'),
|
|
||||||
currentUserIsCore: alias('currentUser.isCore'),
|
|
||||||
hasAccounts: notEmpty('currentUserAccounts'),
|
hasAccounts: notEmpty('currentUserAccounts'),
|
||||||
accountNeedsUnlock: computed('currentUserAccounts', function() {
|
accountNeedsUnlock: computed('currentUserAccounts', function() {
|
||||||
return this.currentUserAccounts && isEmpty(this.currentUserAccounts);
|
return this.currentUserAccounts && isEmpty(this.currentUserAccounts);
|
||||||
@@ -29,7 +27,6 @@ export default Service.extend({
|
|||||||
return new RSVP.Promise((resolve) => {
|
return new RSVP.Promise((resolve) => {
|
||||||
let ethProvider;
|
let ethProvider;
|
||||||
let networkId;
|
let networkId;
|
||||||
let networkName;
|
|
||||||
if (typeof window.web3 !== 'undefined') {
|
if (typeof window.web3 !== 'undefined') {
|
||||||
console.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
console.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
||||||
networkId = parseInt(window.web3.version.network);
|
networkId = parseInt(window.web3.version.network);
|
||||||
@@ -39,30 +36,41 @@ export default Service.extend({
|
|||||||
);
|
);
|
||||||
ethProvider.listAccounts().then((accounts) => {
|
ethProvider.listAccounts().then((accounts) => {
|
||||||
this.set('currentUserAccounts', accounts);
|
this.set('currentUserAccounts', accounts);
|
||||||
resolve(ethProvider, ethProvider.getSigner());
|
const ethSigner = accounts.length === 0 ? null : ethProvider.getSigner();
|
||||||
|
resolve({
|
||||||
|
ethProvider,
|
||||||
|
ethSigner
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.debug('[kredits] Creating new instance from npm module class');
|
console.debug('[kredits] Creating new instance from npm module class');
|
||||||
networkId = parseInt(config.contractMetadata.networkId);
|
networkId = parseInt(config.contractMetadata.networkId);
|
||||||
networkName = config.contractMetadata.networkName;
|
console.debug(`[kredits] networkId=${networkId} providerURL: ${config.web3ProviderUrl}`);
|
||||||
console.log(networkName);
|
ethProvider = new ethers.providers.JsonRpcProvider(
|
||||||
ethProvider = new ethers.providers.InfuraProvider({ chainId: networkId, name: networkName });
|
config.web3ProviderUrl,
|
||||||
resolve(ethProvider, null);
|
{ chainId: networkId }
|
||||||
|
);
|
||||||
|
resolve({
|
||||||
|
ethProvider: ethProvider,
|
||||||
|
ethSigner: null
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return this.getEthProvider().then((ethProvider, ethSigner) => {
|
return this.getEthProvider().then((providerAndSigner) => {
|
||||||
let kredits = new Kredits(ethProvider, ethSigner);
|
|
||||||
|
let kredits = new Kredits(providerAndSigner.ethProvider, providerAndSigner.ethSigner, {
|
||||||
|
ipfsConfig: config.ipfs
|
||||||
|
});
|
||||||
return kredits
|
return kredits
|
||||||
.init()
|
.init()
|
||||||
.then((kredits) => {
|
.then((kredits) => {
|
||||||
this.set('kredits', kredits);
|
this.set('kredits', kredits);
|
||||||
|
|
||||||
if (this.currentUserAccounts && this.currentUserAccounts.length > 0) {
|
if (this.currentUserAccounts && this.currentUserAccounts.length > 0) {
|
||||||
this.getCurrentUser.then((contributorData) => {
|
this.getCurrentUser.then((contributorData) => {
|
||||||
this.set('currentUser', contributorData);
|
this.set('currentUser', Contributor.create(contributorData));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return kredits;
|
return kredits;
|
||||||
@@ -124,10 +132,11 @@ export default Service.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
vote(proposalId) {
|
batchVote(proposalIds) {
|
||||||
console.debug('[kredits] vote for', proposalId);
|
proposalIds = proposalIds.map((id) => parseInt(id))
|
||||||
|
console.debug('[kredits] vote for', proposalIds);
|
||||||
|
|
||||||
return this.kredits.Operator.functions.vote(proposalId)
|
return this.kredits.Operator.functions.batchVote(proposalIds)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
console.debug('[kredits] vote response', data);
|
console.debug('[kredits] vote response', data);
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
button, input[type=submit] {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid rgba(22, 21, 40, 1);
|
||||||
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
|
color: $primaryColor;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
cursor: pointer;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(22, 21, 40, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=submit] {
|
||||||
|
padding: 0.6rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text], select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 1rem;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
|
background-color: rgba(22, 21, 40, 0.3);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
&:focus, &.valid {
|
||||||
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
|
}
|
||||||
|
@include placeholder {
|
||||||
|
color: rgba(238, 238, 238, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, transparent 50%, gray 50%),
|
||||||
|
linear-gradient(135deg, gray 50%, transparent 50%);
|
||||||
|
background-position:
|
||||||
|
calc(100% - 1.5rem) calc(1rem + 0.5rem),
|
||||||
|
calc(100% - 1rem) calc(1rem + 0.5rem);
|
||||||
|
background-size:
|
||||||
|
0.5rem 0.5rem,
|
||||||
|
0.5rem 0.5rem;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
|
||||||
|
&:invalid {
|
||||||
|
color: rgba(238, 238, 238, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=checkbox] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.checkbox {
|
||||||
|
line-height: 3.2rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
&::before {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 0.8rem;
|
||||||
|
height: 3.2rem;
|
||||||
|
width: 3.2rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
background-color: rgba(22, 21, 40, 0.3);
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
content: '✓';
|
||||||
|
color: rgba(255,255,255,0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=checkbox]:checked + label.checkbox {
|
||||||
|
&::before {
|
||||||
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-15
@@ -84,21 +84,7 @@ section {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button, input[type=submit] {
|
@import "forms";
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid rgba(22, 21, 40, 1);
|
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
|
||||||
color: $primaryColor;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-weight: 500;
|
|
||||||
text-transform: uppercase;
|
|
||||||
cursor: pointer;
|
|
||||||
letter-spacing: 0.1em;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(22, 21, 40, 0.8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@import "components/loading-spinner";
|
@import "components/loading-spinner";
|
||||||
@import "components/contributor-list";
|
@import "components/contributor-list";
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
section#add-contributor, section#add-proposal {
|
section#add-contributor, section#add-proposal {
|
||||||
|
|
||||||
form {
|
form {
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
@@ -14,81 +13,6 @@ section#add-contributor, section#add-proposal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=text], select {
|
|
||||||
width: 100%;
|
|
||||||
padding: 1rem;
|
|
||||||
border: none;
|
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.2);
|
|
||||||
background-color: rgba(22, 21, 40, 0.3);
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
&:focus, &.valid {
|
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
|
||||||
}
|
|
||||||
@include placeholder {
|
|
||||||
color: rgba(238, 238, 238, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
-moz-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
border-radius: 0;
|
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
|
||||||
background-image:
|
|
||||||
linear-gradient(45deg, transparent 50%, gray 50%),
|
|
||||||
linear-gradient(135deg, gray 50%, transparent 50%);
|
|
||||||
background-position:
|
|
||||||
calc(100% - 1.5rem) calc(1rem + 0.5rem),
|
|
||||||
calc(100% - 1rem) calc(1rem + 0.5rem);
|
|
||||||
background-size:
|
|
||||||
0.5rem 0.5rem,
|
|
||||||
0.5rem 0.5rem;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
|
|
||||||
&:invalid {
|
|
||||||
color: rgba(238, 238, 238, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=submit] {
|
|
||||||
padding: 0.6rem 2rem;
|
|
||||||
&:disabled {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=checkbox] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
label.checkbox {
|
|
||||||
line-height: 3.2rem;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
&::before {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 0.8rem;
|
|
||||||
height: 3.2rem;
|
|
||||||
width: 3.2rem;
|
|
||||||
font-size: 2rem;
|
|
||||||
background-color: rgba(22, 21, 40, 0.3);
|
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.2);
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
content: '✓';
|
|
||||||
color: rgba(255,255,255,0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=checkbox]:checked + label.checkbox {
|
|
||||||
&::before {
|
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ ul.proposal-list {
|
|||||||
height: 2rem;
|
height: 2rem;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
padding: 0 0.6rem;
|
padding: 0 0.6rem;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background-color: rgba(224,104,251, 0.6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<section id="user-account">
|
<section id="user-account">
|
||||||
{{#if kredits.currentUser }}
|
{{#if kredits.currentUser }}
|
||||||
{{ kredits.currentUser.name }}
|
{{ kredits.currentUser.name }}
|
||||||
{{#if kredits.currentUserIsCore }}
|
{{#if kredits.currentUser.isCore }}
|
||||||
(core)
|
(core)
|
||||||
{{/if}}
|
{{/if}}
|
||||||
Account: {{kredits.currentUser.account}}
|
Account: {{kredits.currentUser.account}}
|
||||||
@@ -32,8 +32,7 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
{{!-- TODO: We need a better naming for kredits.hasAccounts --}}
|
{{!-- TODO: We need a better naming for kredits.hasAccounts --}}
|
||||||
{{proposal-list proposals=proposalsOpenSorted
|
{{proposal-list proposals=proposalsOpenSorted
|
||||||
confirmProposal=(action "confirmProposal")
|
confirmProposals=(action 'confirmProposals')}}
|
||||||
contractInteractionEnabled=kredits.hasAccounts}}
|
|
||||||
|
|
||||||
{{!-- TODO: We need a better naming --}}
|
{{!-- TODO: We need a better naming --}}
|
||||||
{{#if kredits.hasAccounts}}
|
{{#if kredits.hasAccounts}}
|
||||||
@@ -50,8 +49,7 @@
|
|||||||
<h2>Closed Proposals</h2>
|
<h2>Closed Proposals</h2>
|
||||||
</header>
|
</header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{{proposal-list proposals=proposalsClosedSorted
|
{{proposal-list proposals=proposalsClosedSorted}}
|
||||||
confirmProposal=(action "confirmProposal")}}
|
|
||||||
|
|
||||||
{{!-- TODO: We need a better naming --}}
|
{{!-- TODO: We need a better naming --}}
|
||||||
{{#if kredits.hasAccounts}}
|
{{#if kredits.hasAccounts}}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{{loading-spinner}}
|
|
||||||
@@ -35,9 +35,9 @@ module.exports = function(environment) {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
contractMetadata: { networkId: '42', networkName: 'kovan' },
|
contractMetadata: { networkId: '42' },
|
||||||
|
|
||||||
web3ProviderUrl: 'https://parity.kosmos.org:8545',
|
web3ProviderUrl: 'https://kovan.infura.io/keUVk6OMaAvpmRF3m57n',
|
||||||
|
|
||||||
ipfs: {
|
ipfs: {
|
||||||
host: 'ipfs.kosmos.org',
|
host: 'ipfs.kosmos.org',
|
||||||
@@ -52,8 +52,8 @@ module.exports = function(environment) {
|
|||||||
// ENV.APP.LOG_TRANSITIONS = true;
|
// ENV.APP.LOG_TRANSITIONS = true;
|
||||||
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
|
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
|
||||||
// ENV.APP.LOG_VIEW_LOOKUPS = true;
|
// ENV.APP.LOG_VIEW_LOOKUPS = true;
|
||||||
ENV.contractMetadata['networkId'] = '100';
|
ENV.contractMetadata['networkId'] = '42';
|
||||||
ENV.web3ProviderUrl = 'http://localhost:7545';
|
ENV.web3ProviderUrl = 'https://kovan.infura.io/keUVk6OMaAvpmRF3m57n';
|
||||||
|
|
||||||
ENV.ipfs = {
|
ENV.ipfs = {
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
@@ -81,9 +81,6 @@ module.exports = function(environment) {
|
|||||||
if (process.env.NETWORK_ID) {
|
if (process.env.NETWORK_ID) {
|
||||||
ENV.contractMetadata['networkId'] = process.env.NETWORK_ID;
|
ENV.contractMetadata['networkId'] = process.env.NETWORK_ID;
|
||||||
}
|
}
|
||||||
if (process.env.NETWORK_NAME) {
|
|
||||||
ENV.contractMetadata['networkName'] = process.env.NETWORK_NAME;
|
|
||||||
}
|
|
||||||
if (process.env.WEB3_PROVIDER_URL) {
|
if (process.env.WEB3_PROVIDER_URL) {
|
||||||
ENV.web3ProviderUrl = process.env.WEB3_PROVIDER_URL;
|
ENV.web3ProviderUrl = process.env.WEB3_PROVIDER_URL;
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+4734
-5316
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -13,7 +13,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"lint:js": "eslint ./*.js app config lib server tests",
|
"lint:js": "eslint ./*.js app config lib server tests",
|
||||||
"start": "ember serve",
|
"start": "ember serve",
|
||||||
"kovan": "NETWORK_ID=42 ember serve",
|
"start:local": "NETWORK_ID=100 WEB3_PROVIDER_URL=http://localhost:7545 ember s",
|
||||||
"test": "ember test",
|
"test": "ember test",
|
||||||
"build": "ember build",
|
"build": "ember build",
|
||||||
"build-prod": "ember build --environment production",
|
"build-prod": "ember build --environment production",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"ember-ajax": "^3.0.0",
|
"ember-ajax": "^3.0.0",
|
||||||
"ember-awesome-macros": "0.41.0",
|
"ember-awesome-macros": "0.41.0",
|
||||||
"ember-browserify": "^1.1.13",
|
"ember-browserify": "^1.1.13",
|
||||||
"ember-cli": "~3.1.2",
|
"ember-cli": "^3.1.4",
|
||||||
"ember-cli-app-version": "^3.0.0",
|
"ember-cli-app-version": "^3.0.0",
|
||||||
"ember-cli-babel": "^6.6.0",
|
"ember-cli-babel": "^6.6.0",
|
||||||
"ember-cli-dependency-checker": "^2.0.0",
|
"ember-cli-dependency-checker": "^2.0.0",
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
"ember-cli-sass": "^7.2.0",
|
"ember-cli-sass": "^7.2.0",
|
||||||
"ember-cli-sri": "^2.1.0",
|
"ember-cli-sri": "^2.1.0",
|
||||||
"ember-cli-uglify": "^2.0.0",
|
"ember-cli-uglify": "^2.0.0",
|
||||||
"ember-cli-update": "^0.21.2",
|
"ember-cli-update": "^0.21.4",
|
||||||
"ember-export-application-global": "^2.0.0",
|
"ember-export-application-global": "^2.0.0",
|
||||||
"ember-load-initializers": "^1.0.0",
|
"ember-load-initializers": "^1.0.0",
|
||||||
"ember-macro-helpers": "0.17.0",
|
"ember-macro-helpers": "0.17.0",
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
"eslint-plugin-ember": "^5.0.0",
|
"eslint-plugin-ember": "^5.0.0",
|
||||||
"ethers": "3.0.15",
|
"ethers": "3.0.15",
|
||||||
"kosmos-schemas": "^1.1.2",
|
"kosmos-schemas": "^1.1.2",
|
||||||
"kredits-contracts": "github:67P/truffle-kredits",
|
"kredits-contracts": "^3.0.2",
|
||||||
"loader.js": "^4.2.3",
|
"loader.js": "^4.2.3",
|
||||||
"tv4": "^1.3.0"
|
"tv4": "^1.3.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import { module, test } from 'qunit';
|
|
||||||
import { setupTest } from 'ember-qunit';
|
|
||||||
|
|
||||||
module('Unit | Route | spinner', function(hooks) {
|
|
||||||
setupTest(hooks);
|
|
||||||
|
|
||||||
test('it exists', function(assert) {
|
|
||||||
let route = this.owner.lookup('route:spinner');
|
|
||||||
assert.ok(route);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user