Browse Source

Add operations group support to working groups view, proposals and tokenomics

Edvin 3 years ago
parent
commit
bebd32f1c4

+ 10 - 1
pioneer/packages/joy-proposals/src/forms/GenericWorkingGroupProposalForm.tsx

@@ -45,7 +45,16 @@ export type FormInnerProps = ProposalFormInnerProps<FormContainerProps, FormValu
 
 const availableGroupsOptions = Object.keys(WorkingGroupDef)
   .filter((wgKey) => wgKey !== 'Gateway') // Gateway group not yet supported!
-  .map((wgKey) => ({ text: wgKey + ' Working Group', value: wgKey }));
+  .map((wgKey) => {
+    let text = wgKey + "Working Group";
+
+    if(wgKey.toLowerCase().includes("operations")) {
+      const workingGroupType = wgKey.slice("operations".length);
+      text = `Operations Working Group ${workingGroupType}`;
+    }
+
+    return { text, value: wgKey };
+  });
 
 export const GenericWorkingGroupProposalForm: React.FunctionComponent<FormInnerProps> = (props) => {
   const {

+ 9 - 3
pioneer/packages/joy-roles/src/tabs/WorkingGroup.controller.tsx

@@ -9,14 +9,18 @@ import { AvailableGroups } from '../working_groups';
 import { WorkingGroupMembership,
   ContentCurators,
   StorageProviders,
-  OperationsGroup } from './WorkingGroup';
+  OperationsGroupAlpha,
+  OperationsGroupBeta,
+  OperationsGroupGamma } from './WorkingGroup';
 
 import styled from 'styled-components';
 
 type State = {
   curators?: WorkingGroupMembership;
   storageProviders?: WorkingGroupMembership;
-  operationsGroup?: WorkingGroupMembership;
+  operationsGroupAlpha?: WorkingGroupMembership;
+  operationsGroupBeta?: WorkingGroupMembership;
+  operationsGroupGamma?: WorkingGroupMembership;
 }
 
 export class WorkingGroupsController extends Controller<State, ITransport> {
@@ -56,7 +60,9 @@ export const WorkingGroupsView = View<WorkingGroupsController, State>(
     <WorkingGroupsOverview>
       <ContentCurators {...state.curators}/>
       <StorageProviders {...state.storageProviders}/>
-      <OperationsGroup {...state.operationsGroup}/>
+      <OperationsGroupAlpha {...state.operationsGroupAlpha}/>
+      <OperationsGroupBeta {...state.operationsGroupBeta}/>
+      <OperationsGroupGamma {...state.operationsGroupGamma}/>
     </WorkingGroupsOverview>
   )
 );

+ 27 - 2
pioneer/packages/joy-roles/src/tabs/WorkingGroup.tsx

@@ -73,6 +73,11 @@ type GroupOverviewProps = GroupOverviewOuterProps & {
   customBecomeLeadDesc?: string;
 }
 
+
+interface OperationsGroupProps extends GroupOverviewOuterProps{
+  group: WorkingGroups;
+}
+
 const GroupOverview = Loadable<GroupOverviewProps>(
   ['workers', 'leadStatus'],
   ({
@@ -142,9 +147,8 @@ export const StorageProviders = (props: GroupOverviewOuterProps) => (
   />
 );
 
-export const OperationsGroup = (props: GroupOverviewOuterProps) => (
+export const OperationsGroup = (props: OperationsGroupProps) => (
   <GroupOverview
-    group={WorkingGroups.Operations}
     description={
       <span>
         {"Operations Working Group encompases all the activites that don't require privilages on chain, for example:"}
@@ -159,6 +163,27 @@ export const OperationsGroup = (props: GroupOverviewOuterProps) => (
   />
 );
 
+export const OperationsGroupAlpha = (props: GroupOverviewOuterProps) => (
+  <OperationsGroup
+    group={WorkingGroups.OperationsAlpha}
+    {...props}
+  />
+);
+
+export const OperationsGroupBeta = (props: GroupOverviewOuterProps) => (
+  <OperationsGroup
+    group={WorkingGroups.OperationsBeta}
+    {...props}
+  />
+);
+
+export const OperationsGroupGamma = (props: GroupOverviewOuterProps) => (
+  <OperationsGroup
+    group={WorkingGroups.OperationsGamma}
+    {...props}
+  />
+);
+
 const LeadSection = styled.div`
   margin-top: 1rem;
 `;

+ 3 - 1
pioneer/packages/joy-roles/src/transport.substrate.ts

@@ -52,7 +52,9 @@ type StakePair<T = Balance> = {
 const apiModuleByGroup = {
   [WorkingGroups.StorageProviders]: 'storageWorkingGroup',
   [WorkingGroups.ContentCurators]: 'contentDirectoryWorkingGroup',
-  [WorkingGroups.Operations]: 'operationsWorkingGroup'
+  [WorkingGroups.OperationsAlpha]: 'operationsWorkingGroupAlpha',
+  [WorkingGroups.OperationsBeta]: 'operationsWorkingGroupBeta',
+  [WorkingGroups.OperationsGamma]: 'operationsWorkingGroupGamma'
 } as const;
 
 export class Transport extends BaseTransport implements ITransport {

+ 9 - 3
pioneer/packages/joy-roles/src/working_groups.ts

@@ -1,17 +1,23 @@
 export enum WorkingGroups {
   ContentCurators = 'curators',
   StorageProviders = 'storageProviders',
-  Operations = 'operationsGroup'
+  OperationsAlpha = 'operationsGroupAlpha',
+  OperationsBeta = 'operationsGroupBeta',
+  OperationsGamma = 'operationsGroupGamma'
 }
 
 export const AvailableGroups: readonly WorkingGroups[] = [
   WorkingGroups.ContentCurators,
   WorkingGroups.StorageProviders,
-  WorkingGroups.Operations
+  WorkingGroups.OperationsAlpha,
+  WorkingGroups.OperationsBeta,
+  WorkingGroups.OperationsGamma
 ] as const;
 
 export const workerRoleNameByGroup: { [key in WorkingGroups]: string } = {
   [WorkingGroups.ContentCurators]: 'Content Curator',
   [WorkingGroups.StorageProviders]: 'Storage Provider',
-  [WorkingGroups.Operations]: 'Operations Group Worker'
+  [WorkingGroups.OperationsAlpha]: 'Operations Group Alpha Worker',
+  [WorkingGroups.OperationsBeta]: 'Operations Group Beta Worker',
+  [WorkingGroups.OperationsGamma]: 'Operations Group Gamma Worker'
 };

+ 77 - 21
pioneer/packages/joy-tokenomics/src/Overview/SpendingAndStakeDistributionTable.tsx

@@ -121,7 +121,7 @@ const SpendingAndStakeTableRow: React.FC<{
   );
 };
 
-const WORKING_GROUPS = ['storageProviders', 'contentCurators', 'operations'] as const;
+const WORKING_GROUPS = ['storageProviders', 'contentCurators', 'operationsAlpha', 'operationsBeta', 'operationsGamma'] as const;
 
 type TokenomicsGroup =
   'validators' |
@@ -143,6 +143,14 @@ const SpendingAndStakeDistributionTable: React.FC<{data?: TokenomicsData; status
     }
   };
 
+  const renderOperationsHelpText = (groupName: string, isLead?: boolean) => {
+    if(isLead) {
+      return `Current ${groupName} Lead, and their projected reward and stake.`
+    }
+
+    return `The current ${groupName} members, and the sum of their projected rewards and stakes.`
+  }
+
   return (
     <StyledTable divideColumnsAt={[3, 6, 9]} celled>
       <Table.Header>
@@ -233,28 +241,76 @@ const SpendingAndStakeDistributionTable: React.FC<{data?: TokenomicsData; status
           color={COLORS.CURATOR_LEAD}
         />
         <SpendingAndStakeTableRow
-          role='Operations'
-          helpContent='The current Operations members, and the sum of their projected rewards and stakes.'
-          numberOfActors={data && `${data.operations.number}`}
-          groupEarning={data && `${Math.round(data.operations.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('operations', 'rewardsPerWeek')}
-          earningShare={data && `${round(data.operations.rewardsShare * 100)}`}
-          groupStake={data && `${data.operations.totalStake}`}
-          groupStakeDollar={displayStatusData('operations', 'totalStake')}
-          stakeShare={data && `${round(data.operations.stakeShare * 100)}`}
-          color={COLORS.OPERATIONS}
+          role='Operations Alpha'
+          helpContent={renderOperationsHelpText("Operations Group Alpha")}
+          numberOfActors={data && `${data.operationsAlpha.number}`}
+          groupEarning={data && `${Math.round(data.operationsAlpha.rewardsPerWeek)}`}
+          groupEarningDollar={displayStatusData('operationsAlpha', 'rewardsPerWeek')}
+          earningShare={data && `${round(data.operationsAlpha.rewardsShare * 100)}`}
+          groupStake={data && `${data.operationsAlpha.totalStake}`}
+          groupStakeDollar={displayStatusData('operationsAlpha', 'totalStake')}
+          stakeShare={data && `${round(data.operationsAlpha.stakeShare * 100)}`}
+          color={COLORS.OPERATIONS_ALPHA}
+        />
+        <SpendingAndStakeTableRow
+          role='Operations Alpha Lead'
+          helpContent={renderOperationsHelpText("Operations Group Alpha", true)}
+          numberOfActors={data && `${data.operationsAlpha.lead.number}`}
+          groupEarning={data && `${Math.round(data.operationsAlpha.lead.rewardsPerWeek)}`}
+          groupEarningDollar={displayStatusData('operationsAlpha', 'rewardsPerWeek', true)}
+          earningShare={data && `${round(data.operationsAlpha.lead.rewardsShare * 100)}`}
+          groupStake={data && `${data.operationsAlpha.lead.totalStake}`}
+          groupStakeDollar={displayStatusData('operationsAlpha', 'totalStake', true)}
+          stakeShare={data && `${round(data.operationsAlpha.lead.stakeShare * 100)}`}
+          color={COLORS.OPERATIONS_ALPHA_LEAD}
+        />
+        <SpendingAndStakeTableRow
+          role='Operations Beta'
+          helpContent={renderOperationsHelpText("Operations Group Beta")}
+          numberOfActors={data && `${data.operationsBeta.number}`}
+          groupEarning={data && `${Math.round(data.operationsBeta.rewardsPerWeek)}`}
+          groupEarningDollar={displayStatusData('operationsBeta', 'rewardsPerWeek')}
+          earningShare={data && `${round(data.operationsBeta.rewardsShare * 100)}`}
+          groupStake={data && `${data.operationsBeta.totalStake}`}
+          groupStakeDollar={displayStatusData('operationsBeta', 'totalStake')}
+          stakeShare={data && `${round(data.operationsBeta.stakeShare * 100)}`}
+          color={COLORS.OPERATIONS_BETA}
+        />
+        <SpendingAndStakeTableRow
+          role='Operations Beta Lead'
+          helpContent={renderOperationsHelpText("Operations Group Beta", true)}
+          numberOfActors={data && `${data.operationsBeta.lead.number}`}
+          groupEarning={data && `${Math.round(data.operationsBeta.lead.rewardsPerWeek)}`}
+          groupEarningDollar={displayStatusData('operationsBeta', 'rewardsPerWeek', true)}
+          earningShare={data && `${round(data.operationsBeta.lead.rewardsShare * 100)}`}
+          groupStake={data && `${data.operationsBeta.lead.totalStake}`}
+          groupStakeDollar={displayStatusData('operationsBeta', 'totalStake', true)}
+          stakeShare={data && `${round(data.operationsBeta.lead.stakeShare * 100)}`}
+          color={COLORS.OPERATIONS_BETA_LEAD}
+        />
+        <SpendingAndStakeTableRow
+          role='Operations Gamma'
+          helpContent={renderOperationsHelpText("Operations Group Gamma")}
+          numberOfActors={data && `${data.operationsGamma.number}`}
+          groupEarning={data && `${Math.round(data.operationsGamma.rewardsPerWeek)}`}
+          groupEarningDollar={displayStatusData('operationsGamma', 'rewardsPerWeek')}
+          earningShare={data && `${round(data.operationsGamma.rewardsShare * 100)}`}
+          groupStake={data && `${data.operationsGamma.totalStake}`}
+          groupStakeDollar={displayStatusData('operationsGamma', 'totalStake')}
+          stakeShare={data && `${round(data.operationsGamma.stakeShare * 100)}`}
+          color={COLORS.OPERATIONS_GAMMA}
         />
         <SpendingAndStakeTableRow
-          role='Operations Lead'
-          helpContent='Current Operations Lead, and their projected reward and stake.'
-          numberOfActors={data && `${data.operations.lead.number}`}
-          groupEarning={data && `${Math.round(data.operations.lead.rewardsPerWeek)}`}
-          groupEarningDollar={displayStatusData('operations', 'rewardsPerWeek', true)}
-          earningShare={data && `${round(data.operations.lead.rewardsShare * 100)}`}
-          groupStake={data && `${data.operations.lead.totalStake}`}
-          groupStakeDollar={displayStatusData('operations', 'totalStake', true)}
-          stakeShare={data && `${round(data.operations.lead.stakeShare * 100)}`}
-          color={COLORS.OPERATIONS_LEAD}
+          role='Operations Gamma Lead'
+          helpContent={renderOperationsHelpText("Operations Group Gamma", true)}
+          numberOfActors={data && `${data.operationsGamma.lead.number}`}
+          groupEarning={data && `${Math.round(data.operationsGamma.lead.rewardsPerWeek)}`}
+          groupEarningDollar={displayStatusData('operationsGamma', 'rewardsPerWeek', true)}
+          earningShare={data && `${round(data.operationsGamma.lead.rewardsShare * 100)}`}
+          groupStake={data && `${data.operationsGamma.lead.totalStake}`}
+          groupStakeDollar={displayStatusData('operationsGamma', 'totalStake', true)}
+          stakeShare={data && `${round(data.operationsGamma.lead.stakeShare * 100)}`}
+          color={COLORS.OPERATIONS_GAMMA_LEAD}
         />
         <SpendingAndStakeTableRow
           role='TOTAL'

+ 44 - 12
pioneer/packages/joy-tokenomics/src/Overview/TokenomicsCharts.tsx

@@ -56,13 +56,29 @@ const TokenomicsCharts: React.FC<{data?: TokenomicsData; className?: string}> =
             label: 'Content Curators Lead',
             value: data.contentCurators.lead.rewardsShare * 100
           }, {
-            colors: [COLORS.OPERATIONS],
-            label: 'Operations',
-            value: data.operations.rewardsShare * 100
+            colors: [COLORS.OPERATIONS_ALPHA],
+            label: 'Operations Alpha',
+            value: data.operationsAlpha.rewardsShare * 100
           }, {
-            colors: [COLORS.OPERATIONS_LEAD],
-            label: 'Operations Lead',
-            value: data.operations.lead.rewardsShare * 100
+            colors: [COLORS.OPERATIONS_ALPHA_LEAD],
+            label: 'Operations Alpha Lead',
+            value: data.operationsAlpha.lead.rewardsShare * 100
+          }, {
+            colors: [COLORS.OPERATIONS_BETA],
+            label: 'Operations Beta',
+            value: data.operationsBeta.rewardsShare * 100
+          }, {
+            colors: [COLORS.OPERATIONS_BETA_LEAD],
+            label: 'Operations Beta Lead',
+            value: data.operationsBeta.lead.rewardsShare * 100
+          }, {
+            colors: [COLORS.OPERATIONS_GAMMA],
+            label: 'Operations Gamma',
+            value: data.operationsGamma.rewardsShare * 100
+          }, {
+            colors: [COLORS.OPERATIONS_GAMMA_LEAD],
+            label: 'Operations Gamma Lead',
+            value: data.operationsGamma.lead.rewardsShare * 100
           }
           ]} />
         <Label as='div'>
@@ -97,13 +113,29 @@ const TokenomicsCharts: React.FC<{data?: TokenomicsData; className?: string}> =
             label: 'Content Curators Lead',
             value: data.contentCurators.lead.stakeShare * 100
           }, {
-            colors: [COLORS.OPERATIONS],
-            label: 'Operations',
-            value: data.operations.stakeShare * 100
+            colors: [COLORS.OPERATIONS_ALPHA],
+            label: 'Operations Alpha',
+            value: data.operationsAlpha.stakeShare * 100
+          }, {
+            colors: [COLORS.OPERATIONS_ALPHA_LEAD],
+            label: 'Operations Alpha Lead',
+            value: data.operationsAlpha.lead.stakeShare * 100
+          }, {
+            colors: [COLORS.OPERATIONS_BETA],
+            label: 'Operations Beta',
+            value: data.operationsBeta.stakeShare * 100
+          }, {
+            colors: [COLORS.OPERATIONS_BETA_LEAD],
+            label: 'Operations Beta Lead',
+            value: data.operationsBeta.lead.stakeShare * 100
+          }, {
+            colors: [COLORS.OPERATIONS_GAMMA],
+            label: 'Operations Gamma',
+            value: data.operationsGamma.stakeShare * 100
           }, {
-            colors: [COLORS.OPERATIONS_LEAD],
-            label: 'Operations Lead',
-            value: data.operations.lead.stakeShare * 100
+            colors: [COLORS.OPERATIONS_GAMMA_LEAD],
+            label: 'Operations Gamma Lead',
+            value: data.operationsGamma.lead.stakeShare * 100
           }
           ]} />
         <Label as='div'>

+ 6 - 2
pioneer/packages/joy-tokenomics/src/Overview/index.tsx

@@ -45,8 +45,12 @@ const COLORS = {
   STORAGE_LEAD: '#cddc39',
   CONTENT_CURATOR: '#8bc34a',
   CURATOR_LEAD: '#4caf50',
-  OPERATIONS: '#009688',
-  OPERATIONS_LEAD: '#00bcd4'
+  OPERATIONS_ALPHA: '#009688',
+  OPERATIONS_ALPHA_LEAD: '#00bcd4',
+  OPERATIONS_BETA: '#03a9f4',
+  OPERATIONS_BETA_LEAD: '#2196f3',
+  OPERATIONS_GAMMA: '#3f51b5',
+  OPERATIONS_GAMMA_LEAD: '#673ab7'
 };
 
 const Overview: React.FC = () => {

+ 3 - 1
pioneer/packages/joy-utils/src/consts/workingGroups.ts

@@ -2,6 +2,8 @@ import { WorkingGroupKey } from '@joystream/types/common';
 export const apiModuleByGroup: { [k in WorkingGroupKey]: string } = {
   Storage: 'storageWorkingGroup',
   Content: 'contentDirectoryWorkingGroup',
-  Operations: 'operationsWorkingGroup',
+  OperationsAlpha: 'operationsWorkingGroupAlpha',
+  OperationsBeta: 'operationsWorkingGroupBeta',
+  OperationsGamma: 'operationsWorkingGroupGamma',
   Gateway: 'gatewayWorkingGroup'
 };

+ 6 - 2
pioneer/packages/joy-utils/src/transport/tokenomics.ts

@@ -228,7 +228,9 @@ export default class TokenomicsTransport extends BaseTransport {
     const workingGroupsData = {
       storageProviders: await this.getWorkingGroupData('Storage'),
       curators: await this.getWorkingGroupData('Content'),
-      operations: await this.getWorkingGroupData('Operations')
+      operationsAlpha: await this.getWorkingGroupData('OperationsAlpha'),
+      operationsBeta: await this.getWorkingGroupData('OperationsBeta'),
+      operationsGamma: await this.getWorkingGroupData('OperationsGamma')
     };
     const { numberOfValidators, numberOfNominators, totalValidatorStake, validatorRewardsPerWeek, totalIssuance } =
       await this.getValidatorData();
@@ -293,7 +295,9 @@ export default class TokenomicsTransport extends BaseTransport {
       },
       storageProviders: resolveGroupData(workingGroupsData.storageProviders),
       contentCurators: resolveGroupData(workingGroupsData.curators),
-      operations: resolveGroupData(workingGroupsData.operations)
+      operationsAlpha: resolveGroupData(workingGroupsData.operationsAlpha),
+      operationsBeta: resolveGroupData(workingGroupsData.operationsBeta),
+      operationsGamma: resolveGroupData(workingGroupsData.operationsGamma)
     };
   }
 }

+ 3 - 1
pioneer/packages/joy-utils/src/types/tokenomics.ts

@@ -37,7 +37,9 @@ export type TokenomicsData = {
   };
   storageProviders: WorkingGroupTokenomicsData;
   contentCurators: WorkingGroupTokenomicsData;
-  operations: WorkingGroupTokenomicsData;
+  operationsAlpha: WorkingGroupTokenomicsData;
+  operationsBeta: WorkingGroupTokenomicsData;
+  operationsGamma: WorkingGroupTokenomicsData;
 }
 
 export type StatusServerData = {

+ 3 - 1
types/src/common.ts

@@ -109,7 +109,9 @@ export class InputValidationLengthConstraint
 export const WorkingGroupDef = {
   Storage: Null,
   Content: Null,
-  Operations: Null,
+  OperationsAlpha: Null,
+  OperationsBeta: Null,
+  OperationsGamma: Null,
   Gateway: Null,
 } as const
 export type WorkingGroupKey = keyof typeof WorkingGroupDef