opening.ts 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
  2. import { displayTable, displayCollapsedRow, displayHeader } from '../../helpers/display'
  3. import _ from 'lodash'
  4. import { OpeningStatus, GroupOpeningStage, GroupOpeningStakes, UnstakingPeriodsKey } from '../../Types'
  5. import { StakingAmountLimitModeKeys, StakingPolicy } from '@joystream/types/hiring'
  6. import { formatBalance } from '@polkadot/util'
  7. import chalk from 'chalk'
  8. export default class WorkingGroupsOpening extends WorkingGroupsCommandBase {
  9. static description = 'Shows an overview of given working group opening by Working Group Opening ID'
  10. static args = [
  11. {
  12. name: 'wgOpeningId',
  13. required: true,
  14. description: 'Working Group Opening ID',
  15. },
  16. ]
  17. static flags = {
  18. ...WorkingGroupsCommandBase.flags,
  19. }
  20. stageColumns(stage: GroupOpeningStage) {
  21. const { status, date, block } = stage
  22. const statusTimeHeader = status === OpeningStatus.WaitingToBegin ? 'Starts at' : 'Last status change'
  23. return {
  24. Stage: _.startCase(status),
  25. [statusTimeHeader]:
  26. date && block
  27. ? `~ ${date.toLocaleTimeString()} ${date.toLocaleDateString()} (#${block})`
  28. : (block && `#${block}`) || '?',
  29. }
  30. }
  31. formatStake(stake: StakingPolicy | undefined) {
  32. if (!stake) return 'NONE'
  33. const { amount, amount_mode: amountMode } = stake
  34. return amountMode.type === StakingAmountLimitModeKeys.AtLeast
  35. ? `>= ${formatBalance(amount)}`
  36. : `== ${formatBalance(amount)}`
  37. }
  38. stakeColumns(stakes: GroupOpeningStakes) {
  39. const { role, application } = stakes
  40. return {
  41. 'Application stake': this.formatStake(application),
  42. 'Role stake': this.formatStake(role),
  43. }
  44. }
  45. async run() {
  46. const { args } = this.parse(WorkingGroupsOpening)
  47. const opening = await this.getApi().groupOpening(this.group, parseInt(args.wgOpeningId))
  48. displayHeader('Human readable text')
  49. this.jsonPrettyPrint(opening.opening.human_readable_text.toString())
  50. displayHeader('Opening details')
  51. const openingRow = {
  52. 'WG Opening ID': opening.wgOpeningId,
  53. 'Opening ID': opening.openingId,
  54. Type: opening.type.type,
  55. ...this.stageColumns(opening.stage),
  56. ...this.stakeColumns(opening.stakes),
  57. }
  58. displayCollapsedRow(openingRow)
  59. displayHeader('Unstaking periods')
  60. const periodsRow: { [k: string]: string } = {}
  61. for (const key of Object.keys(opening.unstakingPeriods).sort()) {
  62. const displayKey = _.startCase(key) + ': '
  63. periodsRow[displayKey] = opening.unstakingPeriods[key as UnstakingPeriodsKey].toLocaleString() + ' blocks'
  64. }
  65. displayCollapsedRow(periodsRow)
  66. displayHeader(`Applications (${opening.applications.length})`)
  67. const applicationsRows = opening.applications.map((a) => ({
  68. 'WG appl. ID': a.wgApplicationId,
  69. 'Appl. ID': a.applicationId,
  70. Member: a.member?.handle.toString() || chalk.red('NONE'),
  71. Stage: a.stage,
  72. 'Appl. stake': a.stakes.application,
  73. 'Role stake': a.stakes.role,
  74. 'Total stake': Object.values(a.stakes).reduce((a, b) => a + b),
  75. }))
  76. displayTable(applicationsRows, 5)
  77. }
  78. }