3
0

4 کامیت‌ها 386db819ca ... 752eebdfd7

نویسنده SHA1 پیام تاریخ
  mkbeefcake 752eebdfd7 20230218: GraphQL-Integration: Integreated Membership GraphQL 1 سال پیش
  mkbeefcake f481453cfb 20230218: GraphQL-Integration : Fixed issue on Council.gql 1 سال پیش
  mkbeefcake ce72f17646 20230218: GraphQL-Integration : Renamed councilMember.gql to councilMembers.gql 1 سال پیش
  mkbeefcake 33295a18be 20230218: GraphQL-Integration : Integrated Elected Council GraphQL 1 سال پیش

+ 1 - 1
codegen.yml

@@ -1,6 +1,6 @@
 overwrite: true
 
-schema: 'https://query.joystream.org/graphql'
+schema: 'https://tiguan08.com/graphql'
 
 documents:
   - './src/queries/**/*.gql'

+ 2 - 0
package.json

@@ -4,6 +4,7 @@
   "license": "GPL-3.0-or-later",
   "repository": "https://github.com/Joystream/community-repo",
   "dependencies": {
+    "@apollo/client": "^3.7.8",
     "@joystream/types": "0.20.5",
     "@material-ui/core": "^4.12.3",
     "@material-ui/data-grid": "^4.0.0-alpha.35",
@@ -100,6 +101,7 @@
     "stream-browserify": "^3.0.0",
     "style-loader": "^3.3.1",
     "ts-loader": "^9.4.2",
+    "tsconfig-paths-webpack-plugin": "^4.0.0",
     "typescript": "^4.9.5",
     "webpack": "^5.75.0",
     "webpack-cli": "^5.0.1",

+ 1 - 1
public/index.html

@@ -4,7 +4,7 @@
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
     <meta name="theme-color" content="#000000" />
-    <link rel="manifest" href="/public/manifest.json" />
+    <link rel="manifest" href="manifest.json" />
     <title>JoystreamStats</title>
   </head>
   <body>

+ 6 - 7
src/App.tsx

@@ -317,8 +317,7 @@ class App extends React.Component<IProps, IState> {
   }
 
   componentDidMount() {
-    debugger;
-    this.loadData(); // local storage + bootstrap
+    // this.loadData(); // local storage + bootstrap
     // this.joyApi(); // joystream rpc connection
     //this.initializeSocket() // jsstats socket.io
   }
@@ -328,11 +327,11 @@ class App extends React.Component<IProps, IState> {
     this.state = initialState;
     this.save = this.save.bind(this);
     this.load = this.load.bind(this);
-    this.toggleEditKpi = this.toggleEditKpi.bind(this);
-    this.toggleStar = this.toggleStar.bind(this);
-    this.toggleFooter = this.toggleFooter.bind(this);
-    this.toggleShowStatus = this.toggleShowStatus.bind(this);
-    this.getMember = this.getMember.bind(this);
+    // this.toggleEditKpi = this.toggleEditKpi.bind(this);
+    // this.toggleStar = this.toggleStar.bind(this);
+    // this.toggleFooter = this.toggleFooter.bind(this);
+    // this.toggleShowStatus = this.toggleShowStatus.bind(this);
+    // this.getMember = this.getMember.bind(this);
   }
 }
 

+ 27 - 0
src/Providers.tsx

@@ -0,0 +1,27 @@
+import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client';
+import React from 'react';
+import { queryNode } from './config';
+
+const client = new ApolloClient({
+  // uri: import.meta.env.VITE_QN_URL,
+  uri: queryNode,
+  cache: new InMemoryCache(),
+  connectToDevTools: true,
+  defaultOptions: {
+    watchQuery: {
+      fetchPolicy: 'cache-and-network',
+      errorPolicy: 'all',
+    },
+    query: {
+      fetchPolicy: 'standby',
+      errorPolicy: 'all',
+    },
+    mutate: {
+      errorPolicy: 'all',
+    },
+  },
+});
+
+export default function Providers({ children }: React.PropsWithChildren) {
+  return <ApolloProvider client={client}>{children}</ApolloProvider>;
+}

+ 14 - 4
src/components/Dashboard/Memberships.tsx

@@ -1,14 +1,24 @@
 import React from "react";
 import SubBlock from "./ui/SubBlock";
 import Line from "./ui/Line";
+import { ElectedCouncil } from "@/types";
+import { useMemberships } from "@/hooks";
 
-const Memberships = (props: {}) => {
+const Memberships = (props: { council: ElectedCouncil | undefined }) => {
+  const { council } = props;
+  const { created, invited, total, loading, error } = useMemberships({ council });
+
+  console.log(created, invited, total, loading)
 
   return (
     <SubBlock title="Memberships">
-      <Line content={"created"} value={99} />
-      <Line content={"created"} value={100} />
-      <Line content={"total"} value={8000} />
+      { !loading && (
+        <>
+          <Line content={"Created"} value={created} />
+          <Line content={"Invited"} value={invited} />
+          <Line content={"Total"} value={total} />
+        </>
+      )}
     </SubBlock>
   );
 };

+ 26 - 28
src/components/Dashboard/index.tsx

@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useEffect, useState } from "react";
 import { IState } from "../../types";
 import { Container, Grid } from "@material-ui/core";
 import Memberships from "./Memberships";
