Ver código fonte

Merge pull request #640 from Lezek123/nicaea-types

Update @joystream/types for Nicaea
Mokhtar Naamani 4 anos atrás
pai
commit
f61a8045ff

+ 4 - 3
pioneer/packages/joy-forum/src/Context.tsx

@@ -2,7 +2,8 @@
 // NOTE: The purpose of this context is to immitate a Substrate storage for the forum until it's implemented as a substrate runtime module.
 
 import React, { useReducer, createContext, useContext } from 'react';
-import { Category, Thread, Reply, ModerationAction, BlockchainTimestamp } from '@joystream/types/forum';
+import { Category, Thread, Reply, ModerationAction } from '@joystream/types/forum';
+import { BlockAndTime } from '@joystream/types/media';
 import { Option, Text, GenericAccountId } from '@polkadot/types';
 
 type CategoryId = number;
@@ -220,7 +221,7 @@ function reducer (state: ForumState, action: ForumAction): ForumState {
 
       const thread = threadById.get(id) as Thread;
       const moderation = new ModerationAction({
-        moderated_at: BlockchainTimestamp.newEmpty(),
+        moderated_at: BlockAndTime.newEmpty(),
         moderator_id: new GenericAccountId(moderator),
         rationale: new Text(rationale)
       });
@@ -285,7 +286,7 @@ function reducer (state: ForumState, action: ForumAction): ForumState {
 
       const reply = replyById.get(id) as Reply;
       const moderation = new ModerationAction({
-        moderated_at: BlockchainTimestamp.newEmpty(),
+        moderated_at: BlockAndTime.newEmpty(),
         moderator_id: new GenericAccountId(moderator),
         rationale: new Text(rationale)
       });

+ 1 - 1
pioneer/packages/joy-roles/src/tabs/Admin.controller.tsx

@@ -689,7 +689,7 @@ export class AdminController extends Controller<State, ITransport> {
         title = (hrt).job.title;
       }
 
-      this.state.openings.set(openingId.toNumber(), {
+      this.state.openings.set(i, {
         openingId: openingId.toNumber(),
         curatorId: i,
         applications: new Array<application>(),

+ 10 - 0
types/.editorconfig

@@ -0,0 +1,10 @@
+root = true
+[*]
+indent_style=space
+indent_size=2
+tab_width=2
+end_of_line=lf
+charset=utf-8
+trim_trailing_whitespace=true
+max_line_length=120
+insert_final_newline=true

+ 321 - 0
types/src/bureaucracy/index.ts

@@ -0,0 +1,321 @@
+import { getTypeRegistry, Bytes, BTreeMap, Option, Enum } from '@polkadot/types';
+import { u16, Null } from '@polkadot/types/primitive';
+import { AccountId, BlockNumber } from '@polkadot/types/interfaces';
+import { MemberId, ActorId } from '../members';
+import { ApplicationId, OpeningId, ApplicationRationingPolicy, StakingPolicy } from '../hiring';
+import { RewardRelationshipId } from '../recurring-rewards';
+import { StakeId } from '../stake';
+import { JoyStruct } from '../JoyStruct';
+import { BTreeSet } from '../';
+
+export type ILead = {
+  member_id: MemberId,
+  role_account_id: AccountId
+};
+
+// This type is also defined in /content-workig-group (and those are incosistent), but here
+// it is beeing registered as "LeadOf" (which is an alias used by the runtime bureaucracy module),
+// so it shouldn't cause any conflicts)
+export class Lead extends JoyStruct<ILead> {
+  constructor (value?: ILead) {
+    super({
+      member_id: MemberId,
+      role_account_id: "AccountId"
+    }, value);
+  }
+
+  get member_id(): MemberId {
+    return this.getField<MemberId>('member_id')
+  }
+
+  get role_account_id(): AccountId {
+    return this.getField<AccountId>('role_account_id')
+  }
+};
+
+export class WorkerApplicationId extends ApplicationId { };
+
+export class WorkerOpeningId extends OpeningId { };
+
+export class RationaleText extends Bytes { };
+
+export type IWorkerApplication = {
+  role_account: AccountId,
+  worker_opening_id: WorkerOpeningId,
+  member_id: MemberId,
+  application_id: ApplicationId
+};
+
+export class WorkerApplication extends JoyStruct<IWorkerApplication> {
+  constructor (value?: IWorkerApplication) {
+    super({
+      role_account: "AccountId",
+      worker_opening_id: WorkerOpeningId,
+      member_id: MemberId,
+      application_id: ApplicationId
+    }, value);
+  }
+
+  get role_account(): AccountId {
+    return this.getField<AccountId>('role_account');
+  }
+
+  get worker_opening_id(): WorkerOpeningId {
+    return this.getField<WorkerOpeningId>('worker_opening_id');
+  }
+
+  get member_id(): MemberId {
+    return this.getField<MemberId>('member_id');
+  }
+
+  get application_id(): ApplicationId {
+    return this.getField<ApplicationId>('application_id');
+  }
+}
+
+export class WorkerId extends ActorId { };
+
+export class StorageProviderId extends WorkerId { };
+
+export class WorkerApplicationIdSet extends BTreeSet.with(WorkerApplicationId) { };
+
+export class WorkerApplicationIdToWorkerIdMap extends BTreeMap.with(WorkerApplicationId, WorkerId) { };
+
+
+export type IWorkerRoleStakeProfile = {
+  stake_id: StakeId,
+  termination_unstaking_period: Option<BlockNumber>,
+  exit_unstaking_period: Option<BlockNumber>,
+};
+
+export class WorkerRoleStakeProfile extends JoyStruct<IWorkerRoleStakeProfile> {
+  constructor (value?: IWorkerRoleStakeProfile) {
+    super({
+      stake_id: StakeId,
+      termination_unstaking_period: "Option<BlockNumber>",
+      exit_unstaking_period: "Option<BlockNumber>"
+    }, value);
+  }
+
+  get stake_id(): StakeId {
+    return this.getField<StakeId>('stake_id');
+  }
+
+  get termination_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('termination_unstaking_period');
+  }
+
+  get exit_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('exit_unstaking_period');
+  }
+}
+
+export type IWorker = {
+  member_id: MemberId,
+  role_account: AccountId,
+  reward_relationship: Option<RewardRelationshipId>,
+  role_stake_profile: Option<WorkerRoleStakeProfile>,
+}
+
+export class Worker extends JoyStruct<IWorker> {
+  constructor (value?: IWorker) {
+    super({
+      member_id: MemberId,
+      role_account: "AccountId",
+      reward_relationship: Option.with(RewardRelationshipId),
+      role_stake_profile: Option.with(WorkerRoleStakeProfile),
+    }, value);
+  }
+
+  get member_id(): MemberId {
+    return this.getField<MemberId>('member_id');
+  }
+
+  get role_account(): AccountId {
+    return this.getField<AccountId>('role_account');
+  }
+
+  get reward_relationship(): Option<RewardRelationshipId> {
+    return this.getField<Option<RewardRelationshipId>>('reward_relationship');
+  }
+
+  get role_stake_profile(): Option<WorkerRoleStakeProfile> {
+    return this.getField<Option<WorkerRoleStakeProfile>>('role_stake_profile');
+  }
+
+  get is_active(): boolean {
+    return !Boolean(this.isEmpty);
+  }
+}
+
+export type ISlashableTerms = {
+  max_count: u16,
+  max_percent_pts_per_time: u16,
+};
+
+// This type is also defined in /content-working-group, but currently both those definitions are identical
+// (I added this defininition here too, because techinicaly those are 2 different types in the runtime.
+// Later the definition in /content-working-group will be removed and we can just register this type here)
+export class SlashableTerms extends JoyStruct<ISlashableTerms> {
+  constructor (value?: ISlashableTerms) {
+    super({
+      max_count: u16,
+      max_percent_pts_per_time: u16,
+    }, value);
+  }
+};
+
+// This type is also defined in /content-working-group (as above)
+export class SlashingTerms extends Enum {
+  constructor (value?: any, index?: number) {
+    super(
+      {
+        Unslashable: Null,
+        Slashable: SlashableTerms,
+      },
+      value, index);
+  }
+};
+
+export type IBureaucracyOpeningPolicyCommitment = {
+  application_rationing_policy: Option<ApplicationRationingPolicy>,
+  max_review_period_length: BlockNumber,
+  application_staking_policy: Option<StakingPolicy>,
+  role_staking_policy: Option<StakingPolicy>,
+  role_slashing_terms: SlashingTerms,
+  fill_opening_successful_applicant_application_stake_unstaking_period: Option<BlockNumber>,
+  fill_opening_failed_applicant_application_stake_unstaking_period: Option<BlockNumber>,
+  fill_opening_failed_applicant_role_stake_unstaking_period: Option<BlockNumber>,
+  terminate_worker_application_stake_unstaking_period: Option<BlockNumber>,
+  terminate_worker_role_stake_unstaking_period: Option<BlockNumber>,
+  exit_worker_role_application_stake_unstaking_period: Option<BlockNumber>,
+  exit_worker_role_stake_unstaking_period: Option<BlockNumber>,
+};
+
+// This type represents OpeningPolicyCommitment defined inside the runtime's bureaucracy module.
+// The only difference between this and the one defined in /content-working-group is in the names of some fields.
+//
+// There is also a minor issue here:
+// Because api metadata still says that ie. the "commitment" argument of "forumBureaucracy.addWorkerOpening" extrinsic
+// is of type "OpeningPolicyCommitment" (not the "BureaucracyOpeningPolicyCommitment" defined here), the CWG's OpeningPolicyCommitment
+// type is used when sending this extrinsic (it has "terminate_curator_role_stake_unstaking_period" field insted
+// of "terminate_worker_role_stake_unstaking_period" etc.).
+// Since both those types are basically the same structs (only filed names are different) nothing seems to break, but it's
+// very fragile atm and any change to this type in bureaucracy module could result in "unsolvable" inconsistencies
+// (this won't be an issue after CWG gets refactored to use the bureaucracy module too)
+export class BureaucracyOpeningPolicyCommitment extends JoyStruct<IBureaucracyOpeningPolicyCommitment> {
+  constructor (value?: BureaucracyOpeningPolicyCommitment) {
+    super({
+      application_rationing_policy: Option.with(ApplicationRationingPolicy),
+      max_review_period_length: "BlockNumber",
+      application_staking_policy: Option.with(StakingPolicy),
+      role_staking_policy: Option.with(StakingPolicy),
+      role_slashing_terms: SlashingTerms,
+      fill_opening_successful_applicant_application_stake_unstaking_period: "Option<BlockNumber>",
+      fill_opening_failed_applicant_application_stake_unstaking_period: "Option<BlockNumber>",
+      fill_opening_failed_applicant_role_stake_unstaking_period: "Option<BlockNumber>",
+      terminate_worker_application_stake_unstaking_period: "Option<BlockNumber>",
+      terminate_worker_role_stake_unstaking_period: "Option<BlockNumber>",
+      exit_worker_role_application_stake_unstaking_period: "Option<BlockNumber>",
+      exit_worker_role_stake_unstaking_period: "Option<BlockNumber>",
+    }, value);
+  }
+
+  get application_rationing_policy(): Option<ApplicationRationingPolicy> {
+    return this.getField<Option<ApplicationRationingPolicy>>('application_rationing_policy')
+  }
+
+  get max_review_period_length(): BlockNumber {
+    return this.getField<BlockNumber>('max_review_period_length')
+  }
+
+  get application_staking_policy(): Option<StakingPolicy> {
+    return this.getField<Option<StakingPolicy>>('application_staking_policy')
+  }
+
+  get role_staking_policy(): Option<StakingPolicy> {
+    return this.getField<Option<StakingPolicy>>('role_staking_policy')
+  }
+
+  get role_slashing_terms(): SlashingTerms {
+    return this.getField<SlashingTerms>('role_slashing_terms')
+  }
+
+  get fill_opening_successful_applicant_application_stake_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('fill_opening_successful_applicant_application_stake_unstaking_period')
+  }
+
+  get fill_opening_failed_applicant_application_stake_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('fill_opening_failed_applicant_application_stake_unstaking_period')
+  }
+
+  get fill_opening_failed_applicant_role_stake_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('fill_opening_failed_applicant_role_stake_unstaking_period')
+  }
+
+  get terminate_worker_application_stake_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('terminate_worker_application_stake_unstaking_period')
+  }
+
+  get terminate_worker_role_stake_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('terminate_worker_role_stake_unstaking_period')
+  }
+
+  get exit_worker_role_application_stake_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('exit_worker_role_application_stake_unstaking_period')
+  }
+
+  get exit_worker_role_stake_unstaking_period(): Option<BlockNumber> {
+    return this.getField<Option<BlockNumber>>('exit_worker_role_stake_unstaking_period')
+  }
+};
+
+export type IWorkerOpening = {
+  opening_id: OpeningId,
+  worker_applications: BTreeSet<WorkerApplicationId>,
+  policy_commitment: BureaucracyOpeningPolicyCommitment,
+}
+
+export class WorkerOpening extends JoyStruct<IWorkerOpening> {
+  constructor (value?: IWorker) {
+    super({
+      opening_id: OpeningId,
+      worker_applications: BTreeSet.with(WorkerApplicationId),
+      policy_commitment: BureaucracyOpeningPolicyCommitment,
+    }, value);
+  }
+
+  get opening_id(): OpeningId {
+    return this.getField<OpeningId>('opening_id');
+  }
+
+  get worker_applications(): BTreeSet<WorkerApplicationId> {
+    return this.getField<BTreeSet<WorkerApplicationId>>('worker_applications');
+  }
+
+  get policy_commitment(): BureaucracyOpeningPolicyCommitment {
+    return this.getField<BureaucracyOpeningPolicyCommitment>('policy_commitment');
+  }
+}
+
+export function registerBureaucracyTypes() {
+  try {
+    getTypeRegistry().register({
+      // Note that it actually HAS TO be "LeadOf" in the runtime,
+      // otherwise there would be conflicts with the current content-workig-group module
+      LeadOf: Lead,
+      RationaleText,
+      WorkerApplication,
+      WorkerApplicationId,
+      WorkerApplicationIdSet,
+      WorkerApplicationIdToWorkerIdMap,
+      WorkerId,
+      WorkerOf: Worker,
+      WorkerOpening,
+      WorkerOpeningId,
+      StorageProviderId
+    });
+  } catch (err) {
+    console.error('Failed to register custom types of bureaucracy module', err);
+  }
+}

