{pluginName(proposalState.plugin.entity.coreState, proposalState.plugin.entity.coreState.address)}
@@ -225,7 +233,7 @@ class ProposalDetailsPage extends React.Component
{
{
{
diff --git a/src/components/Proposal/ProposalSummary/ProposalSummary.tsx b/src/components/Proposal/ProposalSummary/ProposalSummary.tsx
index f89f00c30..1a1eaf056 100644
--- a/src/components/Proposal/ProposalSummary/ProposalSummary.tsx
+++ b/src/components/Proposal/ProposalSummary/ProposalSummary.tsx
@@ -1,4 +1,14 @@
-import { IDAOState, AnyProposal, IContributionRewardProposalState, IGenericPluginProposalState, IPluginRegistrarProposalState, IProposalState, Proposal, IPluginManagerProposalState } from "@daostack/arc.js";
+import {
+ IDAOState,
+ AnyProposal,
+ IContributionRewardProposalState,
+ IGenericPluginProposalState,
+ IPluginRegistrarProposalState,
+ IProposalState,
+ Proposal,
+ IPluginManagerProposalState,
+ IFundingRequestProposalState,
+ IJoinProposalState } from "@daostack/arc.js";
import classNames from "classnames";
import { GenericPluginRegistry } from "genericPluginRegistry";
import * as React from "react";
@@ -9,6 +19,8 @@ import ProposalSummaryKnownGenericPlugin from "./ProposalSummaryKnownGenericPlug
import ProposalSummaryPluginRegistrar from "./ProposalSummaryPluginRegistrar";
import ProposalSummaryPluginManager from "./ProposalSummaryPluginManager";
import ProposalSummaryUnknownGenericPlugin from "./ProposalSummaryUnknownGenericPlugin";
+import ProposalSummaryJoin from "./ProposalSummaryJoin";
+import ProposalSummaryFundingRequest from "./ProposalSummaryFundingRequest";
import { getArc } from "arc";
interface IProps {
@@ -64,6 +76,12 @@ export default class ProposalSummary extends React.Component {
} else {
return ;
}
+ } else if (proposal.coreState.name === "Join"){
+ const state = proposal.coreState as IJoinProposalState;
+ return ;
+ } else if (proposal.coreState.name === "FundingRequest") {
+ const state = proposal.coreState as IFundingRequestProposalState;
+ return ;
} else {
return Unknown proposal type
;
}
diff --git a/src/components/Proposal/ProposalSummary/ProposalSummaryFundingRequest.tsx b/src/components/Proposal/ProposalSummary/ProposalSummaryFundingRequest.tsx
new file mode 100644
index 000000000..9ca001144
--- /dev/null
+++ b/src/components/Proposal/ProposalSummary/ProposalSummaryFundingRequest.tsx
@@ -0,0 +1,73 @@
+import { IDAOState, IFundingRequestProposalState } from "@daostack/arc.js";
+import classNames from "classnames";
+import { getNetworkName, linkToEtherScan, fromWei } from "lib/util";
+import * as React from "react";
+import { IProfileState } from "reducers/profilesReducer";
+import i18next from "i18next";
+import * as css from "./ProposalSummary.scss";
+
+interface IExternalProps {
+ beneficiaryProfile?: IProfileState;
+ detailView?: boolean;
+ daoState: IDAOState;
+ proposalState: IFundingRequestProposalState;
+ transactionModal?: boolean;
+}
+
+interface IState {
+ network: string;
+}
+
+type IProps = IExternalProps;
+
+export default class ProposalSummary extends React.Component {
+
+ constructor(props: IProps) {
+ super(props);
+ this.state = {
+ network: "",
+ };
+
+ }
+
+ public async componentDidMount(): Promise {
+ this.setState({ network: (await getNetworkName()).toLowerCase() });
+ }
+
+ public render(): RenderOutput {
+ const { proposalState, detailView, transactionModal } = this.props;
+ const proposalSummaryClass = classNames({
+ [css.detailView]: detailView,
+ [css.transactionModal]: transactionModal,
+ [css.proposalSummary]: true,
+ [css.withDetails]: true,
+ });
+
+ return (
+
+
+
+ {proposalState.name}
+
+ {detailView &&
+
+
+
+
+ {i18next.t("Address")}
+
+
+
+ |
+ {proposalState.beneficiary} |
+
+ {i18next.t("Amount")} | {fromWei(proposalState.amount)} |
+ {i18next.t("Amount Redeemed")}: | {fromWei(proposalState.amountRedeemed)} |
+
+
+ }
+
+
+ );
+ }
+}
diff --git a/src/components/Proposal/ProposalSummary/ProposalSummaryJoin.tsx b/src/components/Proposal/ProposalSummary/ProposalSummaryJoin.tsx
new file mode 100644
index 000000000..8480c1b78
--- /dev/null
+++ b/src/components/Proposal/ProposalSummary/ProposalSummaryJoin.tsx
@@ -0,0 +1,74 @@
+import { IDAOState, IJoinProposalState } from "@daostack/arc.js";
+import classNames from "classnames";
+import { getNetworkName, linkToEtherScan, fromWei } from "lib/util";
+import * as React from "react";
+import { IProfileState } from "reducers/profilesReducer";
+import i18next from "i18next";
+import * as css from "./ProposalSummary.scss";
+
+interface IExternalProps {
+ beneficiaryProfile?: IProfileState;
+ detailView?: boolean;
+ daoState: IDAOState;
+ proposalState: IJoinProposalState;
+ transactionModal?: boolean;
+}
+
+interface IState {
+ network: string;
+}
+
+type IProps = IExternalProps;
+
+export default class ProposalSummary extends React.Component {
+
+ constructor(props: IProps) {
+ super(props);
+ this.state = {
+ network: "",
+ };
+
+ }
+
+ public async componentDidMount(): Promise {
+ this.setState({ network: (await getNetworkName()).toLowerCase() });
+ }
+
+ public render(): RenderOutput {
+ const { proposalState, detailView, transactionModal } = this.props;
+ const proposalSummaryClass = classNames({
+ [css.detailView]: detailView,
+ [css.transactionModal]: transactionModal,
+ [css.proposalSummary]: true,
+ [css.withDetails]: true,
+ });
+
+ return (
+
+
+
+ {proposalState.name}
+
+ {detailView &&
+
+
+
+
+ {i18next.t("Address")}
+
+
+
+ |
+ {proposalState.proposedMember} |
+
+ {i18next.t("Funding")} | {fromWei(proposalState.funding)} |
+ {i18next.t("Reputation Minted")} | {fromWei(proposalState.reputationMinted)} |
+ {i18next.t("Minimum DAO bounty")} | {fromWei(proposalState.genesisProtocolParams.minimumDaoBounty)} |
+
+
+ }
+
+
+ );
+ }
+}
diff --git a/src/components/Proposal/Voting/VoteBreakdown.scss b/src/components/Proposal/Voting/VoteBreakdown.scss
index 7935bd4c0..75634e823 100644
--- a/src/components/Proposal/Voting/VoteBreakdown.scss
+++ b/src/components/Proposal/Voting/VoteBreakdown.scss
@@ -55,7 +55,7 @@
.voteBreakdown {
position: relative;
- width: 120px;
+ width: 130px;
text-align: left;
margin-left: 5px;
display: block;
diff --git a/src/components/Proposal/Voting/VoteButtons.scss b/src/components/Proposal/Voting/VoteButtons.scss
index b00821e5b..af691da81 100644
--- a/src/components/Proposal/Voting/VoteButtons.scss
+++ b/src/components/Proposal/Voting/VoteButtons.scss
@@ -199,7 +199,6 @@ button.disabled {
border: 0;
margin: 0 1px;
display: inline-block;
- width: 75px;
padding: 0 5px;
outline: none;
diff --git a/src/genericPluginRegistry/plugins/NFTManager.json b/src/genericPluginRegistry/plugins/NFTManager.json
index 92e2b2e32..82bd7cab8 100644
--- a/src/genericPluginRegistry/plugins/NFTManager.json
+++ b/src/genericPluginRegistry/plugins/NFTManager.json
@@ -30,7 +30,9 @@
{
"label": "Data",
"name": "data",
- "placeholder": ""
+ "placeholder": "Arbitrary data to transfer (0x0 means no data)",
+ "defaultValue": "0x0",
+ "optional": true
}
],
"abi": {
diff --git a/src/index.tsx b/src/index.tsx
index e81137f5e..5953a86f0 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,6 +1,3 @@
-import { library } from "@fortawesome/fontawesome-svg-core";
-import { faGithub } from "@fortawesome/free-brands-svg-icons/faGithub";
-import { faTwitter } from "@fortawesome/free-brands-svg-icons/faTwitter";
import { init as sentryInit } from "@sentry/browser";
import * as Mixpanel from "mixpanel-browser";
import * as React from "react";
@@ -13,8 +10,6 @@ import { App } from "./App";
import "./assets/styles/global.scss";
async function renderApp() {
- // Add icons we want to use from FontAwesome
- library.add(faGithub, faTwitter);
if (process.env.NODE_ENV === "production") {
sentryInit({
diff --git a/src/lib/pluginUtils.ts b/src/lib/pluginUtils.ts
index 17812e738..d94ce2856 100644
--- a/src/lib/pluginUtils.ts
+++ b/src/lib/pluginUtils.ts
@@ -42,6 +42,8 @@ export const REQUIRED_PLUGIN_PERMISSIONS: any = {
"UpgradeScheme": PluginPermissions.IsRegistered | PluginPermissions.CanRegisterPlugins | PluginPermissions.CanUpgradeController,
"VestingScheme": PluginPermissions.IsRegistered,
"VoteInOrganizationScheme": PluginPermissions.IsRegistered | PluginPermissions.CanCallDelegateCall,
+ "Join": PluginPermissions.IsRegistered,
+ "FundingRequest": PluginPermissions.IsRegistered,
};
/** plugins that we know how to interpret */
@@ -53,6 +55,8 @@ export const PLUGIN_NAMES = {
SchemeFactory: "Plugin Manager",
Competition: "Competition",
ContributionRewardExt: "Contribution Reward Ext",
+ Join: "Join",
+ FundingRequest: "Funding Request",
};
/**
diff --git a/src/lib/util.ts b/src/lib/util.ts
index 7506f363f..01f5a7205 100644
--- a/src/lib/util.ts
+++ b/src/lib/util.ts
@@ -657,3 +657,11 @@ export function safeMoment(dateSpecifier: moment.Moment | Date | number | string
}
}
+/**
+ * Checks whether an element is an empty object
+ * @param element
+ * @returns {boolean}
+ */
+export const isEmptyObject = (element: unknown): boolean => {
+ return Object.keys(element).length === 0 && element.constructor === Object;
+};
diff --git a/src/subgraph_endpoints.json b/src/subgraph_endpoints.json
index 10e84d74b..2c8170238 100644
--- a/src/subgraph_endpoints.json
+++ b/src/subgraph_endpoints.json
@@ -1,12 +1,12 @@
{
- "http_main": "https://api.thegraph.com/subgraphs/name/daostack/TODO",
- "ws_main": "wss://api.thegraph.com/subgraphs/name/daostack/TODO",
- "http_rinkeby": "https://api.thegraph.com/subgraphs/name/daostack/v8_11_exp_rinkeby",
- "ws_rinkeby": "wss://api.thegraph.com/subgraphs/name/daostack/v8_11_exp_rinkeby",
- "http_kovan": "https://api.thegraph.com/subgraphs/name/daostack/v8_11_exp_kovan",
- "ws_kovan": "wss://api.thegraph.com/subgraphs/name/daostack/v8_11_exp_kovan",
- "http_xdai": "https://api.thegraph.com/subgraphs/name/daostack/v8_11_exp_xdai",
- "ws_xdai": "wss://api.thegraph.com/subgraphs/name/daostack/v8_11_exp_xdai",
+ "http_main": "https://api.thegraph.com/subgraphs/name/daostack/v8_12_exp",
+ "ws_main": "wss://api.thegraph.com/subgraphs/name/daostack/v8_12_exp",
+ "http_rinkeby": "https://api.thegraph.com/subgraphs/name/daostack/v8_12_exp_rinkeby",
+ "ws_rinkeby": "wss://api.thegraph.com/subgraphs/name/daostack/v8_12_exp_rinkeby",
+ "http_kovan": "https://api.thegraph.com/subgraphs/name/daostack/v8_12_exp_kovan",
+ "ws_kovan": "wss://api.thegraph.com/subgraphs/name/daostack/v8_12_exp_kovan",
+ "http_xdai": "https://api.thegraph.com/subgraphs/name/daostack/v8_12_exp_xdai",
+ "ws_xdai": "wss://api.thegraph.com/subgraphs/name/daostack/v8_12_exp_xdai",
"http_ganache": "http://127.0.0.1:8000/subgraphs/name/daostack",
"ws_ganache": "ws://127.0.0.1:8001/subgraphs/name/daostack"
}
diff --git a/test/integration/wdio.conf.js b/test/integration/wdio.conf.js
index 1dbd18504..de157445a 100644
--- a/test/integration/wdio.conf.js
+++ b/test/integration/wdio.conf.js
@@ -124,7 +124,7 @@ exports.config = {
chrome: {
// check for more recent versions of chrome driver here:
// https://chromedriver.storage.googleapis.com/index.html
- version: "84.0.4147.30",
+ version: "85.0.4183.87",
arch: process.arch,
baseURL: "https://chromedriver.storage.googleapis.com",
},
@@ -139,7 +139,7 @@ exports.config = {
chrome: {
// check for more recent versions of chrome driver here:
// https://chromedriver.storage.googleapis.com/index.html
- version: "83.0.4103.39",
+ version: "85.0.4183.87",
arch: process.arch,
baseURL: "https://chromedriver.storage.googleapis.com",
},