Quellcode durchsuchen

Proposals: NavBar

Joystream Stats vor 4 Jahren
Ursprung
Commit
510350b265

+ 52 - 0
src/components/Proposals/NavBar.tsx

@@ -0,0 +1,52 @@
+import React from "react";
+import { Button, Nav, Navbar, NavDropdown } from "react-bootstrap";
+
+import { Sliders } from "react-feather";
+
+const NavBar = (props: any) => {
+  const { authors } = props;
+
+  return (
+    <Navbar bg="dark" variant="dark">
+      <Navbar.Brand href="/">Joystream</Navbar.Brand>
+      <Navbar.Toggle aria-controls="basic-navbar-nav" />
+      <Navbar.Collapse id="basic-navbar-nav">
+        <Nav className="mr-auto">
+          <Nav.Link href="/proposals">Proposals</Nav.Link>
+        </Nav>
+
+        <NavDropdown
+          title={<div className="text-light">Creator</div>}
+          id="basic-nav-dropdown"
+        >
+          <NavDropdown.Item
+            className={"All" === props.author ? "bg-dark text-light" : ""}
+            onClick={props.selectAuthor}
+          >
+            All
+          </NavDropdown.Item>
+          <NavDropdown.Divider />
+          {Object.keys(authors).map((author) => (
+            <NavDropdown.Item
+              key={author}
+              className={author === props.author ? "bg-dark text-light" : ""}
+              onClick={props.selectAuthor}
+            >
+              {author}
+            </NavDropdown.Item>
+          ))}
+        </NavDropdown>
+        <Button
+          onClick={props.toggleShowTypes}
+          title="Filter By Proposal Type"
+          variant="dark"
+          className="btn-sm m-0 p-0"
+        >
+          <Sliders color="white" />
+        </Button>
+      </Navbar.Collapse>
+    </Navbar>
+  );
+};
+
+export default NavBar;

+ 46 - 28
src/components/Proposals/ProposalTable.tsx

@@ -1,7 +1,8 @@
 import React from "react";
-import { Button, OverlayTrigger, Tooltip } from "react-bootstrap";
+import { OverlayTrigger, Tooltip } from "react-bootstrap";
 import Row from "./Row";
