index.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import React, { Component } from "react";
  2. import MinMax from "./MinMax";
  3. import Validator from "./Validator";
  4. import MemberBox from "../Members/MemberBox";
  5. import {
  6. Handles,
  7. Member,
  8. Post,
  9. ProposalDetail,
  10. Seat,
  11. Stakes,
  12. RewardPoints,
  13. } from "../../types";
  14. interface IProps {
  15. era: number;
  16. councils: Seat[][];
  17. handles: Handles;
  18. members: Member[];
  19. posts: Post[];
  20. proposals: ProposalDetail[];
  21. now: number;
  22. block: number;
  23. validators: string[];
  24. stashes: string[];
  25. nominators: string[];
  26. stars: { [key: string]: boolean };
  27. save: (target: string, data: any) => void;
  28. stakes?: { [key: string]: Stakes };
  29. rewardPoints?: RewardPoints;
  30. lastReward: number;
  31. issued: number;
  32. price: number;
  33. }
  34. interface IState {
  35. sortBy: string;
  36. }
  37. class Validators extends Component<IProps, IState> {
  38. constructor(props: IProps) {
  39. super(props);
  40. this.state = { sortBy: "totalStake" };
  41. this.toggleStar = this.toggleStar.bind(this);
  42. this.setSortBy = this.setSortBy.bind(this);
  43. }
  44. toggleStar(account: string) {
  45. let { stars } = this.props;
  46. stars[account] = !stars[account];
  47. this.props.save("stars", stars);
  48. }
  49. setSortBy(sortBy: string) {
  50. this.setState({ sortBy });
  51. }
  52. sortBy(field: string, validators: string[]) {
  53. const { stakes, rewardPoints } = this.props;
  54. try {
  55. if (field === "points")
  56. return validators.sort((a, b) =>
  57. rewardPoints
  58. ? rewardPoints.individual[b] - rewardPoints.individual[a]
  59. : 0
  60. );
  61. if (field === "commission")
  62. return validators.sort((a, b) =>
  63. stakes ? stakes[a].commission - stakes[b].commission : 0
  64. );
  65. if (field === "ownStake")
  66. return validators.sort((a, b) =>
  67. stakes ? stakes[b].own - stakes[a].own : 0
  68. );
  69. if (field === "totalStake")
  70. return validators.sort((a, b) =>
  71. stakes ? stakes[b].total - stakes[a].total : 0
  72. );
  73. if (field === "othersStake") {
  74. const sumOf = (stakes: { value: number }[]) => {
  75. let sum = 0;
  76. stakes.forEach((s) => (sum += s.value));
  77. return sum;
  78. };
  79. return validators.sort((a, b) =>
  80. stakes ? sumOf(stakes[b].others) - sumOf(stakes[a].others) : 0
  81. );
  82. }
  83. } catch (e) {
  84. console.debug(`sorting failed`, e);
  85. }
  86. return validators;
  87. }
  88. render() {
  89. const {
  90. block,
  91. era,
  92. now,
  93. councils,
  94. handles,
  95. members,
  96. posts,
  97. proposals,
  98. validators,
  99. nominators,
  100. stashes,
  101. stars,
  102. lastReward,
  103. rewardPoints,
  104. stakes,
  105. issued,
  106. price,
  107. } = this.props;
  108. const { sortBy } = this.state;
  109. const startTime = now - block * 6000;
  110. const starred = stashes.filter((v) => stars[v]);
  111. const unstarred = validators.filter((v) => !stars[v]);
  112. const waiting = stashes.filter((s) => !stars[s] && !validators.includes(s));
  113. return (
  114. <div className="box w-100 m-0 px-5">
  115. <div className="float-left">
  116. last block: {block}, era {era}
  117. </div>
  118. <MinMax
  119. stakes={stakes}
  120. issued={issued}
  121. price={price}
  122. validators={validators.length}
  123. nominators={nominators.length}
  124. waiting={waiting.length}
  125. reward={lastReward}
  126. />
  127. <h3>Validators</h3>
  128. <div className="d-flex flex-column">
  129. {this.sortBy(sortBy, starred).map((v) => (
  130. <Validator
  131. key={v}
  132. sortBy={this.setSortBy}
  133. starred={stars[v] ? `teal` : undefined}
  134. toggleStar={this.toggleStar}
  135. startTime={startTime}
  136. validator={v}
  137. reward={lastReward / validators.length}
  138. councils={councils}
  139. handles={handles}
  140. members={members}
  141. posts={posts}
  142. proposals={proposals}
  143. validators={validators}
  144. stakes={stakes}
  145. rewardPoints={rewardPoints}
  146. />
  147. ))}
  148. {this.sortBy(sortBy, unstarred).map((v) => (
  149. <Validator
  150. key={v}
  151. sortBy={this.setSortBy}
  152. starred={stars[v] ? `teal` : undefined}
  153. toggleStar={this.toggleStar}
  154. startTime={startTime}
  155. validator={v}
  156. reward={lastReward / validators.length}
  157. councils={councils}
  158. handles={handles}
  159. members={members}
  160. posts={posts}
  161. proposals={proposals}
  162. validators={validators}
  163. stakes={stakes}
  164. rewardPoints={rewardPoints}
  165. />
  166. ))}
  167. <hr />
  168. Waiting:
  169. {waiting.map((v) => (
  170. <MemberBox
  171. key={v}
  172. id={0}
  173. account={v}
  174. placement={"top"}
  175. councils={councils}
  176. handle={handles[v]}
  177. members={members}
  178. posts={posts}
  179. proposals={proposals}
  180. startTime={startTime}
  181. validators={validators}
  182. />
  183. ))}
  184. </div>
  185. </div>
  186. );
  187. }
  188. }
  189. export default Validators;