+ 15 - 0
types/src/content-working-group/index.ts

@@ -212,6 +212,11 @@ export class CuratorInduction extends JoyStruct<ICuratorInduction> {
     return this.getField<CuratorApplicationId>('curator_application_id')
   }
 
+  // Helper for bureaucracy compatibility
+  get worker_application_id(): CuratorApplicationId {
+    return this.curator_application_id;
+  }
+
   get at_block(): u32 {
     return this.getField<u32>('at_block')
   }
@@ -290,6 +295,11 @@ export class CuratorApplication extends JoyStruct<ICuratorApplication> {
     return this.getField<CuratorOpeningId>('curator_opening_id')
   }
 
+  // Helper for bureaucracy compatibility
+  get worker_opening_id(): CuratorOpeningId {
+    return this.curator_opening_id;
+  }
+
   get member_id(): MemberId {
     return this.getField<MemberId>('member_id')
   }
@@ -467,6 +477,11 @@ export class Lead extends JoyStruct<ILead> {
     return this.getField<GenericAccountId>('role_account')
   }
 
+  // Helper for bureaucracy compatibility
+  get role_account_id(): GenericAccountId {
+    return this.role_account;
+  }
+
   get reward_relationship(): Option<RewardRelationshipId> {
     return this.getField<Option<RewardRelationshipId>>('reward_relationship')
   }