@@ -9,42 +9,40 @@ import Election from "./Election";
 import Validation from "./Validation";
 import SubBlock from "./ui/SubBlock";
 import Banner from "./ui/Banner";
+import { useElectedCouncils } from '@/hooks';
+import { ElectedCouncil } from "@/types";
 
-interface IProps extends IState {
-}
 
+interface IProps extends IState {}
 const Dashboard = (props: IProps) => {
-  const {
-    getMember,
-    toggleStar,
-    councils,
-    members,
-    nominators,
-    openings,
-    posts,
-    proposals,
-    rewardPoints,
-    threads,
-    tokenomics,
-    status,
-    stars,
-    stashes,
-    stakes,
-    validators,
-    domain,
-  } = props;
+  const { } = props;
+  const { data } = useElectedCouncils({});
+	const [description1, setDescription1] = useState('');
+	const [description2, setDescription2] = useState('');
 
-  const _description1 = "For a given council period {so there needs to be an input field for this}, I want to see a nice one page dashboard which shows the following, and nothing else (each at end of period)"
-  const _description2 = "new tokens minted size of budget at end of period amount of debt at end of period number of workers at end of period"
+	const council: ElectedCouncil | undefined = data && data[0]
+
+	useEffect(() => {
+		console.log(council)
+
+		if (!council) return
+
+		setDescription1(
+			"Round: " + council.electionCycleId + 
+			", From: " + new Date(council.electedAt.timestamp) + 
+			", Councilors: [ " + council.councilors.map(each => each.member.handle).join(", ") + " ]")
+
+	}, [council])
+ 
 
   return (
     <div style={{ flexGrow: 1 }}>
       <Container maxWidth="xl">
         <Grid container spacing={3}>
-          <Banner description={_description1}/>
+          <Banner description={description1}/>
         </Grid>
         <Grid container spacing={3}>
-          <Memberships
+          <Memberships council={council}
           />
           <Channels
           />
@@ -58,10 +56,10 @@ const Dashboard = (props: IProps) => {
           />
         </Grid>
         <Grid container spacing={3}>
-          <Banner title="WG" description={_description2}/>
+          <Banner title="WG" description={description2}/>
         </Grid>
         <Grid container spacing={3}>
-          <Banner title="Proposals" description={_description2}/>
+          <Banner title="Proposals" description={description2}/>
         </Grid>
       </Container>
     </div>

+ 3 - 1
src/components/Dashboard/ui/Banner.tsx

@@ -56,7 +56,9 @@ const Banner = (props: {
             </Toolbar>
           </AppBar>
         }
-        <Line content={description} />
+        <i>
+          <Line content={description} />
+        </i>
         {/* <Typography variant="body1" className={classes.description}>
             {description}
         </Typography> */}

+ 1 - 1
src/components/Dashboard/ui/Line.tsx

@@ -15,7 +15,7 @@ const Line = (props: {
   return (
     <Box sx={{ display: 'flex', paddingLeft:'16px', paddingRight:'16px', color: '#000' }} >
 			<Box sx={{ flexGrow: 1, textAlign: "left" }}>{content}</Box>
-			<Box sx={{ textAlign: "right" }}>{value}</Box>
+			<Box sx={{ textAlign: "right" }}><i>{value}</i></Box>
     </Box>
   );
 };

+ 3 - 1
src/config.ts

@@ -4,7 +4,9 @@ export const wsLocation = "wss://joystreamstats.live:9945";
 export const apiLocation = "https://api.joystreamstats.live/api"
 export const socketLocation = "/socket.io"
 export const hydraLocation = "https://hydra.joystream.org/graphql"
-export const queryNode= "https://hydra.joystream.org/graphql"
+export const queryNode= "https://tiguan08.com/graphql"
+// export const queryNode= "https://hydra.joystream.org/graphql"
+// export const queryNode= "https://query.joystream.org/graphql"
 //export const alternativeBackendApis = "http://localhost:3000"
 export const alternativeBackendApis = "https://validators.joystreamstats.live"
 export const tasksEndpoint = "https://api.joystreamstats.live/tasks"

+ 15 - 0
src/helpers/bn.ts

@@ -0,0 +1,15 @@
+import { BN_TEN, BN_TWO, BN_ZERO } from '@polkadot/util';
+import BN from 'bn.js';
+
+type BNParam = number | string | number[] | Uint8Array | Buffer | BN;
+
+export const sumStakes = (entities: { stake: BNParam }[]) =>
+  entities.reduce((total, { stake }) => total.add(new BN(stake)), BN_ZERO);
+
+export const asBN = (value: any) => new BN(String(value));
+
+export const sumBN = (a: BN | undefined, b: BN | undefined): BN => new BN(a ?? 0).add(new BN(b ?? 0));
+
+export const powerOf10 = (value: any) => BN_TEN.pow(asBN(value));
+
+export const powerOf2 = (value: any) => BN_TWO.pow(asBN(value));

+ 2 - 0
src/helpers/index.ts

@@ -0,0 +1,2 @@
+export * from './bn';
+export * from './utils';

+ 94 - 0
src/helpers/utils.ts

@@ -0,0 +1,94 @@
+export const capitalizeFirstLetter = <T extends string>(str: T) =>
+  (str.charAt(0).toUpperCase() + str.slice(1)) as Capitalize<T>;
+
+export const lowerFirstLetter = (str: string): string => str.charAt(0).toLowerCase() + str.slice(1);
+
+export const plural = (quantity?: unknown, suffix = 's') => (quantity === 1 ? '' : suffix);
+
+export const cutText = (text: string, length = 100) => (text.length > length ? text.slice(0, length) + '...' : text);
+
+export const isInFuture = (time: string) => {
+  const timeAsDate = new Date(time).valueOf();
+  return timeAsDate > Date.now();
+};
+
+export const nameMapping = (value: string) => {
+  switch (value) {
+    case 'Operations Alpha':
+      return 'Builders';
+    case 'App':
+      return 'Apps';
+    case 'Operations Beta':
+      return 'HR';
+    case 'Operations Gamma':
+      return 'Marketing';
+    default:
+      return value;
+  }
+};
+
+export const wgListItemMappings = (value: string) => {
+  switch (value) {
+    case 'Operations Alpha':
+      return {
+        subtitle:
+          'A diverse set of contributors, such as Developers, Designers and Product Managers, responsible for development of infrastructure and user facing applications.',
+        tooltipLink: 'https://joystream.gitbook.io/testnet-workspace/system/builders',
+      };
+    case 'Storage':
+      return {
+        subtitle:
+          'Broadly responsible for ensuring storage infrastructure uptime, namely running complete and up-to-date copy of the content directory and accept inbound uploads from end users.',
+        tooltipLink: 'https://joystream.gitbook.io/testnet-workspace/system/storage',
+      };
+    case 'Content':
+      return {
+        subtitle:
+          'Monitor publishing of the new content into the content directory, respond to the reported publications and adjudicate possible dispute processes.',
+        tooltipLink: 'https://joystream.gitbook.io/testnet-workspace/system/content-directory',
+      };
+    case 'Distribution':
+      return {
+        subtitle:
+          'Run and maintain distributor nodes that deliver large volumes of upstream data to a large number of simultaneous end users.',
+        tooltipLink: 'https://joystream.gitbook.io/testnet-workspace/system/storage#distributor',
+      };
+    case 'App':
+      return {
+        subtitle:
+          'Apps group runs multiple video streaming apps working on Joystream blockchain and provides support to all external app operators.',
+        tooltipLink: 'https://joystream.gitbook.io/testnet-workspace/system/gateways',
+      };
+    case 'Operations Beta':
+      return {
+        subtitle:
+          'Human Resources working group is responsible for integrating new members greeting, onboarding, catalyzing and nurturing, as well as managing bounties.',
+        tooltipLink:
+          'https://joystream.gitbook.io/testnet-workspace/testnet/council-period-scoring/human-resources-score',
+      };
+    case 'Operations Gamma':
+      return {
+        subtitle:
+          'Marketing group is responsible for increasing the outreach, sharing the content from the platform with the world, spreading the news about platform development, new members acquisition and overall growth.',
+        tooltipLink: 'https://joystream.gitbook.io/testnet-workspace/system/marketers',
+      };
+    case 'Membership':
+      return {
+        subtitle:
+          'Membership group is responsible for new memberships invitations, referral rewards for existing members and overall process of adding more members via referral scheme.',
+        tooltipLink:
+          'https://joystream.gitbook.io/testnet-workspace/testnet/council-period-scoring/human-resources-score',
+      };
+    case 'Forum':
+      return {
+        subtitle:
+          'Monitor and supervise public communication channels for compliance with usage policies as decided through the governance system.',
+        tooltipLink: 'https://joystream.gitbook.io/testnet-workspace/system/forum',
+      };
+    default:
+      return {
+        subtitle: value,
+        tooltipLink: undefined,
+      };
+  }
+};

+ 4 - 1
src/index.tsx

@@ -3,12 +3,15 @@ import ReactDOM from "react-dom";
 import { BrowserRouter as Router } from "react-router-dom";
 import "./index.css";
 import App from "./App";
+import Providers from "./Providers";
 
 import "./i18n";
 
 ReactDOM.render(
   <Router>
-    <App />
+    <Providers>
+      <App />
+    </Providers>
   </Router>,
   document.getElementById("root")
 );

+ 20 - 20
src/queries/__generated__/baseTypes.generated.ts

@@ -1234,7 +1234,7 @@ export type AuctionTypeEnglish = {
   /** Auction extension time */
   extensionPeriod: Scalars['Int'];
   /** Minimal step between auction bids */
-  minimalBidStep: Scalars['BigInt'];
+  minimalBidStep: Scalars['Float'];
   /** Block when auction is supposed to end */
   plannedEndAtBlock: Scalars['Int'];
 };
@@ -2512,7 +2512,7 @@ export type BountyEntryStatusRejected = {
 
 export type BountyEntryStatusWinner = {
   __typename: 'BountyEntryStatusWinner';
-  reward: Scalars['BigInt'];
+  reward: Scalars['Float'];
 };
 
 export type BountyEntryStatusWithdrawn = {
@@ -2715,15 +2715,15 @@ export type BountyFundingLimited = {
   /** Maximum allowed funding period */
   fundingPeriod: Scalars['Int'];
   /** Upper boundary for a bounty funding */
-  maxFundingAmount: Scalars['BigInt'];
+  maxFundingAmount: Scalars['Float'];
   /** Minimum amount of funds for a successful bounty */
-  minFundingAmount: Scalars['BigInt'];
+  minFundingAmount: Scalars['Float'];
 };
 
 export type BountyFundingPerpetual = {
   __typename: 'BountyFundingPerpetual';
   /** Desired funding */
-  target: Scalars['BigInt'];
+  target: Scalars['Float'];
 };
 
 export type BountyFundingType = BountyFundingLimited | BountyFundingPerpetual;
@@ -8698,7 +8698,7 @@ export type CouncilStage = CouncilStageAnnouncing | CouncilStageElection | Counc
 export type CouncilStageAnnouncing = {
   __typename: 'CouncilStageAnnouncing';
   /** Number of candidates aspiring to be elected as council members. */
-  candidatesCount: Scalars['BigInt'];
+  candidatesCount: Scalars['Float'];
   /** Block number at which the stage ends */
   endsAt: Scalars['Int'];
 };
@@ -8706,7 +8706,7 @@ export type CouncilStageAnnouncing = {
 export type CouncilStageElection = {
   __typename: 'CouncilStageElection';
   /** Number of candidates aspiring to be elected as council members. */
-  candidatesCount: Scalars['BigInt'];
+  candidatesCount: Scalars['Float'];
 };
 
 export type CouncilStageIdle = {
@@ -8959,9 +8959,9 @@ export type CreateWorkingGroupLeadOpeningProposalDetails = {
   /** The opening metadata */
   metadata?: Maybe<WorkingGroupOpeningMetadata>;
   /** Initial workers' reward per block */
-  rewardPerBlock: Scalars['BigInt'];
+  rewardPerBlock: Scalars['Float'];
   /** Min. application / role stake amount */
-  stakeAmount: Scalars['BigInt'];
+  stakeAmount: Scalars['Float'];
   /** Role stake unstaking period in blocks */
   unstakingPeriod: Scalars['Int'];
 };
@@ -9359,7 +9359,7 @@ export type DataObjectTypeVideoThumbnail = {
 export type DecreaseWorkingGroupLeadStakeProposalDetails = {
   __typename: 'DecreaseWorkingGroupLeadStakeProposalDetails';
   /** Amount to decrease the stake by */
-  amount: Scalars['BigInt'];
+  amount: Scalars['Float'];
   /** The lead that should be affected */
   lead?: Maybe<Worker>;
 };
@@ -27536,19 +27536,19 @@ export type SearchSearchResult = Channel | Video;
 export type SetCouncilBudgetIncrementProposalDetails = {
   __typename: 'SetCouncilBudgetIncrementProposalDetails';
   /** New (proposed) amount the council budget should be increased by per each budget period */
-  newAmount: Scalars['BigInt'];
+  newAmount: Scalars['Float'];
 };
 
 export type SetCouncilorRewardProposalDetails = {
   __typename: 'SetCouncilorRewardProposalDetails';
   /** New (proposed) council members' reward per block */
-  newRewardPerBlock: Scalars['BigInt'];
+  newRewardPerBlock: Scalars['Float'];
 };
 
 export type SetInitialInvitationBalanceProposalDetails = {
   __typename: 'SetInitialInvitationBalanceProposalDetails';
   /** The new (proposed) initial balance credited to controller account of an invitee (locked for transaction fee payments only) */
-  newInitialInvitationBalance: Scalars['BigInt'];
+  newInitialInvitationBalance: Scalars['Float'];
 };
 
 export type SetInitialInvitationCountProposalDetails = {
@@ -27572,7 +27572,7 @@ export type SetMembershipLeadInvitationQuotaProposalDetails = {
 export type SetMembershipPriceProposalDetails = {
   __typename: 'SetMembershipPriceProposalDetails';
   /** New (proposed) membership price */
-  newPrice: Scalars['BigInt'];
+  newPrice: Scalars['Float'];
 };
 
 export type SetReferralCutProposalDetails = {
@@ -27586,7 +27586,7 @@ export type SetWorkingGroupLeadRewardProposalDetails = {
   /** The lead that should be affected */
   lead?: Maybe<Worker>;
   /** Lead's new (proposed) reward per block */
-  newRewardPerBlock: Scalars['BigInt'];
+  newRewardPerBlock: Scalars['Float'];
 };
 
 export type SignalProposalDetails = {
@@ -27598,7 +27598,7 @@ export type SignalProposalDetails = {
 export type SlashWorkingGroupLeadProposalDetails = {
   __typename: 'SlashWorkingGroupLeadProposalDetails';
   /** Amount to slash the stake by */
-  amount: Scalars['BigInt'];
+  amount: Scalars['Float'];
   /** The lead that should be affected */
   lead?: Maybe<Worker>;
 };
@@ -29310,7 +29310,7 @@ export type TerminateWorkingGroupLeadProposalDetails = {
   /** Lead that's supposed to be terminated */
   lead?: Maybe<Worker>;
   /** Optionally - the amount to slash the lead's stake by */
-  slashingAmount?: Maybe<Scalars['BigInt']>;
+  slashingAmount?: Maybe<Scalars['Float']>;
 };
 
 export type TerminatedLeaderEvent = BaseGraphQlObject & Event & {
@@ -30366,7 +30366,7 @@ export type TransactionalStatus = TransactionalStatusBuyNow | TransactionalStatu
 
 export type TransactionalStatusBuyNow = {
   __typename: 'TransactionalStatusBuyNow';
-  price: Scalars['BigInt'];
+  price: Scalars['Float'];
 };
 
 export type TransactionalStatusIdle = {
@@ -30380,7 +30380,7 @@ export type TransactionalStatusInitiatedOfferToMember = {
   /** Member identifier */
   memberId: Scalars['Int'];
   /** Whether member should pay to accept offer (optional) */
-  price?: Maybe<Scalars['BigInt']>;
+  price?: Maybe<Scalars['Float']>;
 };
 
 export type TransactionalStatusUpdate = BaseGraphQlObject & {
@@ -30631,7 +30631,7 @@ export type UpcomingWorkingGroupOpeningWhereUniqueInput = {
 export type UpdateWorkingGroupBudgetProposalDetails = {
   __typename: 'UpdateWorkingGroupBudgetProposalDetails';
   /** Amount to increase / decrease the working group budget by (will be decudted from / appended to council budget accordingly) */
-  amount: Scalars['BigInt'];
+  amount: Scalars['Float'];
   /** Related working group */
   group?: Maybe<WorkingGroup>;
 };

+ 6 - 3
src/queries/__generated__/councilMember.generated.tsx → src/queries/__generated__/councilMembers.generated.tsx

@@ -3,15 +3,17 @@ import * as Types from './baseTypes.generated';
 import { gql } from '@apollo/client';
 import * as Apollo from '@apollo/client';
 const defaultOptions = {} as const;
-export type GetCouncilMembersQueryVariables = Types.Exact<{ [key: string]: never; }>;
+export type GetCouncilMembersQueryVariables = Types.Exact<{
+  where?: Types.InputMaybe<Types.CouncilMemberWhereInput>;
+}>;
 
 
 export type GetCouncilMembersQuery = { __typename: 'Query', councilMembers: Array<{ __typename: 'CouncilMember', electedInCouncilId: string, member: { __typename: 'Membership', handle: string } }> };
 
 
 export const GetCouncilMembersDocument = gql`
-    query getCouncilMembers {
-  councilMembers {
+    query getCouncilMembers($where: CouncilMemberWhereInput) {
+  councilMembers(where: $where) {
     electedInCouncilId
     member {
       handle
@@ -32,6 +34,7 @@ export const GetCouncilMembersDocument = gql`
  * @example
  * const { data, loading, error } = useGetCouncilMembersQuery({
  *   variables: {
+ *      where: // value for 'where'
  *   },
  * });
  */

+ 6 - 4
src/queries/__generated__/councils.generated.tsx

@@ -1,6 +1,7 @@
 import * as Types from './baseTypes.generated';
 
 import { gql } from '@apollo/client';
+import { MemberFieldsFragmentDoc } from './members.generated';
 import * as Apollo from '@apollo/client';
 const defaultOptions = {} as const;
 export type GetElectedCouncilsQueryVariables = Types.Exact<{
@@ -11,16 +12,17 @@ export type GetElectedCouncilsQueryVariables = Types.Exact<{
 }>;
 
 
-export type GetElectedCouncilsQuery = { __typename: 'Query', electedCouncils: Array<{ __typename: 'ElectedCouncil', id: string, electedAtBlock: number, endedAtBlock?: number | null, electedAtTime: any, endedAtTime?: any | null, electedAtNetwork: Types.Network, endedAtNetwork?: Types.Network | null, councilElections: Array<{ __typename: 'ElectionRound', cycleId: number }>, councilMembers: Array<{ __typename: 'CouncilMember', id: string, unpaidReward: string, stake: string, member: { __typename: 'Membership', councilMembers: Array<{ __typename: 'CouncilMember' }> } }> }> };
+export type GetElectedCouncilsQuery = { __typename: 'Query', electedCouncils: Array<{ __typename: 'ElectedCouncil', id: string, electedAtBlock: number, endedAtBlock?: number | null, electedAtTime: any, endedAtTime?: any | null, electedAtNetwork: Types.Network, endedAtNetwork?: Types.Network | null, councilElections: Array<{ __typename: 'ElectionRound', cycleId: number }>, councilMembers: Array<{ __typename: 'CouncilMember', id: string, unpaidReward: string, stake: string, member: { __typename: 'Membership', id: string, rootAccount: string, controllerAccount: string, boundAccounts: Array<string>, handle: string, isVerified: boolean, isFoundingMember: boolean, isCouncilMember: boolean, inviteCount: number, createdAt: any, councilMembers: Array<{ __typename: 'CouncilMember' }>, metadata: { __typename: 'MemberMetadata', name?: string | null, about?: string | null, avatar?: { __typename: 'AvatarObject' } | { __typename: 'AvatarUri', avatarUri: string } | null }, roles: Array<{ __typename: 'Worker', id: string, createdAt: any, isLead: boolean, group: { __typename: 'WorkingGroup', name: string } }>, stakingaccountaddedeventmember?: Array<{ __typename: 'StakingAccountAddedEvent', createdAt: any, inBlock: number, network: Types.Network, account: string }> | null } }> }> };
 
-export type ElectedCouncilFieldsFragment = { __typename: 'ElectedCouncil', id: string, electedAtBlock: number, endedAtBlock?: number | null, electedAtTime: any, endedAtTime?: any | null, electedAtNetwork: Types.Network, endedAtNetwork?: Types.Network | null, councilElections: Array<{ __typename: 'ElectionRound', cycleId: number }>, councilMembers: Array<{ __typename: 'CouncilMember', id: string, unpaidReward: string, stake: string, member: { __typename: 'Membership', councilMembers: Array<{ __typename: 'CouncilMember' }> } }> };
+export type ElectedCouncilFieldsFragment = { __typename: 'ElectedCouncil', id: string, electedAtBlock: number, endedAtBlock?: number | null, electedAtTime: any, endedAtTime?: any | null, electedAtNetwork: Types.Network, endedAtNetwork?: Types.Network | null, councilElections: Array<{ __typename: 'ElectionRound', cycleId: number }>, councilMembers: Array<{ __typename: 'CouncilMember', id: string, unpaidReward: string, stake: string, member: { __typename: 'Membership', id: string, rootAccount: string, controllerAccount: string, boundAccounts: Array<string>, handle: string, isVerified: boolean, isFoundingMember: boolean, isCouncilMember: boolean, inviteCount: number, createdAt: any, councilMembers: Array<{ __typename: 'CouncilMember' }>, metadata: { __typename: 'MemberMetadata', name?: string | null, about?: string | null, avatar?: { __typename: 'AvatarObject' } | { __typename: 'AvatarUri', avatarUri: string } | null }, roles: Array<{ __typename: 'Worker', id: string, createdAt: any, isLead: boolean, group: { __typename: 'WorkingGroup', name: string } }>, stakingaccountaddedeventmember?: Array<{ __typename: 'StakingAccountAddedEvent', createdAt: any, inBlock: number, network: Types.Network, account: string }> | null } }> };
 
-export type CouncilMemberFieldsFragment = { __typename: 'CouncilMember', id: string, unpaidReward: string, stake: string, member: { __typename: 'Membership', councilMembers: Array<{ __typename: 'CouncilMember' }> } };
+export type CouncilMemberFieldsFragment = { __typename: 'CouncilMember', id: string, unpaidReward: string, stake: string, member: { __typename: 'Membership', id: string, rootAccount: string, controllerAccount: string, boundAccounts: Array<string>, handle: string, isVerified: boolean, isFoundingMember: boolean, isCouncilMember: boolean, inviteCount: number, createdAt: any, councilMembers: Array<{ __typename: 'CouncilMember' }>, metadata: { __typename: 'MemberMetadata', name?: string | null, about?: string | null, avatar?: { __typename: 'AvatarObject' } | { __typename: 'AvatarUri', avatarUri: string } | null }, roles: Array<{ __typename: 'Worker', id: string, createdAt: any, isLead: boolean, group: { __typename: 'WorkingGroup', name: string } }>, stakingaccountaddedeventmember?: Array<{ __typename: 'StakingAccountAddedEvent', createdAt: any, inBlock: number, network: Types.Network, account: string }> | null } };
 
 export const CouncilMemberFieldsFragmentDoc = gql`
     fragment CouncilMemberFields on CouncilMember {
   id
   member {
+    ...MemberFields
     councilMembers {
       __typename
     }
@@ -28,7 +30,7 @@ export const CouncilMemberFieldsFragmentDoc = gql`
   unpaidReward
   stake
 }
-    `;
+    ${MemberFieldsFragmentDoc}`;
 export const ElectedCouncilFieldsFragmentDoc = gql`
     fragment ElectedCouncilFields on ElectedCouncil {
   id

+ 0 - 8
src/queries/councilMember.gql

@@ -1,8 +0,0 @@
-query getCouncilMembers{
-  councilMembers{
-    electedInCouncilId
-    member{
-      handle
-    }
-  }
-}

+ 8 - 0
src/queries/councilMembers.gql

@@ -0,0 +1,8 @@
+query getCouncilMembers($where:CouncilMemberWhereInput){
+  councilMembers(where:$where){
+    electedInCouncilId
+    member{
+      handle
+    }
+  }
+}

+ 1 - 0
src/queries/councils.gql

@@ -30,6 +30,7 @@ fragment ElectedCouncilFields on ElectedCouncil {
 fragment CouncilMemberFields on CouncilMember {
   id
   member {
+    ...MemberFields
     councilMembers {
       __typename
     }

+ 1 - 0
src/queries/index.tsx

@@ -12,3 +12,4 @@ export * from './__generated__/workingGroups.generated';
 export * from './__generated__/tokens.generated';
 export * from './__generated__/workers.generated';
 export * from './__generated__/councilMembers.generated';
+export * from './patched/index';

+ 8 - 0
src/queries/patched/index.ts

@@ -0,0 +1,8 @@
+import * as Types from '../__generated__/baseTypes.generated';
+
+import { gql } from '@apollo/client';
+import * as Apollo from '@apollo/client';
+
+const defaultOptions = {} as const;
+
+export type CouncilMemberFragment = { __typename: 'CouncilMember', electedInCouncilId: string, member: { handle: string } };

+ 2 - 2
src/types/Member.ts

@@ -68,8 +68,8 @@ export interface MemberWithDetails extends Member {
 export const asMember = (data: Omit<MemberFieldsFragment, '__typename'>): Member => ({
   id: data.id,
   handle: data.handle,
-  name: data.metadata.name ?? undefined,
-  avatar: castQueryResult(data.metadata.avatar, 'AvatarUri')?.avatarUri,
+  // name: data.metadata?.name ?? undefined,
+  // avatar: "", /*castQueryResult(data.metadata.avatar, 'AvatarUri')?.avatarUri ?? "",*/
   inviteCount: data.inviteCount,
   isFoundingMember: data.isFoundingMember,
   isCouncilMember: data.isCouncilMember,

+ 0 - 0
src/types.ts → src/types_.ts


+ 0 - 1
tsconfig.json

@@ -20,7 +20,6 @@
       "baseUrl": ".",
       "paths": {
         "@/*": ["./src/*"],
-        "./*": ["./node_modules/*", "./src/*"]
       }
   },
   "exclude": [

+ 10 - 8
webpack.config.js

@@ -1,6 +1,7 @@
 const path = require('path');
 const webpack = require('webpack')
 const HtmlWebpackPlugin = require('html-webpack-plugin');
+const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
 
 const { DEV, DEBUG } = process.env;
 
@@ -96,19 +97,20 @@ module.exports = {
             path: require.resolve("path-browserify"),
             fs: false,
         },
+        plugins: [ new TsconfigPathsPlugin({ configFile: "./tsconfig.json" }) ]
         // alias: {
         //   '@': path.resolve(__dirname, './src/'),
         //   'react/jsx-runtime': require.resolve('react/jsx-runtime'),
         // },
       },
     plugins:[
-        new HtmlWebpackPlugin({
-            template: path.join(__dirname,'/public/index.html')
-        }),
-        new webpack.ProvidePlugin({
-          Buffer: ['buffer', 'Buffer'],
-          process: 'process/browser.js',
-          "React": "react",
-        }),      
+      new HtmlWebpackPlugin({
+          template: path.join(__dirname,'/public/index.html')
+      }),
+      new webpack.ProvidePlugin({
+        Buffer: ['buffer', 'Buffer'],
+        process: 'process/browser.js',
+        "React": "react",
+      }),      
     ]
 }

+ 97 - 2
yarn.lock

@@ -10,6 +10,25 @@
     "@jridgewell/gen-mapping" "^0.1.0"
     "@jridgewell/trace-mapping" "^0.3.9"
 
+"@apollo/client@^3.7.8":
+  version "3.7.8"
+  resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.7.8.tgz#e1c8dfd02cbbe1baf9b18fa86918904efd9cc580"
+  integrity sha512-o1NxF4ytET2w9HSVMLwYUEEdv6H3XPpbh9M+ABVGnUVT0s6T9pgqRtYO4pFP1TmeDmb1pbRfVhFwh3gC167j5Q==
+  dependencies:
+    "@graphql-typed-document-node/core" "^3.1.1"
+    "@wry/context" "^0.7.0"
+    "@wry/equality" "^0.5.0"
+    "@wry/trie" "^0.3.0"
+    graphql-tag "^2.12.6"
+    hoist-non-react-statics "^3.3.2"
+    optimism "^0.16.1"
+    prop-types "^15.7.2"
+    response-iterator "^0.2.6"
+    symbol-observable "^4.0.0"
+    ts-invariant "^0.10.3"
+    tslib "^2.3.0"
+    zen-observable-ts "^1.2.5"
+
 "@ardatan/relay-compiler@12.0.0":
   version "12.0.0"
   resolved "https://registry.yarnpkg.com/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz#2e4cca43088e807adc63450e8cab037020e91106"
@@ -3801,6 +3820,27 @@
     fast-url-parser "^1.1.3"
     tslib "^2.3.1"
 
+"@wry/context@^0.7.0":
+  version "0.7.0"
+  resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.7.0.tgz#be88e22c0ddf62aeb0ae9f95c3d90932c619a5c8"
+  integrity sha512-LcDAiYWRtwAoSOArfk7cuYvFXytxfVrdX7yxoUmK7pPITLk5jYh2F8knCwS7LjgYL8u1eidPlKKV6Ikqq0ODqQ==
+  dependencies:
+    tslib "^2.3.0"
+
+"@wry/equality@^0.5.0":
+  version "0.5.3"
+  resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.3.tgz#fafebc69561aa2d40340da89fa7dc4b1f6fb7831"
+  integrity sha512-avR+UXdSrsF2v8vIqIgmeTY0UR91UT+IyablCyKe/uk22uOJ8fusKZnH9JH9e1/EtLeNJBtagNmL3eJdnOV53g==
+  dependencies:
+    tslib "^2.3.0"
+
+"@wry/trie@^0.3.0":
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.3.2.tgz#a06f235dc184bd26396ba456711f69f8c35097e6"
+  integrity sha512-yRTyhWSls2OY/pYLfwff867r8ekooZ4UI+/gxot5Wj8EFwSf2rG+n+Mo/6LoLQm1TKA4GRj2+LCpbfS937dClQ==
+  dependencies:
+    tslib "^2.3.0"
+
 "@xtuc/ieee754@^1.2.0":
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
@@ -7262,7 +7302,7 @@ enhanced-resolve@^4.3.0:
     memory-fs "^0.5.0"
     tapable "^1.0.0"
 
-enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0:
+enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0:
   version "5.12.0"
   resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634"
   integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==
@@ -8598,7 +8638,7 @@ graphql-request@^5.0.0:
     extract-files "^9.0.0"
     form-data "^3.0.0"
 
-graphql-tag@^2.11.0, graphql-tag@^2.9.2:
+graphql-tag@^2.11.0, graphql-tag@^2.12.6, graphql-tag@^2.9.2:
   version "2.12.6"
   resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1"
   integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==
@@ -11987,6 +12027,14 @@ opn@^5.5.0:
   dependencies:
     is-wsl "^1.1.0"
 
+optimism@^0.16.1:
+  version "0.16.2"
+  resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.16.2.tgz#519b0c78b3b30954baed0defe5143de7776bf081"
+  integrity sha512-zWNbgWj+3vLEjZNIh/okkY2EUfX+vB9TJopzIZwT1xxaMqC5hRLLraePod4c5n4He08xuXNH+zhKFFCu390wiQ==
+  dependencies:
+    "@wry/context" "^0.7.0"
+    "@wry/trie" "^0.3.0"
+
 optimize-css-assets-webpack-plugin@5.0.4:
   version "5.0.4"
   resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90"
@@ -14215,6 +14263,11 @@ resolve@^2.0.0-next.4:
     path-parse "^1.0.7"
     supports-preserve-symlinks-flag "^1.0.0"
 
+response-iterator@^0.2.6:
+  version "0.2.6"
+  resolved "https://registry.yarnpkg.com/response-iterator/-/response-iterator-0.2.6.tgz#249005fb14d2e4eeb478a3f735a28fd8b4c9f3da"
+  integrity sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==
+
 restore-cursor@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
@@ -15370,6 +15423,11 @@ swap-case@^2.0.2:
   dependencies:
     tslib "^2.0.3"
 
+symbol-observable@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205"
+  integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==
+
 symbol-tree@^3.2.4:
   version "3.2.4"
   resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
@@ -15660,6 +15718,13 @@ tryer@^1.0.1:
   resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
   integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
 
+ts-invariant@^0.10.3:
+  version "0.10.3"
+  resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.10.3.tgz#3e048ff96e91459ffca01304dbc7f61c1f642f6c"
+  integrity sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==
+  dependencies:
+    tslib "^2.1.0"
+
 ts-loader@^9.4.2:
   version "9.4.2"
   resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.2.tgz#80a45eee92dd5170b900b3d00abcfa14949aeb78"
@@ -15699,6 +15764,15 @@ ts-pnp@1.2.0, ts-pnp@^1.1.6:
   resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
   integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==
 
+tsconfig-paths-webpack-plugin@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.0.tgz#84008fc3e3e0658fdb0262758b07b4da6265ff1a"
+  integrity sha512-fw/7265mIWukrSHd0i+wSwx64kYUSAKPfxRDksjKIYTxSAp9W9/xcZVBF4Kl0eqQd5eBpAQ/oQrc5RyM/0c1GQ==
+  dependencies:
+    chalk "^4.1.0"
+    enhanced-resolve "^5.7.0"
+    tsconfig-paths "^4.0.0"
+
 tsconfig-paths@^3.14.1:
   version "3.14.1"
   resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
@@ -15709,6 +15783,15 @@ tsconfig-paths@^3.14.1:
     minimist "^1.2.6"
     strip-bom "^3.0.0"
 
+tsconfig-paths@^4.0.0:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz#4819f861eef82e6da52fb4af1e8c930a39ed979a"
+  integrity sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==
+  dependencies:
+    json5 "^2.2.2"
+    minimist "^1.2.6"
+    strip-bom "^3.0.0"
+
 tslib@^1.8.1:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@@ -17115,6 +17198,18 @@ yocto-queue@^0.1.0:
   resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
   integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
 
+zen-observable-ts@^1.2.5:
+  version "1.2.5"
+  resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58"
+  integrity sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==
+  dependencies:
+    zen-observable "0.8.15"
+
+zen-observable@0.8.15:
+  version "0.8.15"
+  resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15"
+  integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
+
 zwitch@^1.0.0:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"