Browse Source

Basic opening management - set stage, fill opening

Leszek Wiesner 4 years ago
parent
commit
a58f16db73

+ 2 - 1
cli/src/base/ApiCommandBase.ts

@@ -73,7 +73,6 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase {
     // Prompt for Option<Codec> value
     async promptForOption(typeDef: TypeDef, defaultValue?: Option<Codec>): Promise<Option<Codec>> {
         const subtype = <TypeDef> typeDef.sub; // We assume that Opion always has a single subtype
-
         const confirmed = await this.simplePrompt({
             message: `Do you want to provide the optional ${ this.paramName(typeDef) } parameter?`,
             type: 'confirm',
@@ -81,7 +80,9 @@ export default abstract class ApiCommandBase extends StateAwareCommandBase {
         });
 
         if (confirmed) {
+            this.openIndentGroup();
             const value = await this.promptForParam(subtype.type, subtype.name, defaultValue?.unwrapOr(undefined));
+            this.closeIndentGroup();
             return new Option(subtype.type as any, value);
         }
 

+ 16 - 1
cli/src/base/WorkingGroupsCommandBase.ts

@@ -1,7 +1,7 @@
 import ExitCodes from '../ExitCodes';
 import AccountsCommandBase from './AccountsCommandBase';
 import { flags } from '@oclif/command';
-import { WorkingGroups, AvailableGroups, NamedKeyringPair, GroupLeadWithProfile, GroupMember } from '../Types';
+import { WorkingGroups, AvailableGroups, NamedKeyringPair, GroupLeadWithProfile, GroupMember, GroupOpening, GroupApplication } from '../Types';
 import { apiModuleByGroup } from '../Api';
 import { CLIError } from '@oclif/errors';
 import inquirer from 'inquirer';
@@ -9,6 +9,7 @@ import { ApiMethodInputArg } from './ApiCommandBase';
 import fs from 'fs';
 import path from 'path';
 import _ from 'lodash';
+import { ApplicationStageKeys } from '@joystream/types/lib/hiring';
 
 const DEFAULT_GROUP = WorkingGroups.StorageProviders;
 const DRAFTS_FOLDER = '/opening-drafts';
@@ -73,6 +74,20 @@ export default abstract class WorkingGroupsCommandBase extends AccountsCommandBa
         return groupMembers[choosenWorkerIndex];
     }
 
+    async promptForApplicationsToAccept(opening: GroupOpening): Promise<number[]> {
+        const acceptableApplications = opening.applications.filter(a => a.stage === ApplicationStageKeys.Active);
+        const acceptedApplications = await this.simplePrompt({
+            message: 'Select succesful applicants',
+            type: 'checkbox',
+            choices: acceptableApplications.map(a => ({
+                name: ` ${a.workerApplicationId}: ${a.member?.handle.toString()}`,
+                value: a.workerApplicationId,
+            }))
+        });
+
+        return acceptedApplications;
+    }
+
     async promptForNewOpeningDraftName() {
         let
             draftName: string = '',

+ 51 - 0
cli/src/commands/working-groups/fillOpening.ts

@@ -0,0 +1,51 @@
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
+import _ from 'lodash';
+import { OpeningStatus } from '../../Types';
+import ExitCodes from '../../ExitCodes';
+import { apiModuleByGroup } from '../../Api';
+import { WorkerOpeningId, WorkerApplicationIdSet } from '@joystream/types/lib/working-group';
+import { RewardPolicy } from '@joystream/types/lib/content-working-group';
+
+export default class WorkingGroupsFillOpening extends WorkingGroupsCommandBase {
+    static description = 'Allows filling worker opening that\'s currently in review. Requires lead access.';
+    static args = [
+        {
+            name: 'workerOpeningId',
+            required: true,
+            description: 'Worker Opening ID'
+        },
+    ]
+    static flags = {
+        ...WorkingGroupsCommandBase.flags,
+    };
+
+    async run() {
+        const { args } = this.parse(WorkingGroupsFillOpening);
+
+        const account = await this.getRequiredSelectedAccount();
+        // Lead-only gate
+        await this.getRequiredLead();
+
+        const opening = await this.getApi().groupOpening(this.group, parseInt(args.workerOpeningId));
+
+        if (opening.stage.status !== OpeningStatus.InReview) {
+            this.error('This opening is not in the Review stage!', { exit: ExitCodes.InvalidInput });
+        }
+
+        const applications = await this.promptForApplicationsToAccept(opening);
+        const rewardPolicyOpt = await this.promptForParam(`Option<${RewardPolicy.name}>`, 'RewardPolicy');
+
+        await this.requestAccountDecoding(account);
+
+        await this.sendAndFollowExtrinsic(
+            account,
+            apiModuleByGroup[this.group],
+            'fillWorkerOpening',
+            [
+                new WorkerOpeningId(opening.workerOpeningId),
+                new WorkerApplicationIdSet(applications),
+                rewardPolicyOpt
+            ]
+        );
+    }
+  }

+ 3 - 3
cli/src/commands/working-groups/startAcceptingApplications.ts

@@ -3,10 +3,10 @@ import _ from 'lodash';
 import { OpeningStatus } from '../../Types';
 import ExitCodes from '../../ExitCodes';
 import { apiModuleByGroup } from '../../Api';
-import { createType } from '@polkadot/types';
+import { WorkerOpeningId } from '@joystream/types/lib/working-group';
 
 export default class WorkingGroupsStartAcceptingApplications extends WorkingGroupsCommandBase {
-    static description = 'Changes the status of pending opening to "Accepting applications"';
+    static description = 'Changes the status of pending opening to "Accepting applications". Requires lead access.';
     static args = [
         {
             name: 'workerOpeningId',
@@ -37,7 +37,7 @@ export default class WorkingGroupsStartAcceptingApplications extends WorkingGrou
             account,
             apiModuleByGroup[this.group],
             'acceptWorkerApplications',
-            [ createType('WorkerOpeningId' as any, opening.workerOpeningId) ]
+            [ new WorkerOpeningId(opening.workerOpeningId) ]
         );
     }
   }

+ 43 - 0
cli/src/commands/working-groups/startReviewPeriod.ts

@@ -0,0 +1,43 @@
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
+import _ from 'lodash';
+import { OpeningStatus } from '../../Types';
+import ExitCodes from '../../ExitCodes';
+import { apiModuleByGroup } from '../../Api';
+import { WorkerOpeningId } from '@joystream/types/lib/working-group';
+
+export default class WorkingGroupsStartReviewPeriod extends WorkingGroupsCommandBase {
+    static description = 'Changes the status of active opening to "In review". Requires lead access.';
+    static args = [
+        {
+            name: 'workerOpeningId',
+            required: true,
+            description: 'Worker Opening ID'
+        },
+    ]
+    static flags = {
+        ...WorkingGroupsCommandBase.flags,
+    };
+
+    async run() {
+        const { args } = this.parse(WorkingGroupsStartReviewPeriod);
+
+        const account = await this.getRequiredSelectedAccount();
+        // Lead-only gate
+        await this.getRequiredLead();
+
+        const opening = await this.getApi().groupOpening(this.group, parseInt(args.workerOpeningId));
+
+        if (opening.stage.status !== OpeningStatus.AcceptingApplications) {
+            this.error('This opening is not in "Accepting Applications" stage!', { exit: ExitCodes.InvalidInput });
+        }
+
+        await this.requestAccountDecoding(account);
+
+        await this.sendAndFollowExtrinsic(
+            account,
+            apiModuleByGroup[this.group],
+            'beginWorkerApplicantReview',
+            [ new WorkerOpeningId(opening.workerOpeningId) ]
+        );
+    }
+  }