+ 17 - 45
types/src/forum.ts

@@ -1,39 +1,12 @@
 import { getTypeRegistry, bool, u16, u32, u64, Text, Option, Vec as Vector} from '@polkadot/types';
-import { AccountId, Moment, BlockNumber } from '@polkadot/types/interfaces';
+import { AccountId } from '@polkadot/types/interfaces';
 import { GenericAccountId } from '@polkadot/types';
+import { BlockAndTime } from './media';
 
 import { JoyStruct } from './JoyStruct';
 
-// Based on copypasta from joy-media/BlockAndTimeType
-export type BlockchainTimestampType = {
-  block: BlockNumber,
-  time: Moment
-};
-
-// Based on copypasta from joy-media/BlockAndTime
-export class BlockchainTimestamp extends JoyStruct<BlockchainTimestampType> {
-  constructor (value?: BlockchainTimestampType) {
-    super({
-      block: u32, // BlockNumber
-      time: u64, // Moment
-    }, value);
-  }
-
-  get block (): BlockNumber {
-    return this.getField('block');
-  }
-
-  get time (): Moment {
-    return this.getField('time');
-  }
-
-  static newEmpty (): BlockchainTimestamp {
-    return new BlockchainTimestamp({} as BlockchainTimestampType);
-  }
-}
-
 export type ModerationActionType = {
-  moderated_at: BlockchainTimestamp,
+  moderated_at: BlockAndTime,
   moderator_id: AccountId,
   rationale: Text
 };
