Skip to content

Commit

Permalink
Merge branch 'newstyle' into 1115-addressbook-aragonDS
Browse files Browse the repository at this point in the history
* newstyle: (47 commits)
  Revert Rewards & Projects to previous aragonUI
  Dot Voting: fix issues found during QA
  Dot Voting/CastVote: fix prop type
  Revert "[DEV] rm pre-commit lint"
  Dot Voting: mv totalSupport calc to VotingResults
  Dot Voting/VoteDetails: mv Participation
  Dot Voting/CastVote: rm tokenData; keep userBalance
  Dot Voting: define tokenContract in CastVote
  Dot Voting: mv CastVote to own file
  Dot Voting/VoteDetails: mv VoteEnact & VotingResults
  Add a minimal EMPTY_ROLE to Discussions - This is needed to be considered an actual Aragon app by the Kernel - Reference: https://hack.aragon.org/docs/cli-dao-commands#dao-install
  Remove partial ACL guards on discussions:
  Discussions: fix typos in README examples
  Dot voting demo fixes (#1176)
  Dot Voting/VoteDetails: mv DescriptionAndCreator
  Discussions (#1050)
  Dot Voting/VoteDetails: mv Title to own file
  Dot Voting/VoteDetail: mv Status to new file
  Dot Voting/VoteDetails: mv AppBadge to new file
  [DEV] rm pre-commit lint
  ...
  • Loading branch information
chadoh committed Aug 27, 2019
2 parents 58b890b + b640cf7 commit c0be9a4
Show file tree
Hide file tree
Showing 106 changed files with 3,578 additions and 1,763 deletions.
51 changes: 13 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
# That Planning Suite
# Open Enterprise
*Note: Open Enterprise is the new name of That Planning Suite. We still need to update the Github repo URL.*

[![Build Status](https://img.shields.io/travis/AutarkLabs/planning-suite.svg?style=flat-square)](https://travis-ci.org/AutarkLabs/planning-suite) [![Coverage Status](https://img.shields.io/coveralls/github/AutarkLabs/planning-suite.svg?style=flat-square)](https://coveralls.io/github/AutarkLabs/planning-suite)

<!-- markdownlint-disable MD033 -->
<p align="center">
<a href="#development-setup">Development Setup</a> •
<a href="#background">Background</a> •
<a href="#details">Details</a> •
<a href="#design-concepts">Design Concepts</a> •
<a href="#app-overview">App Overview</a> •
<a href="#contact">Contact</a>
</p>
<!-- markdownlint-enable MD033 -->

Open Enterprise is a collection of Aragon apps that enable organizations to curate issues, collectively budget, and design custom reward and bounty programs. If you are interested in viewing app demos or want to install them to your Rinkeby organizations, learn more here:
https://www.autark.xyz/apps

**Release status:** The apps are currently on Rinkeby and undergoing a security audit and UX enhancements. The apps will be released to mainnet in Q4 2019.


## Development Setup

Node.js LTS or greater required.
Expand Down Expand Up @@ -43,13 +48,9 @@ $ npm run start:dot

**Detailed information in the [DEVELOPMENT_NOTES.md](/docs/DEVELOPMENT_NOTES.md) document.**

## Background

The proposal for an Aragon [Planning Suite](https://github.com/aragon/nest/pull/24) was developed by members of [Autark](https://autark.xyz), and received funding via [Aragon's Nest program](https://blog.aragon.one/introducing-aragon-nest-1aa8c91c0566): an example of decentralization at it's finest. We are developing this app as a collaborative unit because it is a crucial building block for any organization that aims to coordinate work and streamline management duties, without traditional managers. These apps will work with MiniMe ERC-20 tokens or Aragon DAOs.

## The Suite
## App Overview

The Planning Suite is a collection of five Aragon Apps that supports the following:
Open Enterprise is a collection of five Aragon Apps that supports the following:

- **Allocations:** The Allocations app is used to propose a financial allocation meant to be distributed to multiple parties. Allocation proposals are forwarded to the Dot Voting app. The percentage of the allocation amount distributed to each party is determined based on the results of the Dot Vote.
- **Address Book:** Maintain a list of Ethereum addresses mapped to human-readable names. The Address Book will enable a more user-friendly way to access and review common addresses a DAO uses for Allocations and Dot Voting.
Expand All @@ -59,39 +60,13 @@ The Planning Suite is a collection of five Aragon Apps that supports the followi
- **Dot Voting:** Dot Voting is used to cast votes for Allocation or Issue Curation proposals. Members can vote on how to distribute an allocation across distinct entities or prioritize a list of Github issues by specifying a percentage of votes per option.
- **Rewards:** Distributes payments to token holders based on the number of tokens one has earned in a specific cycle of time (one-time reward) or based on the total tokens one holds (dividend).

### Please review the [White Paper](http://goo.gl/eXAybm) for full details

## Design Concepts

These are some initial concepts. We expect to refine them and gather community feedback once approved.

### Projects App

![ara_planning1](docs/screenshots/Projects_app.jpg)

#### Allocations App

![ara_planning2](docs/screenshots/Allocations_app.jpg)

#### Rewards App

![ara_planning3](docs/screenshots/Rewards_app.jpg)

#### Issue Curation using Dot Voting

![ara_planning4](docs/screenshots/Dot_vote_issue.jpg)

### Flow Diagram

#### Financial Planning Toolkit
### [Review more details](https://www.autark.xyz/apps)

Hypothetical flow diagram. The components should be "plug and play" to design a rewards system tailored to an organization's unique needs.
![image](https://user-images.githubusercontent.com/2584493/36970345-91ff7ee6-2068-11e8-94a6-968f055b7ebc.png)

## Contact

We can be found in the [`autark.community` keybase channel](https://keybase.io/team/autark.community). If you have any questions or want to get involved in our development please drop in.

## Special Thanks

Special thanks go to the Aragon team for much of the work this project is based on, as well as for allocating us this grant to build the tools we need to DAOify open source development!
Special thanks to the Aragon Network for funding our work with three grants to date ([Nest](https://blog.aragon.one/introducing-aragon-nest-1aa8c91c0566), [AGP-19](https://github.com/aragon/AGPs/blob/master/AGPs/AGP-19.md), and [AGP-73](https://github.com/aragon/AGPs/blob/master/AGPs/AGP-73.md)).
22 changes: 12 additions & 10 deletions apps/address-book/app/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,33 @@ import NewEntity from '../Panel/NewEntity'
const ASSETS_URL = './aragon-ui'

const App = () => {
const [ panelVisible,setPanelVisible ] = useState(false)
const [ panelVisible, setPanelVisible ] = useState(false)
const { api, appState = {} } = useAragonApi()

const { entries = [] } = appState

const createEntity = ({ address, name, type }) => {
api.addEntry(address, name, type)
api.addEntry(address, name, type).toPromise()
closePanel()
}

const removeEntity = (address) => {
api.removeEntry(address)
const removeEntity = address => {
api.removeEntry(address).toPromise()
}

const newEntity = () => {
setPanelVisible(true)
}

const closePanel = () => {
setPanelVisible(false)
}

const handleResolveLocalIdentity = (address) => api.resolveAddressIdentity(address).toPromise()

const handleShowLocalIdentityModal = (address) => api.requestAddressIdentityModification(address).toPromise()
const handleResolveLocalIdentity = address =>
api.resolveAddressIdentity(address).toPromise()

const handleShowLocalIdentityModal = address =>
api.requestAddressIdentityModification(address).toPromise()

return (
<Main assetsUrl={ASSETS_URL}>
Expand Down
8 changes: 4 additions & 4 deletions apps/address-book/contracts/misc/Migrations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ pragma solidity ^0.4.24;
contract Migrations {
address public owner;
uint public lastCompletedMigration;

modifier restricted() {
if (msg.sender == owner) _; // solium-disable-line lbrace
}

constructor() public {
owner = msg.sender;
}

function setCompleted(uint completed) public restricted {
lastCompletedMigration = completed;
}

function upgrade(address newAddress) public restricted {
Migrations upgraded = Migrations(newAddress);
upgraded.setCompleted(lastCompletedMigration);
Expand Down
2 changes: 1 addition & 1 deletion apps/address-book/contracts/test/TestImports.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import "@tps/test-helpers/contracts/lib/bounties/StandardBounties.sol";


contract TestImports {
constructor() public {
constructor() public { // solium-disable-line no-empty-blocks
// to avoid lint error
}
}
9 changes: 5 additions & 4 deletions apps/address-book/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"test": "TRUFFLE_TEST=true npm run ganache-cli:test"
},
"dependencies": {
"@aragon/api": "1.1.0",
"@aragon/api-react": "1.0.0-beta.2",
"@aragon/api": "2.0.0-beta.5",
"@aragon/api-react": "2.0.0-beta.4",
"@aragon/ui": "1.0.0-alpha.9",
"@tps/ui": "^0.0.1",
"prop-types": "^15.7.2",
Expand All @@ -40,18 +40,19 @@
"web3-utils": "^1.0.0"
},
"devDependencies": {
"@tps/test-helpers": "^0.0.1",
"@babel/core": "^7.4.5",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"@tps/test-helpers": "^0.0.1",
"babel-eslint": "^10.0.1",
"babel-plugin-styled-components": "^1.10.0",
"eslint": "^5.16.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-config-prettier": "^6.0.0",
"eslint-config-standard": "^12.0.0",
"eslint-config-standard-react": "^7.0.2",
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-promise": "^4.1.1",
"eslint-plugin-react": "^7.13.0",
Expand Down
54 changes: 22 additions & 32 deletions apps/allocations/app/components/App/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { useState } from 'react'

import { useAragonApi } from '@aragon/api-react'
import { AppBar, AppView, Main, SidePanel, Button } from '@aragon/ui'
import { Button, Header, IconPlus, Main, SidePanel } from '@aragon/ui'

import { AppTitle } from '../../../../../shared/ui'
import { IdentityProvider } from '../../../../../shared/identity'
import { NewAccount, NewAllocation } from '../Panel'
import { Accounts, Payouts } from '.'
Expand All @@ -14,11 +13,11 @@ const nameSorter = (a, b) => a.data.name.toUpperCase() > b.data.name.toUpperCase

const App = () => {
const [ panel, setPanel ] = useState(null)
const { api, appState, displayMenuButton = false } = useAragonApi()
const { api, appState } = useAragonApi()
const { accounts = [], balances = [], entries = [], payouts = [] } = appState

const onCreateAccount = ({ description }) => {
api.newAccount(description)
api.newAccount(description).toPromise()
closePanel()
}

Expand All @@ -37,12 +36,12 @@ const App = () => {
period,
balance,
tokenAddress
)
).toPromise()
closePanel()
}

const onExecutePayout = (accountId, payoutId) => {
api.runPayout(accountId, payoutId)
api.runPayout(accountId, payoutId).toPromise()
}

const onNewAccount = () => {
Expand Down Expand Up @@ -92,35 +91,26 @@ const App = () => {
return (
// TODO: Profile App with React.StrictMode, perf and why-did-you-update, apply memoization
<Main assetsUrl={ASSETS_URL}>
<Header
primary="Allocations"
secondary={
<Button mode="strong" icon={<IconPlus />} onClick={onNewAccount} label="New Account" />
}
/>

<IdentityProvider
onResolve={handleResolveLocalIdentity}
onShowLocalIdentityModal={handleShowLocalIdentityModal}>
<AppView
appBar={
<AppBar
endContent={
<Button mode="strong" onClick={onNewAccount}>New Account</Button>
}
>
<AppTitle
title="Allocations"
displayMenuButton={displayMenuButton}
css="padding-left: 30px"
/>
</AppBar>
}
>
<Accounts
accounts={accounts}
onNewAccount={onNewAccount}
onNewAllocation={onNewAllocation}
/>
<Payouts
payouts={payouts}
executePayout={onExecutePayout}
tokens={balances}
/>
</AppView>
<Accounts
accounts={accounts}
onNewAccount={onNewAccount}
onNewAllocation={onNewAllocation}
/>
<Payouts
payouts={payouts}
executePayout={onExecutePayout}
tokens={balances}
/>

<SidePanel
title={(panel && panel.data.heading) || ''}
Expand Down
14 changes: 6 additions & 8 deletions apps/allocations/app/components/Form/Input/InputDropDown.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import { DropDown, TextInput, theme } from '@aragon/ui'
import styled from 'styled-components'

// TODO: Better naming
const InputDropDown = ({ textInput, dropDown, wide }) => {
return (
<StyledInputDropDown wide={wide}>
<TextInput {...textInput} />
<DropDown {...dropDown} />
</StyledInputDropDown>
)
}
const InputDropDown = ({ textInput, dropDown, wide }) => (
<StyledInputDropDown wide={wide}>
<TextInput {...textInput} />
<DropDown {...dropDown} />
</StyledInputDropDown>
)

InputDropDown.propTypes = {
textInput: PropTypes.object,
Expand Down
6 changes: 3 additions & 3 deletions apps/allocations/app/components/Panel/NewAllocation.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class NewAllocation extends React.Component {

// TODO: Manage dropdown to return a name and value as the rest of inputs

changePayoutToken = (index, items) => {
changePayoutToken = items => index => {
this.setState({
allocationError: false,
payoutTokenIndex: index,
Expand Down Expand Up @@ -192,8 +192,8 @@ class NewAllocation extends React.Component {
const amountDropDown = {
name: 'token',
items: availableTokens,
active: state.payoutTokenIndex,
onChange: this.changePayoutToken,
selected: state.payoutTokenIndex,
onChange: this.changePayoutToken(availableTokens),
}

const amountWarningMessages = (
Expand Down
7 changes: 2 additions & 5 deletions apps/allocations/app/store/events.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { initializeTokens, vaultLoadBalance } from './token'
import { vaultLoadBalance } from './token'
import { onFundedAccount, onNewAccount, onPayoutExecuted } from './account'
import { onEntryAdded, onEntryRemoved } from './entry'
import { INITIALIZATION_TRIGGER } from './'
import { addressesEqual } from '../utils/web3-utils'

export const handleEvent = async (state, event, settings) => {
Expand All @@ -11,9 +10,7 @@ export const handleEvent = async (state, event, settings) => {

let nextAccounts, nextBoth
let nextState = { ...state }
if (eventName === INITIALIZATION_TRIGGER) {
nextState = await initializeTokens(nextState, settings)
} else if (addressesEqual(eventAddress, vault.address)) {
if (addressesEqual(eventAddress, vault.address)) {
// Vault event
nextState = await vaultLoadBalance(nextState, event, settings)
} else {
Expand Down
1 change: 0 additions & 1 deletion apps/allocations/app/store/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { app } from './app'
export { handleEvent } from './events'
export { initialize } from './init'
export const INITIALIZATION_TRIGGER = Symbol('INITIALIZATION_TRIGGER')
28 changes: 18 additions & 10 deletions apps/allocations/app/store/init.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import AddressBookJSON from '../../../shared/json-abis/address-book.json'
import { INITIALIZATION_TRIGGER, app, handleEvent } from './'
import { of } from 'rxjs'
import { app, handleEvent } from './'
import { first } from 'rxjs/operators'

import { initializeTokens } from './token'
import vaultBalanceAbi from '../../../shared/json-abis/vault/vault-balance.json'
import vaultGetInitializationBlockAbi from '../../../shared/json-abis/vault/vault-getinitializationblock.json'
import vaultEventAbi from '../../../shared/json-abis/vault/vault-events.json'
Expand Down Expand Up @@ -73,13 +73,21 @@ const createStore = async settings => {
// always return the state even unmodified
return nextState
},
[
of({ event: INITIALIZATION_TRIGGER }),
// handle address book events
// TODO: Start from AddrBook initialization block as Vault
settings.addressBook.contract.events(),
// handle vault events
settings.vault.contract.events(vaultInitializationBlock),
]
{
externals: [
{ contract: settings.addressBook.contract },
{
contract: settings.vault.contract,
initializationBlock: vaultInitializationBlock
},

],
init: initState(settings)
}
)
}

const initState = (settings) => async (cachedState) => {
const nextState = await initializeTokens(cachedState, settings)
return nextState
}

0 comments on commit c0be9a4

Please sign in to comment.