-
+import NavBar from "./NavBar";
+import Types from "./Types";
 import { Member, ProposalDetail, ProposalPost } from "../../types";
 
 interface IProps {
@@ -16,14 +17,22 @@ interface IState {
   key: any;
   asc: boolean;
   hidden: string[];
+  showTypes: boolean;
 }
 
 class ProposalTable extends React.Component<IProps, IState> {
   constructor(props: IProps) {
     super(props);
-    this.state = { key: "id", asc: false, hidden: [], author: "All" };
+    this.state = {
+      key: "id",
+      asc: false,
+      hidden: [],
+      author: "All",
+      showTypes: false,
+    };
     this.selectAuthor = this.selectAuthor.bind(this);
     this.toggleHide = this.toggleHide.bind(this);
+    this.toggleShowTypes = this.toggleShowTypes.bind(this);
   }
 
   setKey(key: string) {
@@ -31,6 +40,9 @@ class ProposalTable extends React.Component<IProps, IState> {
     else this.setState({ key });
   }
 
+  toggleShowTypes() {
+    this.setState({ showTypes: !this.state.showTypes });
+  }
   toggleHide(type: string) {
     const isHidden = this.state.hidden.includes(type);
     const hidden = isHidden
@@ -39,7 +51,7 @@ class ProposalTable extends React.Component<IProps, IState> {
     this.setState({ hidden });
   }
   selectAuthor(event: any) {
-    this.setState({ author: event.target.value });
+    this.setState({ author: event.target.text });
   }
 
   filterProposals() {
@@ -62,7 +74,7 @@ class ProposalTable extends React.Component<IProps, IState> {
   }
 
   render() {
-    const { avgDays, avgHours, block, members, proposalPosts } = this.props;
+    const { block, members, proposalPosts } = this.props;
     const { author, hidden } = this.state;
 
     // proposal types
@@ -76,32 +88,39 @@ class ProposalTable extends React.Component<IProps, IState> {
     const proposals = this.sortProposals(this.filterProposals());
     const approved = proposals.filter((p) => p.result === "Approved").length;
 
+    // calculate finalization times
+    const durations: any = proposals.map((p) =>
+      p.finalizedAt
+        ? p.finalizedAt - p.createdAt
+        : (block && block - p.createdAt) || 0
+    );
+
+    // calculate mean voting duration
+    const avgBlocks =
+      durations.reduce((a: number, b: number) => a + b) / durations.length;
+    const avgDays = Math.floor(avgBlocks / 14400);
+    const avgHours = Math.floor((avgBlocks - avgDays * 14400) / 600);
+
     return (
-      <div className="h-100 overflow-hidden">
-        <div className="">
-          {Object.keys(types).map((type) => (
-            <Button
-              key={type}
-              variant={hidden.includes(type) ? "outline-dark" : "dark"}
-              className="btn-sm m-1"
-              onClick={() => this.toggleHide(type)}
-            >
-              {type}
-            </Button>
-          ))}
-        </div>
+      <div className="h-100 overflow-hidden bg-light">
+        <NavBar
+          author={author}
+          authors={authors}
+          selectAuthor={this.selectAuthor}
+          toggleShowTypes={this.toggleShowTypes}
+        />
+
+        <Types
+          hidden={hidden}
+          show={this.state.showTypes}
+          toggleHide={this.toggleHide}
+          types={types}
+        />
 
         <div className="d-flex flex-row justify-content-between p-2 bg-dark text-light text-left font-weight-bold">
           <div onClick={() => this.setKey("id")}>ID</div>
           <div className="col-2" onClick={() => this.setKey("author")}>
             Author
-            <br />
-            <select value={author} onChange={this.selectAuthor}>
-              <option>All</option>
-              {Object.keys(authors).map((author: string) => (
-                <option key={author}>{author}</option>
-              ))}
-            </select>
           </div>
           <div className="col-3" onClick={() => this.setKey("description")}>
             Description
@@ -125,8 +144,7 @@ class ProposalTable extends React.Component<IProps, IState> {
           </div>
           <div className="col-2">
             Voting Duration
-            <br />
-            Average: {avgDays ? `${avgDays}d` : ""}
+            <br />∅ {avgDays ? `${avgDays}d` : ""}
             {avgHours ? `${avgHours}h` : ""}
           </div>
           <div className="col-1" onClick={() => this.setKey("createdAt")}>
@@ -139,7 +157,7 @@ class ProposalTable extends React.Component<IProps, IState> {
 
         <div
           className="d-flex flex-column overflow-auto p-2"
-          style={{ height: `75%` }}
+          style={{ height: `85%` }}
         >
           {proposals.map((p) => (
             <Row

+ 23 - 0
src/components/Proposals/Types.tsx

@@ -0,0 +1,23 @@
+import React from "react";
+import { Button } from "react-bootstrap";
+
+const Types = (props: any) => {
+  const { toggleHide, hidden, show, types } = props;
+  if (!show) return <div />;
+  return (
+    <div className="bg-dark p-2">
+      {Object.keys(types).map((type) => (
+        <Button
+          key={type}
+          variant={hidden.includes(type) ? "secondary" : "outline-light"}
+          className="btn-sm m-1"
+          onClick={() => toggleHide(type)}
+        >
+          {type}
+        </Button>
+      ))}
+    </div>
+  );
+};
+
+export default Types;

+ 7 - 27
src/components/Proposals/index.tsx

@@ -2,7 +2,6 @@ import React from "react";
 import { Member, ProposalDetail, ProposalPost } from "../../types";
 import Loading from "..//Loading";
 import ProposalTable from "./ProposalTable";
-import Back from "../Back";
 
 const Proposals = (props: {
   now: number;
@@ -30,34 +29,15 @@ const Proposals = (props: {
       </div>
     );
 
-  // - calculate blocks until finalized
-  const durations: any = proposals.map((p) =>
-    p.finalizedAt ? p.finalizedAt - p.createdAt : 0
-  );
-
-  // - calculate mean voting duration
-  const avgBlocks =
-    durations.reduce((a: number, b: number) => a + b) / durations.length;
-  const avgDays = avgBlocks ? Math.floor(avgBlocks / 14400) : 0;
-  const avgHours = avgBlocks
-    ? Math.floor((avgBlocks - avgDays * 14400) / 600)
-    : 0;
-
   // - list all proposals
   return (
-    <div className="w-100 h-100 flex-grow-1 overflow-hidden bg-light text-center">
-      <Back />
-      <h1>Joystream Proposals</h1>
-      <ProposalTable
-        avgDays={avgDays}
-        avgHours={avgHours}
-        block={block}
-        members={members}
-        proposals={proposals}
-        proposalPosts={proposalPosts}
-        startTime={startTime}
-      />
-    </div>
+    <ProposalTable
+      block={block}
+      members={members}
+      proposals={proposals}
+      proposalPosts={proposalPosts}
+      startTime={startTime}
+    />
   );
 };