@@ -41,13 +14,13 @@ export type ModerationActionType = {
 export class ModerationAction extends JoyStruct<ModerationActionType> {
   constructor (value: ModerationActionType) {
     super({
-      moderated_at: BlockchainTimestamp,
+      moderated_at: BlockAndTime,
       moderator_id: GenericAccountId,
       rationale: Text
     }, value);
   }
 
-  get moderated_at (): BlockchainTimestamp {
+  get moderated_at (): BlockAndTime {
     return this.getField('moderated_at');
   }
 
@@ -61,19 +34,19 @@ export class ModerationAction extends JoyStruct<ModerationActionType> {
 }
 
 export type PostTextChangeType = {
-  expired_at: BlockchainTimestamp,
+  expired_at: BlockAndTime,
   text: Text
 };
 
 export class PostTextChange extends JoyStruct<PostTextChangeType> {
   constructor (value: PostTextChangeType) {
     super({
-      expired_at: BlockchainTimestamp,
+      expired_at: BlockAndTime,
       text: Text
     }, value);
   }
 
-  get expired_at (): BlockchainTimestamp {
+  get expired_at (): BlockAndTime {
     return this.getField('expired_at');
   }
 
@@ -154,7 +127,7 @@ export type CategoryType = {
   id: CategoryId,
   title: Text,
   description: Text,
-  created_at: BlockchainTimestamp,
+  created_at: BlockAndTime,
   deleted: bool,
   archived: bool,
   num_direct_subcategories: u32,
@@ -170,7 +143,7 @@ export class Category extends JoyStruct<CategoryType> {
       id: CategoryId,
       title: Text,
       description: Text,
-      created_at: BlockchainTimestamp,
+      created_at: BlockAndTime,
       deleted: bool,
       archived: bool,
       num_direct_subcategories: u32,
@@ -197,7 +170,7 @@ export class Category extends JoyStruct<CategoryType> {
     return this.getString('description');
   }
 
-  get created_at (): BlockchainTimestamp {
+  get created_at (): BlockAndTime {
     return this.getField('created_at');
   }
 
@@ -264,7 +237,7 @@ export type ThreadType = {
   moderation: OptionModerationAction,
   num_unmoderated_posts: u32,
   num_moderated_posts: u32,
-  created_at: BlockchainTimestamp,
+  created_at: BlockAndTime,
   author_id: AccountId
 };
 
@@ -278,7 +251,7 @@ export class Thread extends JoyStruct<ThreadType> {
       moderation: OptionModerationAction,
       num_unmoderated_posts: u32,
       num_moderated_posts: u32,
-      created_at: BlockchainTimestamp,
+      created_at: BlockAndTime,
       author_id: GenericAccountId
     }, value);
   }
@@ -323,7 +296,7 @@ export class Thread extends JoyStruct<ThreadType> {
     return new u32(this.num_unmoderated_posts.add(this.num_moderated_posts));
   }
 
-  get created_at (): BlockchainTimestamp {
+  get created_at (): BlockAndTime {
     return this.getField('created_at');
   }
 
@@ -339,7 +312,7 @@ export type PostType = {
   current_text: Text,
   moderation: OptionModerationAction,
   text_change_history: VecPostTextChange,
-  created_at: BlockchainTimestamp,
+  created_at: BlockAndTime,
   author_id: AccountId
 };
 
@@ -353,7 +326,7 @@ export class Post extends JoyStruct<PostType> {
       current_text: Text,
       moderation: OptionModerationAction,
       text_change_history: VecPostTextChange,
-      created_at: BlockchainTimestamp,
+      created_at: BlockAndTime,
       author_id: GenericAccountId
     }, value);
   }
@@ -390,7 +363,7 @@ export class Post extends JoyStruct<PostType> {
     return this.getField('text_change_history');
   }
 
-  get created_at (): BlockchainTimestamp {
+  get created_at (): BlockAndTime {
     return this.getField('created_at');
   }
 
@@ -441,7 +414,6 @@ export class Reply extends JoyStruct<ReplyType> {
 export function registerForumTypes () {
   try {
     getTypeRegistry().register({
-      BlockchainTimestamp,
       PostTextChange,
       ModerationAction,
       InputValidationLengthConstraint,

+ 1 - 0
types/src/index.ts

@@ -225,4 +225,5 @@ export function registerJoystreamTypes() {
   registerHiringTypes();
   registerContentWorkingGroupTypes();
   registerProposalTypes();
+  require("./bureaucracy").registerBureaucracyTypes();
 }

+ 4 - 0
types/src/media.ts

@@ -51,6 +51,10 @@ export class BlockAndTime extends Struct {
   get time (): Moment {
     return this.get('time') as Moment;
   }
+
+  static newEmpty (): BlockAndTime {
+    return new BlockAndTime({} as BlockAndTime);
+  }
 }
 
 // TODO rename to Draft to Unlisted