@riboseinc/paneron-registry-kit 2.0.3 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riboseinc/paneron-registry-kit",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "main": "index.js",
5
5
  "author": "Ribose Inc. <open.source@ribose.com>",
6
6
  "scripts": {
@@ -29,7 +29,7 @@
29
29
  "@emotion/react": "^11.10.6",
30
30
  "@emotion/styled": "^11.10.6",
31
31
  "@riboseinc/isogit-lfs": "0.1.6",
32
- "@riboseinc/paneron-extension-kit": "2.0.1",
32
+ "@riboseinc/paneron-extension-kit": "2.0.2",
33
33
  "@types/js-yaml": "^3.12.5",
34
34
  "@types/node": "^16.11.7",
35
35
  "@types/object-hash": "~3.0.2",
package/types/cr.d.ts CHANGED
@@ -117,7 +117,6 @@ export interface RegisterManagerInput {
117
117
  export declare function hasRegisterManagerInput(val: any): val is RegisterManagerInput;
118
118
  export interface ControlBodyInput {
119
119
  controlBodyNotes: string;
120
- controlBodyDecisionEvent: string;
121
120
  }
122
121
  export declare function hasControlBodyInput(val: any): val is ControlBodyInput;
123
122
  export interface AppealRequest {
@@ -188,6 +187,7 @@ export interface TransitionConfig<CR1 extends Base, CR2 extends Base, P extends
188
187
  */
189
188
  export declare type Transitions = {
190
189
  [State.DRAFT]: {
190
+ [State.WITHDRAWN]: TransitionConfig<Proposed, Withdrawn>;
191
191
  [State.PROPOSED]: TransitionConfig<Drafted, Proposed, SubmitterInput>;
192
192
  };
193
193
  [State.PROPOSED]: {
package/types/cr.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cr.js","sourceRoot":"","sources":["../../src/types/cr.ts"],"names":[],"mappings":"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","sourcesContent":["/** Change request types, states and state transitions. */\n\nimport type React from 'react';\nimport type { ProposalSet } from './proposal';\nimport { type RegisterStakeholder } from './stakeholder';\n\n\n\nexport function isSubmittedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return (\n //isSubmitter(stakeholder) &&\n stakeholder.gitServerUsername === cr.submittingStakeholderGitServerUsername);\n}\n\n\n\n// =====================\n// Change request states\n// =====================\n\n/** Used in place of enum for convenience. */\nexport const State = {\n DRAFT: 'draft',\n PROPOSED: 'proposed',\n SUBMITTED_FOR_CONTROL_BODY_REVIEW: 'pending-control-body-review',\n RETURNED_FOR_CLARIFICATION: 'returned-for-clarification',\n WITHDRAWN: 'withdrawn',\n ACCEPTED: 'accepted',\n REJECTED: 'rejected',\n APPEALED: 'rejection-appealed-to-owner',\n ACCEPTED_ON_APPEAL: 'accepted-on-appeal',\n REJECTION_UPHELD_ON_APPEAL: 'rejection-upheld-on-appeal',\n APPEAL_WITHDRAWN: 'appeal-withdrawn',\n} as const;\n\nexport type StateType = typeof State[keyof typeof State];\n\nexport function isState(val: string): val is StateType {\n return Object.values(State).indexOf(val as StateType) >= 0;\n}\n\n/** A subset of `State` that represents editable states. */\nexport const EditableState = [\n State.DRAFT,\n State.RETURNED_FOR_CLARIFICATION,\n] as const;\n\nexport type EditableStateType = StateType & typeof EditableState[number];\n\nexport function isEditableState(state: StateType): state is EditableStateType {\n return EditableState.indexOf(state as EditableStateType) >= 0;\n}\n\n\n\n// ======================\n// Change request classes\n// ======================\n\n/**\n * Base change request type.\n *\n * Note that e.g. type Base<typeof State.DRAFT> does not equal to Drafted\n * because Drafted includes additional information (namely, SubmitterInput).\n *\n * If the state of a CR matters, this type should not be used directly\n * and concrete types should be used instead.\n */\nexport interface Base<S extends StateType = StateType>\n{\n id: string;\n // decision: typeof Decision[keyof typeof Decision]\n // disposition?: typeof Disposition[keyof typeof Disposition]\n state: S;\n\n /**\n * Used to match against stakeholders declared in register metadata.\n */\n submittingStakeholderGitServerUsername: string;\n\n items: ProposalSet;\n\n /**\n * Against to which register version changes were proposed.\n */\n registerVersion: string;\n\n /**\n * A link to external discussion.\n */\n externalDiscussionURI?: string;\n}\n\n\nexport function isCreatedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return stakeholder.gitServerUsername === cr.submittingStakeholderGitServerUsername;\n}\n\nexport function canBeEditedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return isCreatedBy(stakeholder, cr) && isEditableState(cr.state);\n}\n\n\n/**\n * A change request in any state.\n * Contains a superset of all possible properties, but all optional.\n * XXX: ^^^ This is a lie. Should be changed from | to & with Partial<>?\n */\nexport type SomeCR = \n | Drafted\n | Proposed\n | Withdrawn\n | ReturnedForClarificationByManager\n | SubmittedForControlBodyReview\n | ReturnedForClarificationByControlBody\n | Accepted\n | Rejected\n | RejectionUpheld\n | AcceptedOnAppeal\n | RejectedWithAppealWithdrawn;\n\nexport type Withdrawable =\n | Proposed\n | SubmittedForControlBodyReview\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type Proposable =\n | Drafted\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type SomeEditable =\n | Drafted\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type Disposed =\n | Withdrawn\n | Accepted\n | Rejected\n | AcceptedOnAppeal\n | RejectionUpheld;\n\n\n// More specific change request types.\n// TODO: Refactor to avoid confusiong between current state e.g. Proposed)\n// and type (Proposed, to which all inheriting classes also conform)\n\nexport interface Drafted extends\n SubmitterInput,\n Base<typeof State.DRAFT> { timeStarted: Date, timeEdited: Date }\nexport function isDrafted(cr: Base): cr is Drafted {\n return isInState(cr, State.DRAFT);\n}\n\nexport interface Proposed extends\n Omit<Drafted, 'state'>,\n Base<typeof State.PROPOSED> { timeProposed: Date }\nexport function isProposed(cr: Base): cr is Proposed {\n return isInState(cr, State.PROPOSED);\n}\n\nexport interface Withdrawn extends\n Omit<Withdrawable, 'state'>,\n Base<typeof State.WITHDRAWN> { timeDisposed: Date }\nexport function isWithdrawn(cr: Base): cr is Withdrawn {\n return isInState(cr, State.WITHDRAWN);\n}\n\nexport function hadBeenProposed(cr: Base): cr is Base & { timeProposed: Date } {\n return cr && cr.hasOwnProperty('timeProposed') && !!(cr as Proposed).timeProposed;\n}\nexport function isDisposed(cr: Base): cr is Base & { timeDisposed: Date } {\n return cr && cr.hasOwnProperty('timeDisposed') && !!(cr as Disposed).timeDisposed;\n //return [\n // State.WITHDRAWN,\n // State.ACCEPTED,\n // State.REJECTED,\n // State.REJECTION_UPHELD_ON_APPEAL,\n // State.ACCEPTED_ON_APPEAL,\n //].some(s => cr.state === s);\n}\n\nexport interface SubmittedForControlBodyReview extends\n Omit<Proposed, 'state'>,\n RegisterManagerInput,\n Base<typeof State.SUBMITTED_FOR_CONTROL_BODY_REVIEW> {}\n\nexport interface ReturnedForClarificationByManager extends\n Omit<Proposed, 'state'>,\n RegisterManagerInput,\n Base<typeof State.RETURNED_FOR_CLARIFICATION> {}\n\nexport interface ReturnedForClarificationByControlBody extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.RETURNED_FOR_CLARIFICATION> {}\n\nexport interface Accepted extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.ACCEPTED> { timeDisposed: Date }\nexport function isAccepted(cr: Base): cr is Accepted {\n return isInState(cr, State.ACCEPTED);\n}\n\nexport interface Rejected extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.REJECTED> { timeDisposed: Date }\n\nexport interface Appealed extends\n Omit<Rejected, 'state' | 'timeDisposed'>,\n AppealRequest,\n Base<typeof State.APPEALED> { timeDisposed: undefined }\nexport function isAppealed(cr: Base): cr is Appealed {\n return isInState(cr, State.APPEALED);\n}\n\nexport interface RejectionUpheld extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n RegisterOwnerInput,\n Base<typeof State.REJECTION_UPHELD_ON_APPEAL> { timeDisposed: Date }\n\nexport interface AcceptedOnAppeal extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n RegisterOwnerInput,\n Base<typeof State.ACCEPTED_ON_APPEAL> { timeDisposed: Date }\nexport function isAcceptedOnAppeal(cr: Base): cr is AcceptedOnAppeal {\n return isInState(cr, State.ACCEPTED_ON_APPEAL);\n}\n\nexport interface RejectedWithAppealWithdrawn extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n Base<typeof State.APPEAL_WITHDRAWN> { timeDisposed: Date }\n\n\n\n// Input required when transitioning to different states\n\nexport interface SubmitterInput {\n justification: string;\n}\nexport function hasSubmitterInput(val: any): val is SubmitterInput {\n return val.hasOwnProperty('justification') && typeof val.justification === 'string';\n}\nexport interface RegisterManagerInput {\n registerManagerNotes: string;\n}\nexport function hasRegisterManagerInput(val: any): val is RegisterManagerInput {\n return val.hasOwnProperty('registerManagerNotes') && typeof val.registerManagerNotes === 'string';\n}\nexport interface ControlBodyInput {\n controlBodyNotes: string;\n controlBodyDecisionEvent: string;\n}\nexport function hasControlBodyInput(val: any): val is ControlBodyInput {\n return (\n val.hasOwnProperty('controlBodyNotes') && typeof val.controlBodyNotes === 'string' &&\n val.hasOwnProperty('controlBodyDecisionEvent') && typeof val.controlBodyDecisionEvent === 'string');\n}\nexport interface AppealRequest {\n appealReason: string;\n}\nexport function hasAppealRequest(val: any): val is AppealRequest {\n return val.hasOwnProperty('appealReason') && typeof val.appealReason === 'string';\n}\nexport interface RegisterOwnerInput {\n registerOwnerNotes: string;\n}\nexport function hasRegisterOwnerInput(val: any): val is RegisterOwnerInput {\n return val.hasOwnProperty('registerOwnerNotes') && typeof val.registerOwnerNotes === 'string';\n}\n\nexport type StateInput =\n | SubmitterInput\n | RegisterManagerInput\n | ControlBodyInput\n | AppealRequest\n | RegisterOwnerInput;\n\n\n/** \n * CR type guard helper.\n * Normally you would not use it directly and instead use\n * more specific is[Type]() helper from this module.\n *\n * Checks CR type using the `state` property.\n * Does not validate other properties.\n *\n * Usage:\n *\n * @example\n * ```ts\n * let someCR;\n * if (isInState<Drafted>(someCR, State.DRAFT)) {\n * // Can assume someCR is Drafted\n * }\n * ```\n *\n * It’ll try to tell you if you mismatch those.\n *\n * @example\n * Will not compile:\n * ```ts\n * let someCR;\n * if (isInState<Drafted>(someCR, State.PROPOSED)) {\n * // Compile error\n * // because State.PROPOSED is not a possible value of Drafted[\"state\"]\n * }\n * ```\n *\n * @example\n * Incorrect usage (do not do this):\n * ```ts\n * let someCR;\n * if (isInState(someCR, State.DRAFT)) {\n * // Can NOT assume someCR is Drafted\n * // The compiler must know the expected concrete CR type\n * }\n * ```\n */\nfunction isInState<CR extends Base>(cr: Base, s: CR[\"state\"]): cr is CR {\n return cr.state === s;\n}\n\n\n\n\n// ===========\n// Transitions\n// ===========\n\n/**\n * A function that transitions CR1 to CR2.\n *\n * The function is declared to return the object\n * without the `state` field, it is set\n * by common wrapper function to reduce duplication.\n */\nexport type Transition<\n /** From CR of this subtype */\n CR1 extends Base,\n /** To CR of this subtype */\n CR2 extends Base,\n /** Using this extra information */\n P extends Record<string, any> | null = null,\n> = (cr: CR1, payload: P) => Omit<CR2, 'state'>;\n\n\n/**\n * Describes a transition.\n *\n * @typeParam CR1: Change request source state type\n * @typeParam CR2: Change request target state type\n * @typeParam P: Extra input needed to transition, if any\n */\nexport interface TransitionConfig<CR1 extends Base, CR2 extends Base, P extends Record<string, any> | null = null> {\n /**\n * Function that implements the transition.\n * Takes a CR in the original state and returns CR in the new state.\n * Additionally, takes appropriate payload, if any, for the transition\n * (e.g., register manager or control body notes).\n *\n * For function implementor:\n *\n * - Function MUST NOT modify CR in place.\n * - Function should throw if submitted payload does not conform to requirements.\n */\n func: Transition<CR1, CR2, P>;\n\n targetState: CR2[\"state\"];\n\n /** Title. Use verb. */\n title: string;\n\n hint?: string | JSX.Element;\n\n /** Widget that can be used to view or enter extra input. */\n Widget: P extends null ? null : React.FC<{ value: P, onChange?: (userInput: P) => void }>;\n\n /**\n * Function that returns true\n * if given stakeholder can perform this transition on given CR.\n */\n canBeTransitionedBy: (stakeholder: RegisterStakeholder, cr: CR1) => boolean;\n}\n\n\n// type TransitionSpec = {\n// [S1 in StateType]?: {\n// [S2 in StateType]?: Transition<Base<S1>, Base<S2>, Record<string, any>>\n// }\n// }\n\n\n/**\n * Source of truth for available transitions.\n * When updating change request business logic,\n * this is the type that should be modified.\n *\n * It will cause compile errors until transition implementation\n * is updated correspondingly.\n */\nexport type Transitions = {\n [State.DRAFT]: {\n // [State.DRAFT]:\n // TransitionConfig<Drafted, Drafted, SubmitterInput>;\n [State.PROPOSED]:\n TransitionConfig<Drafted, Proposed, SubmitterInput>;\n };\n [State.PROPOSED]: {\n [State.WITHDRAWN]:\n TransitionConfig<Proposed, Withdrawn>;\n [State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]:\n TransitionConfig<Proposed, SubmittedForControlBodyReview, RegisterManagerInput>;\n [State.RETURNED_FOR_CLARIFICATION]:\n TransitionConfig<Proposed, ReturnedForClarificationByManager, RegisterManagerInput>;\n };\n [State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n [State.WITHDRAWN]:\n TransitionConfig<SubmittedForControlBodyReview, Withdrawn>;\n [State.RETURNED_FOR_CLARIFICATION]:\n TransitionConfig<SubmittedForControlBodyReview, ReturnedForClarificationByControlBody, ControlBodyInput>;\n [State.REJECTED]:\n TransitionConfig<SubmittedForControlBodyReview, Rejected, ControlBodyInput>;\n [State.ACCEPTED]:\n TransitionConfig<SubmittedForControlBodyReview, Accepted, ControlBodyInput>;\n };\n [State.RETURNED_FOR_CLARIFICATION]: {\n [State.PROPOSED]:\n TransitionConfig<ReturnedForClarificationByManager | ReturnedForClarificationByControlBody, Proposed, SubmitterInput>;\n [State.WITHDRAWN]:\n TransitionConfig<ReturnedForClarificationByManager | ReturnedForClarificationByControlBody, Withdrawn>;\n };\n [State.REJECTED]: {\n [State.APPEALED]:\n TransitionConfig<Rejected, Appealed, AppealRequest>;\n };\n [State.APPEALED]: {\n [State.APPEAL_WITHDRAWN]:\n TransitionConfig<Appealed, RejectedWithAppealWithdrawn>;\n [State.ACCEPTED_ON_APPEAL]:\n TransitionConfig<Appealed, AcceptedOnAppeal, RegisterOwnerInput>;\n [State.REJECTION_UPHELD_ON_APPEAL]:\n TransitionConfig<Appealed, RejectionUpheld, RegisterOwnerInput>;\n };\n}\n"]}
1
+ {"version":3,"file":"cr.js","sourceRoot":"","sources":["../../src/types/cr.ts"],"names":[],"mappings":"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","sourcesContent":["/** Change request types, states and state transitions. */\n\nimport type React from 'react';\nimport type { ProposalSet } from './proposal';\nimport { type RegisterStakeholder } from './stakeholder';\n\n\n\nexport function isSubmittedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return (\n //isSubmitter(stakeholder) &&\n stakeholder.gitServerUsername === cr.submittingStakeholderGitServerUsername);\n}\n\n\n\n// =====================\n// Change request states\n// =====================\n\n/** Used in place of enum for convenience. */\nexport const State = {\n DRAFT: 'draft',\n PROPOSED: 'proposed',\n SUBMITTED_FOR_CONTROL_BODY_REVIEW: 'pending-control-body-review',\n RETURNED_FOR_CLARIFICATION: 'returned-for-clarification',\n WITHDRAWN: 'withdrawn',\n ACCEPTED: 'accepted',\n REJECTED: 'rejected',\n APPEALED: 'rejection-appealed-to-owner',\n ACCEPTED_ON_APPEAL: 'accepted-on-appeal',\n REJECTION_UPHELD_ON_APPEAL: 'rejection-upheld-on-appeal',\n APPEAL_WITHDRAWN: 'appeal-withdrawn',\n} as const;\n\nexport type StateType = typeof State[keyof typeof State];\n\nexport function isState(val: string): val is StateType {\n return Object.values(State).indexOf(val as StateType) >= 0;\n}\n\n/** A subset of `State` that represents editable states. */\nexport const EditableState = [\n State.DRAFT,\n State.RETURNED_FOR_CLARIFICATION,\n] as const;\n\nexport type EditableStateType = StateType & typeof EditableState[number];\n\nexport function isEditableState(state: StateType): state is EditableStateType {\n return EditableState.indexOf(state as EditableStateType) >= 0;\n}\n\n\n\n// ======================\n// Change request classes\n// ======================\n\n/**\n * Base change request type.\n *\n * Note that e.g. type Base<typeof State.DRAFT> does not equal to Drafted\n * because Drafted includes additional information (namely, SubmitterInput).\n *\n * If the state of a CR matters, this type should not be used directly\n * and concrete types should be used instead.\n */\nexport interface Base<S extends StateType = StateType>\n{\n id: string;\n // decision: typeof Decision[keyof typeof Decision]\n // disposition?: typeof Disposition[keyof typeof Disposition]\n state: S;\n\n /**\n * Used to match against stakeholders declared in register metadata.\n */\n submittingStakeholderGitServerUsername: string;\n\n items: ProposalSet;\n\n /**\n * Against to which register version changes were proposed.\n */\n registerVersion: string;\n\n /**\n * A link to external discussion.\n */\n externalDiscussionURI?: string;\n}\n\n\nexport function isCreatedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return stakeholder.gitServerUsername === cr.submittingStakeholderGitServerUsername;\n}\n\nexport function canBeEditedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return isCreatedBy(stakeholder, cr) && isEditableState(cr.state);\n}\n\n\n/**\n * A change request in any state.\n * Contains a superset of all possible properties, but all optional.\n * XXX: ^^^ This is a lie. Should be changed from | to & with Partial<>?\n */\nexport type SomeCR = \n | Drafted\n | Proposed\n | Withdrawn\n | ReturnedForClarificationByManager\n | SubmittedForControlBodyReview\n | ReturnedForClarificationByControlBody\n | Accepted\n | Rejected\n | RejectionUpheld\n | AcceptedOnAppeal\n | RejectedWithAppealWithdrawn;\n\nexport type Withdrawable =\n | Proposed\n | SubmittedForControlBodyReview\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type Proposable =\n | Drafted\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type SomeEditable =\n | Drafted\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type Disposed =\n | Withdrawn\n | Accepted\n | Rejected\n | AcceptedOnAppeal\n | RejectionUpheld;\n\n\n// More specific change request types.\n// TODO: Refactor to avoid confusiong between current state e.g. Proposed)\n// and type (Proposed, to which all inheriting classes also conform)\n\nexport interface Drafted extends\n SubmitterInput,\n Base<typeof State.DRAFT> { timeStarted: Date, timeEdited: Date }\nexport function isDrafted(cr: Base): cr is Drafted {\n return isInState(cr, State.DRAFT);\n}\n\nexport interface Proposed extends\n Omit<Drafted, 'state'>,\n Base<typeof State.PROPOSED> { timeProposed: Date }\nexport function isProposed(cr: Base): cr is Proposed {\n return isInState(cr, State.PROPOSED);\n}\n\nexport interface Withdrawn extends\n Omit<Withdrawable, 'state'>,\n Base<typeof State.WITHDRAWN> { timeDisposed: Date }\nexport function isWithdrawn(cr: Base): cr is Withdrawn {\n return isInState(cr, State.WITHDRAWN);\n}\n\nexport function hadBeenProposed(cr: Base): cr is Base & { timeProposed: Date } {\n return cr && cr.hasOwnProperty('timeProposed') && !!(cr as Proposed).timeProposed;\n}\nexport function isDisposed(cr: Base): cr is Base & { timeDisposed: Date } {\n return cr && cr.hasOwnProperty('timeDisposed') && !!(cr as Disposed).timeDisposed;\n //return [\n // State.WITHDRAWN,\n // State.ACCEPTED,\n // State.REJECTED,\n // State.REJECTION_UPHELD_ON_APPEAL,\n // State.ACCEPTED_ON_APPEAL,\n //].some(s => cr.state === s);\n}\n\nexport interface SubmittedForControlBodyReview extends\n Omit<Proposed, 'state'>,\n RegisterManagerInput,\n Base<typeof State.SUBMITTED_FOR_CONTROL_BODY_REVIEW> {}\n\nexport interface ReturnedForClarificationByManager extends\n Omit<Proposed, 'state'>,\n RegisterManagerInput,\n Base<typeof State.RETURNED_FOR_CLARIFICATION> {}\n\nexport interface ReturnedForClarificationByControlBody extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.RETURNED_FOR_CLARIFICATION> {}\n\nexport interface Accepted extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.ACCEPTED> { timeDisposed: Date }\nexport function isAccepted(cr: Base): cr is Accepted {\n return isInState(cr, State.ACCEPTED);\n}\n\nexport interface Rejected extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.REJECTED> { timeDisposed: Date }\n\nexport interface Appealed extends\n Omit<Rejected, 'state' | 'timeDisposed'>,\n AppealRequest,\n Base<typeof State.APPEALED> { timeDisposed: undefined }\nexport function isAppealed(cr: Base): cr is Appealed {\n return isInState(cr, State.APPEALED);\n}\n\nexport interface RejectionUpheld extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n RegisterOwnerInput,\n Base<typeof State.REJECTION_UPHELD_ON_APPEAL> { timeDisposed: Date }\n\nexport interface AcceptedOnAppeal extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n RegisterOwnerInput,\n Base<typeof State.ACCEPTED_ON_APPEAL> { timeDisposed: Date }\nexport function isAcceptedOnAppeal(cr: Base): cr is AcceptedOnAppeal {\n return isInState(cr, State.ACCEPTED_ON_APPEAL);\n}\n\nexport interface RejectedWithAppealWithdrawn extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n Base<typeof State.APPEAL_WITHDRAWN> { timeDisposed: Date }\n\n\n\n// Input required when transitioning to different states\n\nexport interface SubmitterInput {\n justification: string;\n}\nexport function hasSubmitterInput(val: any): val is SubmitterInput {\n return val.hasOwnProperty('justification') && typeof val.justification === 'string';\n}\nexport interface RegisterManagerInput {\n registerManagerNotes: string;\n}\nexport function hasRegisterManagerInput(val: any): val is RegisterManagerInput {\n return val.hasOwnProperty('registerManagerNotes') && typeof val.registerManagerNotes === 'string';\n}\nexport interface ControlBodyInput {\n controlBodyNotes: string;\n}\nexport function hasControlBodyInput(val: any): val is ControlBodyInput {\n return (\n val.hasOwnProperty('controlBodyNotes') && typeof val.controlBodyNotes === 'string' &&\n val.hasOwnProperty('controlBodyDecisionEvent') && typeof val.controlBodyDecisionEvent === 'string');\n}\nexport interface AppealRequest {\n appealReason: string;\n}\nexport function hasAppealRequest(val: any): val is AppealRequest {\n return val.hasOwnProperty('appealReason') && typeof val.appealReason === 'string';\n}\nexport interface RegisterOwnerInput {\n registerOwnerNotes: string;\n}\nexport function hasRegisterOwnerInput(val: any): val is RegisterOwnerInput {\n return val.hasOwnProperty('registerOwnerNotes') && typeof val.registerOwnerNotes === 'string';\n}\n\nexport type StateInput =\n | SubmitterInput\n | RegisterManagerInput\n | ControlBodyInput\n | AppealRequest\n | RegisterOwnerInput;\n\n\n/** \n * CR type guard helper.\n * Normally you would not use it directly and instead use\n * more specific is[Type]() helper from this module.\n *\n * Checks CR type using the `state` property.\n * Does not validate other properties.\n *\n * Usage:\n *\n * @example\n * ```ts\n * let someCR;\n * if (isInState<Drafted>(someCR, State.DRAFT)) {\n * // Can assume someCR is Drafted\n * }\n * ```\n *\n * It’ll try to tell you if you mismatch those.\n *\n * @example\n * Will not compile:\n * ```ts\n * let someCR;\n * if (isInState<Drafted>(someCR, State.PROPOSED)) {\n * // Compile error\n * // because State.PROPOSED is not a possible value of Drafted[\"state\"]\n * }\n * ```\n *\n * @example\n * Incorrect usage (do not do this):\n * ```ts\n * let someCR;\n * if (isInState(someCR, State.DRAFT)) {\n * // Can NOT assume someCR is Drafted\n * // The compiler must know the expected concrete CR type\n * }\n * ```\n */\nfunction isInState<CR extends Base>(cr: Base, s: CR[\"state\"]): cr is CR {\n return cr.state === s;\n}\n\n\n\n\n// ===========\n// Transitions\n// ===========\n\n/**\n * A function that transitions CR1 to CR2.\n *\n * The function is declared to return the object\n * without the `state` field, it is set\n * by common wrapper function to reduce duplication.\n */\nexport type Transition<\n /** From CR of this subtype */\n CR1 extends Base,\n /** To CR of this subtype */\n CR2 extends Base,\n /** Using this extra information */\n P extends Record<string, any> | null = null,\n> = (cr: CR1, payload: P) => Omit<CR2, 'state'>;\n\n\n/**\n * Describes a transition.\n *\n * @typeParam CR1: Change request source state type\n * @typeParam CR2: Change request target state type\n * @typeParam P: Extra input needed to transition, if any\n */\nexport interface TransitionConfig<CR1 extends Base, CR2 extends Base, P extends Record<string, any> | null = null> {\n /**\n * Function that implements the transition.\n * Takes a CR in the original state and returns CR in the new state.\n * Additionally, takes appropriate payload, if any, for the transition\n * (e.g., register manager or control body notes).\n *\n * For function implementor:\n *\n * - Function MUST NOT modify CR in place.\n * - Function should throw if submitted payload does not conform to requirements.\n */\n func: Transition<CR1, CR2, P>;\n\n targetState: CR2[\"state\"];\n\n /** Title. Use verb. */\n title: string;\n\n hint?: string | JSX.Element;\n\n /** Widget that can be used to view or enter extra input. */\n Widget: P extends null ? null : React.FC<{ value: P, onChange?: (userInput: P) => void }>;\n\n /**\n * Function that returns true\n * if given stakeholder can perform this transition on given CR.\n */\n canBeTransitionedBy: (stakeholder: RegisterStakeholder, cr: CR1) => boolean;\n}\n\n\n// type TransitionSpec = {\n// [S1 in StateType]?: {\n// [S2 in StateType]?: Transition<Base<S1>, Base<S2>, Record<string, any>>\n// }\n// }\n\n\n/**\n * Source of truth for available transitions.\n * When updating change request business logic,\n * this is the type that should be modified.\n *\n * It will cause compile errors until transition implementation\n * is updated correspondingly.\n */\nexport type Transitions = {\n [State.DRAFT]: {\n // [State.DRAFT]:\n // TransitionConfig<Drafted, Drafted, SubmitterInput>;\n [State.WITHDRAWN]:\n TransitionConfig<Proposed, Withdrawn>;\n [State.PROPOSED]:\n TransitionConfig<Drafted, Proposed, SubmitterInput>;\n };\n [State.PROPOSED]: {\n [State.WITHDRAWN]:\n TransitionConfig<Proposed, Withdrawn>;\n [State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]:\n TransitionConfig<Proposed, SubmittedForControlBodyReview, RegisterManagerInput>;\n [State.RETURNED_FOR_CLARIFICATION]:\n TransitionConfig<Proposed, ReturnedForClarificationByManager, RegisterManagerInput>;\n };\n [State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n [State.WITHDRAWN]:\n TransitionConfig<SubmittedForControlBodyReview, Withdrawn>;\n [State.RETURNED_FOR_CLARIFICATION]:\n TransitionConfig<SubmittedForControlBodyReview, ReturnedForClarificationByControlBody, ControlBodyInput>;\n [State.REJECTED]:\n TransitionConfig<SubmittedForControlBodyReview, Rejected, ControlBodyInput>;\n [State.ACCEPTED]:\n TransitionConfig<SubmittedForControlBodyReview, Accepted, ControlBodyInput>;\n };\n [State.RETURNED_FOR_CLARIFICATION]: {\n [State.PROPOSED]:\n TransitionConfig<ReturnedForClarificationByManager | ReturnedForClarificationByControlBody, Proposed, SubmitterInput>;\n [State.WITHDRAWN]:\n TransitionConfig<ReturnedForClarificationByManager | ReturnedForClarificationByControlBody, Withdrawn>;\n };\n [State.REJECTED]: {\n [State.APPEALED]:\n TransitionConfig<Rejected, Appealed, AppealRequest>;\n };\n [State.APPEALED]: {\n [State.APPEAL_WITHDRAWN]:\n TransitionConfig<Appealed, RejectedWithAppealWithdrawn>;\n [State.ACCEPTED_ON_APPEAL]:\n TransitionConfig<Appealed, AcceptedOnAppeal, RegisterOwnerInput>;\n [State.REJECTION_UPHELD_ON_APPEAL]:\n TransitionConfig<Appealed, RejectionUpheld, RegisterOwnerInput>;\n };\n}\n"]}
@@ -15,6 +15,8 @@ var _context = require("@riboseinc/paneron-extension-kit/context");
15
15
 
16
16
  var _HelpTooltip = _interopRequireDefault(require("@riboseinc/paneron-extension-kit/widgets/HelpTooltip"));
17
17
 
18
+ var _context2 = require("@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context");
19
+
18
20
  var _BrowserCtx = require("../../BrowserCtx");
19
21
 
20
22
  var _itemPathUtils = require("../../itemPathUtils");
@@ -27,6 +29,8 @@ var _cr = require("../../../types/cr");
27
29
 
28
30
  var _RegisterStakeholder = require("../../RegisterStakeholder");
29
31
 
32
+ var _protocolRegistry = require("../../protocolRegistry");
33
+
30
34
  var _util = require("../../util");
31
35
 
32
36
  var _transitions = require("./transitions");
@@ -44,24 +48,35 @@ const View = function ({
44
48
  uri
45
49
  }) {
46
50
  const crID = (0, _itemPathUtils.crPathToCRID)(uri);
51
+ const {
52
+ closeTabWithURI
53
+ } = (0, _react.useContext)(_context2.TabbedWorkspaceContext);
47
54
  return (0, _react2.jsx)(_ChangeRequestContext.ChangeRequestContextProvider, {
48
55
  changeRequestID: crID
49
56
  }, (0, _react2.jsx)(ChangeRequestDetails, {
50
57
  css: (0, _react2.css)`
51
- position: absolute;
52
- inset: 0;
53
- overflow-y: auto;
54
- `
58
+ position: absolute;
59
+ inset: 0;
60
+ overflow-y: auto;
61
+ `,
62
+ afterDelete: () => {
63
+ closeTabWithURI(`${_protocolRegistry.Protocols.CHANGE_REQUEST}:${uri}`);
64
+ }
55
65
  }));
56
66
  };
57
67
 
58
68
  const ChangeRequestDetails = function ({
69
+ afterDelete,
59
70
  className
60
71
  }) {
61
72
  const {
62
73
  changeRequest: cr,
63
74
  canEdit
64
75
  } = (0, _react.useContext)(_ChangeRequestContext.ChangeRequestContext);
76
+ const {
77
+ performOperation,
78
+ updateTree
79
+ } = (0, _react.useContext)(_context.DatasetContext);
65
80
  const {
66
81
  registerMetadata,
67
82
  stakeholder,
@@ -77,6 +92,20 @@ const ChangeRequestDetails = function ({
77
92
  const anotherIsActive = activeChangeRequestID && activeChangeRequestID !== cr.id;
78
93
  const canTransition = stakeholder && (0, _transitions.getTransitions)(cr, stakeholder).length > 0;
79
94
  const crStakeholder = ((registerMetadata === null || registerMetadata === void 0 ? void 0 : registerMetadata.stakeholders) ?? []).find(s => s.gitServerUsername === cr.submittingStakeholderGitServerUsername);
95
+ const authorIsCurrentUser = (stakeholder === null || stakeholder === void 0 ? void 0 : stakeholder.gitServerUsername) && cr.submittingStakeholderGitServerUsername === stakeholder.gitServerUsername;
96
+
97
+ async function handleDelete() {
98
+ if (authorIsCurrentUser && cr && updateTree && !isActive && Object.keys(cr.items).length < 1) {
99
+ const subtreeRoot = (0, _itemPathUtils.crIDToCRPath)(cr.id).replace('/main.yaml', '');
100
+ await updateTree({
101
+ subtreeRoot,
102
+ newSubtreeRoot: null,
103
+ commitMessage: 'remove CR draft'
104
+ });
105
+ afterDelete === null || afterDelete === void 0 ? void 0 : afterDelete();
106
+ }
107
+ }
108
+
80
109
  return (0, _react2.jsx)(_util.TabContentsWithActions, {
81
110
  className: className,
82
111
  actions: (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.FormGroup, {
@@ -111,15 +140,22 @@ const ChangeRequestDetails = function ({
111
140
  display: flex;
112
141
  min-height: 70vh;
113
142
  `
114
- }, (0, _react2.jsx)(_Proposals.default, {
143
+ }, Object.keys(cr.items).length > 0 ? (0, _react2.jsx)(_Proposals.default, {
115
144
  proposals: cr.items,
116
145
  css: (0, _react2.css)`flex: 1;`
146
+ }) : (0, _react2.jsx)(_core.NonIdealState, {
147
+ icon: "clean",
148
+ title: "Nothing is proposed here yet.",
149
+ description: authorIsCurrentUser && updateTree && !cr.timeProposed && !isActive ? (0, _react2.jsx)(_core.Button, {
150
+ onClick: performOperation('deleting proposal', handleDelete),
151
+ intent: "danger"
152
+ }, "Delete this CR draft") : undefined
117
153
  })), (0, _react2.jsx)(_core.Card, {
118
154
  elevation: 1,
119
155
  css: (0, _react2.css)`flex: 30%; padding: 11px;`
120
156
  }, crStakeholder ? (0, _react2.jsx)("div", null, "Author: ", (0, _react2.jsx)(_RegisterStakeholder.RegisterStakeholderListItem, {
121
157
  stakeholder: crStakeholder,
122
- isCurrentUser: cr.submittingStakeholderGitServerUsername === (stakeholder === null || stakeholder === void 0 ? void 0 : stakeholder.gitServerUsername) ? true : undefined
158
+ isCurrentUser: authorIsCurrentUser || undefined
123
159
  })) : null, (0, _react2.jsx)(_core.Divider, null), (0, _react2.jsx)("div", null, "To register version: ", (0, _react2.jsx)("strong", null, cr.registerVersion ?? 'N/A'), " ", cr.registerVersion === (registerMetadata === null || registerMetadata === void 0 ? void 0 : (_registerMetadata$ver = registerMetadata.version) === null || _registerMetadata$ver === void 0 ? void 0 : _registerMetadata$ver.id) ? (0, _react2.jsx)(_core.Tag, {
124
160
  css: (0, _react2.css)`display: inline;`,
125
161
  intent: 'success',
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/views/detail/ChangeRequest/index.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext } from 'react';\nimport { jsx, css } from '@emotion/react';\nimport {\n Button,\n Card,\n FormGroup,\n Colors,\n NonIdealState,\n Spinner,\n H5,\n UL,\n Tag,\n Divider,\n Classes,\n} from '@blueprintjs/core';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport HelpTooltip from '@riboseinc/paneron-extension-kit/widgets/HelpTooltip';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport { crPathToCRID } from '../../itemPathUtils';\nimport {\n ChangeRequestContextProvider,\n ChangeRequestContext,\n} from '../../change-request/ChangeRequestContext';\nimport Proposals from '../../change-request/Proposals';\nimport { hadBeenProposed, isDisposed } from '../../../types/cr';\nimport { RegisterStakeholderListItem } from '../../RegisterStakeholder';\nimport {\n TabContentsWithActions,\n RegisterHelmet as Helmet,\n maybeEllipsizeString,\n Datestamp,\n} from '../../util';\nimport { TransitionOptions, getPastTransitions, getTransitions } from './transitions';\n\n\nconst View: React.FC<{ uri: string }> = function ({ uri }) {\n const crID = crPathToCRID(uri);\n\n return (\n <ChangeRequestContextProvider changeRequestID={crID}>\n <ChangeRequestDetails css={css`\n position: absolute;\n inset: 0;\n overflow-y: auto;\n `} />\n </ChangeRequestContextProvider>\n );\n};\n\n\nconst ChangeRequestDetails:\nReact.VoidFunctionComponent<{ className?: string }> =\nfunction ({ className }) {\n const { changeRequest: cr, canEdit } = useContext(ChangeRequestContext);\n const {\n registerMetadata,\n stakeholder,\n activeChangeRequestID,\n setActiveChangeRequestID,\n } = useContext(BrowserCtx);\n\n const helmet = \n <Helmet>\n <title>Viewing proposal: {cr?.justification ?? \"N/A\"}</title>\n </Helmet>;\n\n if (cr) {\n const isActive = activeChangeRequestID === cr.id;\n const anotherIsActive = activeChangeRequestID && activeChangeRequestID !== cr.id;\n const canTransition = stakeholder && getTransitions(cr, stakeholder).length > 0;\n\n const crStakeholder = (registerMetadata?.stakeholders ?? []).\n find(s => s.gitServerUsername === cr.submittingStakeholderGitServerUsername);\n\n return (\n <TabContentsWithActions\n className={className}\n actions={<>\n <FormGroup\n inline\n labelInfo={<HelpTooltip\n icon='info-sign'\n content={<>\n <UL>\n <li>Proposal ID: {cr.id}</li>\n </UL>\n </>}\n />}\n label={<strong>Proposal</strong>}\n css={css`margin: 0; .bp4-form-content { display: flex; flex-flow: row wrap; gap: 10px; }`}>\n <CRActivation\n isActive={isActive}\n htmlTitle={anotherIsActive\n ? \"You are in another proposal so you can’t enter this one. \"\n : canEdit && !isActive\n ? \"Enter proposal to preview or add to proposed changes. \"\n : !isActive\n ? \"Enter proposal to preview the register as proposed.\"\n : \"You’re previewing the register with this proposal applied.\"}\n onChangeActiveStatus={!anotherIsActive && setActiveChangeRequestID\n ? ((active) => active\n ? setActiveChangeRequestID?.(cr.id)\n : setActiveChangeRequestID?.(null)\n )\n : undefined}\n />\n </FormGroup>\n </>}\n main={\n <div\n css={css`\n display: flex;\n flex-flow: row wrap;\n padding: 10px;\n gap: 10px;\n align-content: flex-start;\n align-items: flex-start;\n `}\n className={className}>\n {helmet}\n\n <Card elevation={0} css={css`\n flex: 100%;\n background: ${Colors.LIGHT_GRAY3};\n padding: 11px;\n display: flex;\n min-height: 70vh;\n `}>\n <Proposals\n proposals={cr.items}\n css={css`flex: 1;`}\n />\n </Card>\n\n <Card elevation={1} css={css`flex: 30%; padding: 11px;`}>\n\n {crStakeholder\n ? <div>\n Author: <RegisterStakeholderListItem\n stakeholder={crStakeholder}\n isCurrentUser={cr.submittingStakeholderGitServerUsername === stakeholder?.gitServerUsername\n ? true\n : undefined}\n />\n </div>\n : null}\n\n <Divider />\n <div>\n To register version: <strong>{cr.registerVersion ?? 'N/A'}</strong>\n {\" \"}\n {cr.registerVersion === registerMetadata?.version?.id\n ? <Tag css={css`display: inline;`} intent='success' minimal round>current</Tag>\n : <Tag css={css`display: inline;`} intent='warning' minimal round>\n not current\n {\" \"}\n <HelpTooltip intent='warning' icon='warning-sign' content={<>\n Register is currently at version <strong>{registerMetadata?.version?.id ?? 'N/A'}</strong>,\n {\" \"}\n which is different from version proposal author may have had in mind.\n {\" \"}\n It is recommended that proposed changes are reviewed to avoid unintentionally\n {\" \"}\n undoing a prior change.\n </>} />\n </Tag>}\n </div>\n <Divider />\n <div>Edited: <Datestamp date={cr.timeEdited} /></div>\n <Divider />\n <div>Proposed: {hadBeenProposed(cr) ? <Datestamp date={cr.timeProposed} /> : 'not yet'}</div>\n <Divider />\n <div>Disposed: {isDisposed(cr) ? <Datestamp date={cr.timeDisposed} /> : 'not yet'}</div>\n <Divider />\n\n <H5>\n {cr.state?.replaceAll('-', ' ') || 'N/A'}\n </H5>\n </Card>\n\n <Card elevation={1} css={css`flex: 30%; padding: 11px;`}>\n {getPastTransitions(cr).map(([key, el], idx) =>\n <React.Fragment key={key}>\n {idx !== 0 ? <Divider /> : null}\n <FormGroup label={`${key}:`}>\n <div\n css={css`white-space: pre-wrap;`}\n className={Classes.RUNNING_TEXT}>\n {el}\n </div>\n </FormGroup>\n </React.Fragment>\n )}\n </Card>\n\n {canTransition\n ? <Card elevation={3} css={css`flex: 30%; padding: 11px;`}>\n <TransitionOptions cr={cr} />\n </Card>\n : null}\n </div>}\n />\n );\n } else {\n return <NonIdealState\n icon={<Spinner />}\n className={className}\n description={helmet}\n />;\n }\n};\n\n\nconst CRActivation: React.FC<{\n isActive: boolean;\n htmlTitle?: string;\n\n /** Labels for the “activate” and “deactivate” buttons. */\n labels?: { activate?: string, deactivate?: string };\n\n onChangeActiveStatus?: (newStatus: boolean) => void;\n}> = function ({ isActive, htmlTitle, labels, onChangeActiveStatus }) {\n return onChangeActiveStatus && isActive\n ? <Button\n title={htmlTitle}\n intent=\"warning\"\n disabled={!onChangeActiveStatus}\n onClick={() => onChangeActiveStatus?.(false)}>\n {labels?.deactivate ?? \"Exit proposal\"}\n </Button>\n : <Button\n title={htmlTitle}\n intent={onChangeActiveStatus ? 'primary' : undefined}\n disabled={!onChangeActiveStatus}\n onClick={() => onChangeActiveStatus?.(true)}>\n {labels?.activate ?? \"Enter proposal\"}\n </Button>;\n};\n\n\nconst CRTitle: React.FC<{ uri: string }> = function ({ uri }) {\n const { useObjectData } = useContext(DatasetContext);\n const justification = useObjectData({ objectPaths: [uri] }).value.data?.[uri]?.justification;\n return <>Proposal “{maybeEllipsizeString(justification ?? uri)}”</>;\n}\n\nexport default { main: View, title: CRTitle, plainTitle: async (uri: string) => `proposal ${uri}` };\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/views/detail/ChangeRequest/index.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext } from 'react';\nimport { jsx, css } from '@emotion/react';\nimport {\n Button,\n Card,\n FormGroup,\n Colors,\n NonIdealState,\n Spinner,\n H5,\n UL,\n Tag,\n Divider,\n Classes,\n} from '@blueprintjs/core';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport HelpTooltip from '@riboseinc/paneron-extension-kit/widgets/HelpTooltip';\nimport { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport { crPathToCRID, crIDToCRPath } from '../../itemPathUtils';\nimport {\n ChangeRequestContextProvider,\n ChangeRequestContext,\n} from '../../change-request/ChangeRequestContext';\nimport Proposals from '../../change-request/Proposals';\nimport { Proposed, hadBeenProposed, isDisposed } from '../../../types/cr';\nimport { RegisterStakeholderListItem } from '../../RegisterStakeholder';\nimport { Protocols } from '../../protocolRegistry';\nimport {\n TabContentsWithActions,\n RegisterHelmet as Helmet,\n maybeEllipsizeString,\n Datestamp,\n} from '../../util';\nimport { TransitionOptions, getPastTransitions, getTransitions } from './transitions';\n\n\nconst View: React.FC<{ uri: string }> = function ({ uri }) {\n const crID = crPathToCRID(uri);\n const { closeTabWithURI } = useContext(TabbedWorkspaceContext);\n\n return (\n <ChangeRequestContextProvider changeRequestID={crID}>\n <ChangeRequestDetails\n css={css`\n position: absolute;\n inset: 0;\n overflow-y: auto;\n `}\n afterDelete={() => {\n closeTabWithURI(`${Protocols.CHANGE_REQUEST}:${uri}`);\n }}\n />\n </ChangeRequestContextProvider>\n );\n};\n\n\nconst ChangeRequestDetails:\nReact.VoidFunctionComponent<{ afterDelete?: () => void, className?: string }> =\nfunction ({ afterDelete, className }) {\n const { changeRequest: cr, canEdit } = useContext(ChangeRequestContext);\n const { performOperation, updateTree } = useContext(DatasetContext);\n const {\n registerMetadata,\n stakeholder,\n activeChangeRequestID,\n setActiveChangeRequestID,\n } = useContext(BrowserCtx);\n\n const helmet = \n <Helmet>\n <title>Viewing proposal: {cr?.justification ?? \"N/A\"}</title>\n </Helmet>;\n\n if (cr) {\n const isActive = activeChangeRequestID === cr.id;\n const anotherIsActive = activeChangeRequestID && activeChangeRequestID !== cr.id;\n const canTransition = stakeholder && getTransitions(cr, stakeholder).length > 0;\n\n const crStakeholder = (registerMetadata?.stakeholders ?? []).\n find(s => s.gitServerUsername === cr.submittingStakeholderGitServerUsername);\n\n const authorIsCurrentUser = (\n stakeholder?.gitServerUsername &&\n cr.submittingStakeholderGitServerUsername === stakeholder.gitServerUsername);\n\n async function handleDelete() {\n if (authorIsCurrentUser && cr && updateTree && !isActive && Object.keys(cr.items).length < 1) {\n const subtreeRoot = crIDToCRPath(cr.id).replace('/main.yaml', '');\n await updateTree({ subtreeRoot, newSubtreeRoot: null, commitMessage: 'remove CR draft' });\n afterDelete?.();\n }\n }\n\n return (\n <TabContentsWithActions\n className={className}\n actions={<>\n <FormGroup\n inline\n labelInfo={<HelpTooltip\n icon='info-sign'\n content={<>\n <UL>\n <li>Proposal ID: {cr.id}</li>\n </UL>\n </>}\n />}\n label={<strong>Proposal</strong>}\n css={css`margin: 0; .bp4-form-content { display: flex; flex-flow: row wrap; gap: 10px; }`}>\n <CRActivation\n isActive={isActive}\n htmlTitle={anotherIsActive\n ? \"You are in another proposal so you can’t enter this one. \"\n : canEdit && !isActive\n ? \"Enter proposal to preview or add to proposed changes. \"\n : !isActive\n ? \"Enter proposal to preview the register as proposed.\"\n : \"You’re previewing the register with this proposal applied.\"}\n onChangeActiveStatus={!anotherIsActive && setActiveChangeRequestID\n ? ((active) => active\n ? setActiveChangeRequestID?.(cr.id)\n : setActiveChangeRequestID?.(null)\n )\n : undefined}\n />\n </FormGroup>\n </>}\n main={\n <div\n css={css`\n display: flex;\n flex-flow: row wrap;\n padding: 10px;\n gap: 10px;\n align-content: flex-start;\n align-items: flex-start;\n `}\n className={className}>\n {helmet}\n\n <Card elevation={0} css={css`\n flex: 100%;\n background: ${Colors.LIGHT_GRAY3};\n padding: 11px;\n display: flex;\n min-height: 70vh;\n `}>\n {Object.keys(cr.items).length > 0\n ? <Proposals proposals={cr.items} css={css`flex: 1;`} />\n : <NonIdealState\n icon=\"clean\"\n title=\"Nothing is proposed here yet.\"\n description={authorIsCurrentUser && updateTree && !(cr as Proposed).timeProposed && !isActive\n ? <Button onClick={performOperation('deleting proposal', handleDelete)} intent=\"danger\">\n Delete this CR draft\n </Button>\n : undefined}\n />}\n </Card>\n\n <Card elevation={1} css={css`flex: 30%; padding: 11px;`}>\n\n {crStakeholder\n ? <div>\n Author: <RegisterStakeholderListItem\n stakeholder={crStakeholder}\n isCurrentUser={authorIsCurrentUser || undefined}\n />\n </div>\n : null}\n\n <Divider />\n <div>\n To register version: <strong>{cr.registerVersion ?? 'N/A'}</strong>\n {\" \"}\n {cr.registerVersion === registerMetadata?.version?.id\n ? <Tag css={css`display: inline;`} intent='success' minimal round>current</Tag>\n : <Tag css={css`display: inline;`} intent='warning' minimal round>\n not current\n {\" \"}\n <HelpTooltip intent='warning' icon='warning-sign' content={<>\n Register is currently at version <strong>{registerMetadata?.version?.id ?? 'N/A'}</strong>,\n {\" \"}\n which is different from version proposal author may have had in mind.\n {\" \"}\n It is recommended that proposed changes are reviewed to avoid unintentionally\n {\" \"}\n undoing a prior change.\n </>} />\n </Tag>}\n </div>\n <Divider />\n <div>Edited: <Datestamp date={cr.timeEdited} /></div>\n <Divider />\n <div>Proposed: {hadBeenProposed(cr) ? <Datestamp date={cr.timeProposed} /> : 'not yet'}</div>\n <Divider />\n <div>Disposed: {isDisposed(cr) ? <Datestamp date={cr.timeDisposed} /> : 'not yet'}</div>\n <Divider />\n\n <H5>\n {cr.state?.replaceAll('-', ' ') || 'N/A'}\n </H5>\n </Card>\n\n <Card elevation={1} css={css`flex: 30%; padding: 11px;`}>\n {getPastTransitions(cr).map(([key, el], idx) =>\n <React.Fragment key={key}>\n {idx !== 0 ? <Divider /> : null}\n <FormGroup label={`${key}:`}>\n <div\n css={css`white-space: pre-wrap;`}\n className={Classes.RUNNING_TEXT}>\n {el}\n </div>\n </FormGroup>\n </React.Fragment>\n )}\n </Card>\n\n {canTransition\n ? <Card elevation={3} css={css`flex: 30%; padding: 11px;`}>\n <TransitionOptions cr={cr} />\n </Card>\n : null}\n </div>}\n />\n );\n } else {\n return <NonIdealState\n icon={<Spinner />}\n className={className}\n description={helmet}\n />;\n }\n};\n\n\nconst CRActivation: React.FC<{\n isActive: boolean;\n htmlTitle?: string;\n\n /** Labels for the “activate” and “deactivate” buttons. */\n labels?: { activate?: string, deactivate?: string };\n\n onChangeActiveStatus?: (newStatus: boolean) => void;\n}> = function ({ isActive, htmlTitle, labels, onChangeActiveStatus }) {\n return onChangeActiveStatus && isActive\n ? <Button\n title={htmlTitle}\n intent=\"warning\"\n disabled={!onChangeActiveStatus}\n onClick={() => onChangeActiveStatus?.(false)}>\n {labels?.deactivate ?? \"Exit proposal\"}\n </Button>\n : <Button\n title={htmlTitle}\n intent={onChangeActiveStatus ? 'primary' : undefined}\n disabled={!onChangeActiveStatus}\n onClick={() => onChangeActiveStatus?.(true)}>\n {labels?.activate ?? \"Enter proposal\"}\n </Button>;\n};\n\n\nconst CRTitle: React.FC<{ uri: string }> = function ({ uri }) {\n const { useObjectData } = useContext(DatasetContext);\n const justification = useObjectData({ objectPaths: [uri] }).value.data?.[uri]?.justification;\n return <>Proposal “{maybeEllipsizeString(justification ?? uri)}”</>;\n}\n\nexport default { main: View, title: CRTitle, plainTitle: async (uri: string) => `proposal ${uri}` };\n"]}
@@ -52,7 +52,7 @@ const TransitionOptions = function ({
52
52
  usePersistentDatasetStateReducer
53
53
  } = (0, _react.useContext)(_context.DatasetContext);
54
54
  const isBusy = operationKey !== undefined;
55
- const transitions = (0, _react.useMemo)(() => stakeholder ? getTransitions(cr, stakeholder) : [], [JSON.stringify(stakeholder), cr === null || cr === void 0 ? void 0 : cr.id, cr === null || cr === void 0 ? void 0 : cr.state]);
55
+ const transitions = (0, _react.useMemo)(() => stakeholder ? getTransitions(cr, stakeholder) : [], [JSON.stringify(stakeholder), JSON.stringify(cr)]);
56
56
  const initialState = {
57
57
  // Pre-select next state to first available transition
58
58
  chosenNextState: transitions.length > 0 ? transitions[0][0] : undefined,
@@ -105,12 +105,12 @@ const TransitionOptions = function ({
105
105
  const getItemChangesetAsApproved = (0, _react.useCallback)(async function (cr) {
106
106
  const origItemData = (await getObjectData({
107
107
  objectPaths: [...Object.entries(cr.items).filter(([, prop]) => prop.type !== 'addition').map(([itemPath]) => itemPath), ...Object.values(cr.items).filter(prop => prop.type === 'amendment' && prop.amendmentType === 'supersession').flatMap(prop => prop.supersedingItemIDs)]
108
- })).data;
109
- console.debug("Got orig item data", origItemData);
108
+ })).data; //console.debug("Got orig item data", origItemData);
109
+
110
110
  const newItemData = (await getObjectData({
111
111
  objectPaths: Object.entries(cr.items).filter(([, prop]) => prop.type === 'clarification' || prop.type === 'addition').map(([itemPath]) => (0, _itemPathUtils.itemPathInCR)(itemPath, cr.id))
112
- })).data;
113
- console.debug("Got new item data", newItemData);
112
+ })).data; //console.debug("Got new item data", newItemData);
113
+
114
114
  return await (0, _objectChangeset.proposalsToObjectChangeset)(cr.id, subregisters !== undefined, cr.items, origItemData, newItemData);
115
115
  }, [JSON.stringify(cr), JSON.stringify(subregisters)]);
116
116
  const handleTransition = (0, _react.useCallback)(async function (transitionCfg, stateInput) {
@@ -181,17 +181,15 @@ function getPastTransitions(cr) {
181
181
  const els = [];
182
182
 
183
183
  if (CR.hasSubmitterInput(cr)) {
184
- els.push(['Submitter input', (0, _react2.jsx)(_react.default.Fragment, null, cr.justification)]);
184
+ els.push(['Submitter’s justification', (0, _react2.jsx)(_react.default.Fragment, null, cr.justification)]);
185
185
  }
186
186
 
187
187
  if (CR.hasRegisterManagerInput(cr)) {
188
- els.push(['Register manager notes', (0, _react2.jsx)(_react.default.Fragment, null, cr.registerManagerNotes)]);
188
+ els.push(['Register manager’s notes', (0, _react2.jsx)(_react.default.Fragment, null, cr.registerManagerNotes)]);
189
189
  }
190
190
 
191
191
  if (CR.hasControlBodyInput(cr)) {
192
- els.push(['Control body input', (0, _react2.jsx)(_react.default.Fragment, null, cr.controlBodyNotes, (0, _react2.jsx)("br", null), (0, _react2.jsx)("em", {
193
- css: (0, _react2.css)`display: block;`
194
- }, "Decision event: ", cr.controlBodyDecisionEvent))]);
192
+ els.push(['Control body decision', (0, _react2.jsx)(_react.default.Fragment, null, cr.controlBodyNotes)]);
195
193
  }
196
194
 
197
195
  if (CR.hasAppealRequest(cr)) {
@@ -226,63 +224,29 @@ function getTransitions(cr, stakeholder) {
226
224
 
227
225
  function isFinalState(state) {
228
226
  return Object.keys(TRANSITIONS[state] ?? {}).length < 1;
229
- } // Transition runtime implementation
230
- // const draft: CR.Transition<
231
- // | CR.ReturnedForClarificationByControlBody
232
- // | CR.ReturnedForClarificationByManager
233
- // | CR.Drafted,
234
- // CR.Drafted,
235
- // CR.SubmitterInput> =
236
- // function (cr, { justification, items }) {
237
- // return {
238
- // ...cr,
239
- // justification,
240
- // timeEdited: new Date(),
241
- // items,
242
- // };
243
- // }
244
- //
245
- // const withdraw: CR.Transition<
246
- // CR.Proposed
247
- // | CR.SubmittedForControlBodyReview
248
- // | CR.ReturnedForClarificationByControlBody
249
- // | CR.ReturnedForClarificationByManager,
250
- // CR.Withdrawn> =
251
- // function withdraw (cr) {
252
- // return {
253
- // ...cr,
254
- // timeDisposed: new Date(),
255
- // };
256
- // }
257
-
227
+ }
258
228
 
259
229
  const applyRegisterManagerDecision = function applyRegisterManagerDecision(cr, {
260
230
  registerManagerNotes
261
231
  }) {
262
- if (!(registerManagerNotes !== null && registerManagerNotes !== void 0 && registerManagerNotes.trim())) {
263
- throw new Error("Register manager note is required.");
264
- }
265
-
266
232
  return { ...cr,
267
- registerManagerNotes
233
+ registerManagerNotes: registerManagerNotes ?? ''
268
234
  };
269
235
  };
270
236
 
271
237
  const applyControlBodyDecision = function applyControlBodyDecision(cr, {
272
- controlBodyNotes,
273
- controlBodyDecisionEvent
238
+ controlBodyNotes
274
239
  }) {
275
- if (!(controlBodyNotes !== null && controlBodyNotes !== void 0 && controlBodyNotes.trim()) || !(controlBodyDecisionEvent !== null && controlBodyDecisionEvent !== void 0 && controlBodyDecisionEvent.trim())) {
276
- throw new Error("Control body notes and decision event are required.");
240
+ if (!(controlBodyNotes !== null && controlBodyNotes !== void 0 && controlBodyNotes.trim())) {
241
+ throw new Error("Control body decision is required.");
277
242
  }
278
243
 
279
244
  return { ...cr,
280
- controlBodyNotes,
281
- controlBodyDecisionEvent
245
+ controlBodyNotes
282
246
  };
283
247
  };
284
248
 
285
- const applyAppeal = function applyRegisterManagerDecision(cr, {
249
+ const applyAppeal = function applyAppeal(cr, {
286
250
  appealReason
287
251
  }) {
288
252
  if (!(appealReason !== null && appealReason !== void 0 && appealReason.trim())) {
@@ -295,7 +259,7 @@ const applyAppeal = function applyRegisterManagerDecision(cr, {
295
259
  };
296
260
  };
297
261
 
298
- const applyRegisterOwnerDecision = function applyRegisterManagerDecision(cr, {
262
+ const applyRegisterOwnerDecision = function applyRegisterOwnerDecision(cr, {
299
263
  registerOwnerNotes
300
264
  }) {
301
265
  if (!(registerOwnerNotes !== null && registerOwnerNotes !== void 0 && registerOwnerNotes.trim())) {
@@ -312,7 +276,7 @@ const WITHDRAWAL_TRANSITION = {
312
276
  title: "Withdraw",
313
277
  targetState: CR.State.WITHDRAWN,
314
278
  Widget: null,
315
- canBeTransitionedBy: CR.isSubmittedBy,
279
+ canBeTransitionedBy: (stakeholder, cr) => cr.timeProposed && CR.isSubmittedBy(stakeholder, cr),
316
280
  func: cr => ({ ...cr,
317
281
  timeDisposed: new Date()
318
282
  })
@@ -380,25 +344,15 @@ const ControlBodyNotesWidget = function ({
380
344
  value,
381
345
  onChange
382
346
  }) {
383
- return (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.FormGroup, {
384
- label: "Control body notes:"
347
+ return (0, _react2.jsx)(_core.FormGroup, {
348
+ label: "Control body decision:"
385
349
  }, (0, _react2.jsx)(TransitionInputTextArea, {
386
350
  value: value.controlBodyNotes,
387
351
  required: true,
388
352
  onChange: evt => onChange === null || onChange === void 0 ? void 0 : onChange({
389
- controlBodyNotes: evt.currentTarget.value,
390
- controlBodyDecisionEvent: value.controlBodyDecisionEvent
353
+ controlBodyNotes: evt.currentTarget.value
391
354
  })
392
- })), (0, _react2.jsx)(_core.FormGroup, {
393
- label: "Control body decision event:"
394
- }, (0, _react2.jsx)(TransitionInputTextArea, {
395
- value: value.controlBodyDecisionEvent,
396
- required: true,
397
- onChange: evt => onChange === null || onChange === void 0 ? void 0 : onChange({
398
- controlBodyNotes: value.controlBodyNotes,
399
- controlBodyDecisionEvent: evt.currentTarget.value
400
- })
401
- })));
355
+ }));
402
356
  };
403
357
 
404
358
  const AppealRequestWidget = function ({
@@ -442,6 +396,7 @@ const STATE_INTENT = {
442
396
  exports.STATE_INTENT = STATE_INTENT;
443
397
  const TRANSITIONS = {
444
398
  [CR.State.DRAFT]: {
399
+ [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,
445
400
  [CR.State.PROPOSED]: PROPOSAL_TRANSITION
446
401
  },
447
402
  [CR.State.PROPOSED]: {
@@ -458,7 +413,13 @@ const TRANSITIONS = {
458
413
  targetState: CR.State.RETURNED_FOR_CLARIFICATION,
459
414
  canBeTransitionedBy: stakeholder => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,
460
415
  Widget: RegisterManagerNotesWidget,
461
- func: applyRegisterManagerDecision
416
+ func: function applyRegisterManagerReturnDecision(cr, payload) {
417
+ if ((payload.registerManagerNotes ?? '').trim() === '') {
418
+ throw new Error("Register manager notes are required if returning for clarification");
419
+ }
420
+
421
+ return applyRegisterManagerDecision(cr, payload);
422
+ }
462
423
  }
463
424
  },
464
425
  [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {
@@ -1 +1 @@
1
- {"version":3,"file":"transitions.js","sourceRoot":"","sources":["../../../../src/views/detail/ChangeRequest/transitions.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useEffect, useMemo, useCallback } from 'react';\nimport { jsx, css } from '@emotion/react';\nimport { Button, RadioGroup, Radio, FormGroup, TextArea, TextAreaProps, Intent } from '@blueprintjs/core';\nimport { Tooltip2 as Tooltip } from '@blueprintjs/popover2';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport type { PersistentStateReducerHook } from '@riboseinc/paneron-extension-kit/usePersistentStateReducer';\nimport type { ObjectChangeset } from '@riboseinc/paneron-extension-kit/types/objects';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport type { RegisterItem, RegisterStakeholder, Supersession } from '../../../types';\nimport { itemPathInCR, crIDToCRPath } from '../../itemPathUtils';\nimport * as CR from '../../../types/cr';\nimport { proposalsToObjectChangeset } from '../../change-request/objectChangeset';\n\n\n// XXX: simplify\n//type TransitionInputWidget<TO extends BaseCR, FROM extends BaseCR> =\n// TO[\"state\"] extends keyof Transitions\n// ? FROM[\"state\"] extends keyof Transitions[TO[\"state\"]]\n// ? Transitions[TO[\"state\"]][FROM[\"state\"]] extends Transition<any, any, infer P>\n// ? React.FC<{\n// inputData: P;\n// onConfirm: (inputData: P) => Promise<void>;\n// }>\n// : never\n// : never\n// : never\n\n// type TransitionInputWidget<P extends Record<string, any> | undefined> =\n// React.FC<{\n// //inputData: P;\n// onConfirm: (inputData: P) => Promise<void>;\n// }>\n// \n// \n// type TransitionWidgetConfiguration<T> =\n// T extends Transition<infer C, infer C2, infer P>\n// ? {\n// title: JSX.Element | string\n// hint?: JSX.Element | string\n// Widget: TransitionInputWidget<P>;\n// stakeholderCanTransition: (stakeholder: RegisterStakeholder, cr: C) => boolean;\n// typeGuard: (c: BaseCR) => c is C;\n// targetState: C2[\"state\"];\n// }\n// : never\n// \n// //const SubmitterInput: TransitionInputWidget<SubmitterInput> = function ({ inputData, onConfirm }) {\n// // return <></>;\n// //}\n// \n// const ProposalInput: TransitionInputWidget<SubmitterInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// const DraftInput: TransitionInputWidget<SubmitterInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// const SubmitToControlBodyInput: TransitionInputWidget<RegisterManagerInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// //type C = Transitions[typeof State.DRAFT][typeof State.PROPOSED]\n// \n// const propose: TransitionWidgetConfiguration<Transitions[typeof State.DRAFT][typeof State.PROPOSED]> = {\n// Widget: ProposalInput,\n// title: \"Propose\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isDrafted,\n// targetState: State.PROPOSED,\n// };\n// const updateDraft: TransitionWidgetConfiguration<Transitions[typeof State.DRAFT][typeof State.DRAFT]> = {\n// Widget: DraftInput,\n// title: \"Update draft\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isDrafted,\n// targetState: State.DRAFT,\n// };\n// const submitToControlBody: TransitionWidgetConfiguration<Transitions[typeof State.PROPOSED][typeof State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]> = {\n// Widget: SubmitToControlBodyInput,\n// title: \"Update draft\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isProposed,\n// targetState: State.SUBMITTED_FOR_CONTROL_BODY_REVIEW,\n// };\n// \n// const options = [updateDraft, propose, submitToControlBody];\n// \n// const RegisterManagerInput: TransitionInputWidget<RegisterManagerInput> = function ({ onConfirm }) {\n// return (\n// <FormGroup label=\"Content summary:\">\n// <TextArea\n// fill\n// value={value.contentSummary || ''} readOnly={!onChange}\n// onChange={handleSummaryChange} />\n// </FormGroup>\n// );\n// }\n//type TransitionWidgetsConfiguration = {\n// [Statuses in `${keyof Transitions}_${keyof Transitions}`]:\n// Statuses extends `${infer F}_${infer T}`\n// ? F extends keyof Transitions\n// ? T extends keyof Transitions[F]\n// ? TransitionWidgetConfiguration<Transitions[F][T]>\n// : never\n// : never\n// : never\n//}\n\ninterface State {\n chosenNextState?: CR.StateType;\n\n /**\n * Can contain any fields. Upon transition,\n * they will be validated against selected `chosenNextState`.\n */\n stateInput: Partial<CR.StateInput>;\n}\n\ntype Action =\n | { type: 'unset-next-state' }\n | { type: 'choose-next-state'; payload: { state: CR.StateType } }\n | { type: 'update-next-state-input'; payload: Record<string, any> }\n\n//export const TransitionOptions: C extends CR.Base ? C[\"state\"] extends keyof CR.Transitions ? React.FC<{ cr: CR.Base }> : never : never = function ({ cr }) {\nexport const TransitionOptions: React.FC<{ cr: CR.Base, className?: string }> =\nfunction ({ cr, className }) {\n const { stakeholder, subregisters } = useContext(BrowserCtx);\n const {\n getObjectData,\n updateObjects,\n performOperation,\n operationKey,\n usePersistentDatasetStateReducer,\n } = useContext(DatasetContext);\n\n const isBusy = operationKey !== undefined;\n\n const transitions = useMemo((\n () => stakeholder\n ? getTransitions(cr, stakeholder)\n : []\n ), [JSON.stringify(stakeholder), cr?.id, cr?.state]);\n\n const initialState: State = {\n // Pre-select next state to first available transition\n chosenNextState: transitions.length > 0\n ? transitions[0][0]\n : undefined,\n stateInput: {},\n };\n\n const [ state, dispatch, stateRecalled ] =\n (usePersistentDatasetStateReducer as PersistentStateReducerHook<State, Action>)(\n `${cr.id}-${cr.state}`,\n undefined,\n undefined,\n (prevState, action) => {\n switch (action.type) {\n case 'unset-next-state':\n return {\n ...prevState,\n chosenNextState: undefined,\n };\n case 'choose-next-state':\n return {\n ...prevState,\n chosenNextState: action.payload.state,\n };\n case 'update-next-state-input':\n return {\n ...prevState,\n stateInput: action.payload,\n };\n default:\n throw new Error(\"Unexpected state\");\n }\n },\n initialState,\n null);\n\n const selectedTransitionCfg = (stateRecalled && state.chosenNextState\n ? transitions.find(([t, ]) => t === state.chosenNextState)?.[1]\n : undefined\n ) ?? undefined;\n\n useEffect(() => {\n if (stateRecalled && state.chosenNextState) {\n if (!selectedTransitionCfg) {\n dispatch({ type: 'unset-next-state' });\n }\n }\n }, [\n stateRecalled,\n state.chosenNextState,\n JSON.stringify(selectedTransitionCfg),\n ]);\n\n const [validatedStateInput, stateInputValidationErrors]:\n [CR.StateInput, undefined] | [undefined, string] =\n useMemo(() => {\n if (cr && selectedTransitionCfg) {\n try {\n selectedTransitionCfg.func(cr, state.stateInput);\n } catch (e) {\n return [undefined, (e as any).message ?? `${e}`];\n }\n return [state.stateInput as CR.StateInput, undefined];\n } else {\n return [undefined, \"no CR or no transition selected\"];\n }\n }, [JSON.stringify(cr), JSON.stringify(selectedTransitionCfg), JSON.stringify(state.stateInput)]);\n\n const getItemChangesetAsApproved = useCallback(\n async function (cr: CR.Accepted | CR.AcceptedOnAppeal): Promise<ObjectChangeset> {\n const origItemData = (await getObjectData({\n objectPaths: [\n ...Object.entries(cr.items).\n filter(([, prop]) => prop.type !== 'addition').\n map(([itemPath, ]) => itemPath),\n ...Object.values(cr.items).\n filter(prop => prop.type === 'amendment' && prop.amendmentType === 'supersession').\n flatMap(prop => (prop as Supersession).supersedingItemIDs),\n ],\n })).data as Record<string, RegisterItem<any> | null>;\n console.debug(\"Got orig item data\", origItemData);\n const newItemData = (await getObjectData({\n objectPaths: Object.entries(cr.items).\n filter(([, prop]) => prop.type === 'clarification' || prop.type === 'addition').\n map(([itemPath, ]) => itemPathInCR(itemPath, cr.id)),\n })).data as Record<string, RegisterItem<any> | null>;\n console.debug(\"Got new item data\", newItemData);\n return await proposalsToObjectChangeset(\n cr.id,\n subregisters !== undefined,\n cr.items,\n origItemData,\n newItemData);\n }, [JSON.stringify(cr), JSON.stringify(subregisters)]);\n\n const handleTransition = useCallback(\n async function (transitionCfg: typeof selectedTransitionCfg, stateInput: CR.StateInput) {\n if (transitionCfg && updateObjects && stakeholder && transitionCfg.canBeTransitionedBy(stakeholder, cr)) {\n const newCR = {\n ...(transitionCfg.func(cr, stateInput) as Omit<CR.SomeCR, 'state'>),\n state: transitionCfg.targetState,\n };\n //console.debug(\"Transitioning CR\", JSON.stringify(cr), JSON.stringify(newCR));\n const changeset: ObjectChangeset = {\n [crIDToCRPath(cr.id)]: {\n oldValue: cr,\n newValue: newCR,\n },\n };\n if (CR.isAccepted(newCR) || CR.isAcceptedOnAppeal(newCR)) {\n Object.assign(changeset, await getItemChangesetAsApproved(newCR));\n }\n await updateObjects({\n commitMessage: `${transitionCfg.title} CR`,\n objectChangeset: changeset,\n });\n } else {\n throw new Error(\"Either transition is not specified or dataset is read-only\");\n }\n }, [updateObjects, JSON.stringify(stakeholder), JSON.stringify(cr)]);\n\n const canTransition = selectedTransitionCfg !== undefined && !isBusy && validatedStateInput !== undefined;\n\n return (\n <div css={css`display: flex; flex-flow: column nowrap;`} className={className}>\n {transitions.length > 0\n ? <RadioGroup\n selectedValue={state.chosenNextState}\n onChange={(evt) => CR.isState(evt.currentTarget.value)\n ? dispatch({\n type: 'choose-next-state',\n payload: { state: evt.currentTarget.value },\n })\n : void 0}>\n {transitions.map(([state, cfg]) => \n <Radio\n key={state}\n label={cfg.title}\n value={state}\n disabled={isBusy}\n large\n />\n )}\n </RadioGroup>\n : null}\n {selectedTransitionCfg?.Widget\n ? <Tooltip\n isOpen={stateInputValidationErrors !== undefined}\n placement='bottom'\n targetTagName='div'\n intent='warning'\n content={<>{stateInputValidationErrors}</>}>\n <selectedTransitionCfg.Widget\n value={Object.keys(state.stateInput).length > 0\n ? state.stateInput\n : cr}\n onChange={!isBusy\n ? (payload) => dispatch({\n type: 'update-next-state-input',\n payload,\n })\n : undefined}\n />\n </Tooltip>\n : null}\n {selectedTransitionCfg\n ? <Button\n disabled={!canTransition}\n intent={canTransition ? 'primary' : undefined}\n onClick={() =>\n validatedStateInput\n ? performOperation('transitioning CR state', handleTransition)\n (selectedTransitionCfg, validatedStateInput)\n : void 0\n }>\n {selectedTransitionCfg.title}\n </Button>\n : null}\n </div>\n );\n};\n\n\nexport function getPastTransitions(cr: CR.Base): [key: string, el: JSX.Element][] {\n const els: [key: string, el: JSX.Element][] = [];\n if (CR.hasSubmitterInput(cr)) {\n els.push(['Submitter input', <>{cr.justification}</>]);\n }\n if (CR.hasRegisterManagerInput(cr)) {\n els.push(['Register manager notes', <>{cr.registerManagerNotes}</>]);\n }\n if (CR.hasControlBodyInput(cr)) {\n els.push([\n 'Control body input',\n <>\n {cr.controlBodyNotes}\n <br />\n <em css={css`display: block;`}>Decision event: {cr.controlBodyDecisionEvent}</em>\n </>\n ]);\n }\n if (CR.hasAppealRequest(cr)) {\n els.push(['Reason for appeal', <>{cr.appealReason}</>]);\n }\n if (CR.hasRegisterOwnerInput(cr)) {\n els.push(['Register owner notes', <>{cr.registerOwnerNotes}</>]);\n }\n return els;\n}\n\n//export const PastTransitions: React.FC<{ cr: CR.Base }> = function ({ cr }) {\n// const els: JSX.Element[] = [];\n// if (CR.hasSubmitterInput(cr)) {\n// els.push(<SubmitterInputWidget value={cr} />);\n// }\n// if (CR.hasRegisterManagerInput(cr)) {\n// els.push(<RegisterManagerNotesWidget value={cr} />);\n// }\n// if (CR.hasControlBodyInput(cr)) {\n// els.push(<ControlBodyNotesWidget value={cr} />);\n// }\n// if (CR.hasAppealRequest(cr)) {\n// els.push(<AppealRequestWidget value={cr} />);\n// }\n// if (CR.hasRegisterOwnerInput(cr)) {\n// els.push(<RegisterOwnerNotesWidget value={cr} />);\n// }\n// return <>{els}</>;\n//}\n\n\ntype PossibleTransitionForCR<CR extends CR.Base> = [\n targetState: CR.StateType,\n cfg: CR.TransitionConfig<CR, CR.SomeCR, any>,\n];\n\n/**\n * Returns a list of transitions\n * that can be performed on given CR by given stakeholder.\n */\nexport function getTransitions<CR extends CR.Base>(\n cr: CR,\n stakeholder: RegisterStakeholder,\n): PossibleTransitionForCR<CR>[] {\n const possibleTransitions = TRANSITIONS[cr.state as keyof CR.Transitions];\n if (possibleTransitions) {\n return (\n (Object.entries(possibleTransitions) as PossibleTransitionForCR<CR>[]).\n filter(([, t]) => t.canBeTransitionedBy(stakeholder, cr))\n );\n } else {\n return [];\n }\n}\n\n\n/**\n * Returns True if there is no possible transition for given state.\n */\nexport function isFinalState(state: CR.StateType): boolean {\n return (Object.keys(TRANSITIONS[state as keyof CR.Transitions] ?? {})).length < 1;\n}\n\n\n// Transition runtime implementation\n\n// const draft: CR.Transition<\n// | CR.ReturnedForClarificationByControlBody\n// | CR.ReturnedForClarificationByManager\n// | CR.Drafted,\n// CR.Drafted,\n// CR.SubmitterInput> =\n// function (cr, { justification, items }) {\n// return {\n// ...cr,\n// justification,\n// timeEdited: new Date(),\n// items,\n// };\n// }\n// \n// const withdraw: CR.Transition<\n// CR.Proposed\n// | CR.SubmittedForControlBodyReview\n// | CR.ReturnedForClarificationByControlBody\n// | CR.ReturnedForClarificationByManager,\n// CR.Withdrawn> =\n// function withdraw (cr) {\n// return {\n// ...cr,\n// timeDisposed: new Date(),\n// };\n// }\n\n\nconst applyRegisterManagerDecision: CR.Transition<\n CR.Proposed,\n CR.SubmittedForControlBodyReview\n| CR.ReturnedForClarificationByManager,\n CR.RegisterManagerInput> =\nfunction applyRegisterManagerDecision (cr, { registerManagerNotes }) {\n if (!registerManagerNotes?.trim()) {\n throw new Error(\"Register manager note is required.\");\n }\n return {\n ...cr,\n registerManagerNotes,\n };\n}\n\n\nconst applyControlBodyDecision: CR.Transition<\n CR.SubmittedForControlBodyReview,\n CR.Accepted\n| CR.Rejected\n| CR.ReturnedForClarificationByControlBody,\n CR.ControlBodyInput> =\nfunction applyControlBodyDecision (cr, { controlBodyNotes, controlBodyDecisionEvent }) {\n if (!controlBodyNotes?.trim() || !controlBodyDecisionEvent?.trim()) {\n throw new Error(\"Control body notes and decision event are required.\");\n }\n return {\n ...cr,\n controlBodyNotes,\n controlBodyDecisionEvent,\n };\n}\n\n\nconst applyAppeal: CR.Transition<\n CR.Rejected,\n CR.Appealed,\n CR.AppealRequest> =\nfunction applyRegisterManagerDecision (cr, { appealReason }) {\n if (!appealReason?.trim()) {\n throw new Error(\"Appeal reason is required.\");\n }\n return {\n ...cr,\n appealReason,\n timeDisposed: undefined,\n };\n}\n\n\nconst applyRegisterOwnerDecision: CR.Transition<\n CR.Appealed,\n CR.AcceptedOnAppeal\n| CR.RejectionUpheld,\n CR.RegisterOwnerInput> =\nfunction applyRegisterManagerDecision (cr, { registerOwnerNotes }) {\n if (!registerOwnerNotes?.trim()) {\n throw new Error(\"Register owner note is required.\");\n }\n return {\n ...cr,\n registerOwnerNotes,\n timeDisposed: new Date(),\n };\n}\n\n\nconst WITHDRAWAL_TRANSITION:\nCR.TransitionConfig<CR.Withdrawable, CR.Withdrawn, null> = {\n title: \"Withdraw\",\n targetState: CR.State.WITHDRAWN,\n Widget: null,\n canBeTransitionedBy: CR.isSubmittedBy,\n func: (cr: CR.Withdrawable) => ({\n ...cr,\n timeDisposed: new Date(),\n }),\n} as const;\n\n\nconst SubmitterInputWidget: React.FC<{\n value: CR.SubmitterInput\n onChange?: (newVal: CR.SubmitterInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Justification:\">\n <TransitionInputTextArea\n required\n value={value.justification}\n onChange={(evt) =>\n onChange?.({ justification: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst TransitionInputTextArea: React.FC<TextAreaProps> = function (props) {\n return <TextArea\n fill\n css={css`resize: vertical;`}\n readOnly={!props.onChange}\n {...props}\n />;\n};\n\n\nconst PROPOSAL_TRANSITION:\nCR.TransitionConfig<CR.Proposable, CR.Proposed, CR.SubmitterInput> = {\n title: \"Propose\",\n targetState: CR.State.PROPOSED,\n canBeTransitionedBy: ((stakeholder, cr) =>\n CR.isSubmittedBy(stakeholder, cr) && Object.keys(cr.items).length > 0\n ),\n Widget: SubmitterInputWidget,\n func: (cr, submitterInput) => {\n if (!submitterInput?.justification?.trim()) {\n throw new Error(\"Justification is required.\");\n }\n return {\n ...cr,\n ...submitterInput,\n timeProposed: new Date(),\n }\n },\n}\n\n\nconst RegisterManagerNotesWidget: React.FC<{\n value: CR.RegisterManagerInput\n onChange?: (newVal: CR.RegisterManagerInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Register manager notes:\">\n <TransitionInputTextArea\n value={value.registerManagerNotes}\n required\n onChange={evt =>\n onChange?.({ registerManagerNotes: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst ControlBodyNotesWidget: React.FC<{\n value: CR.ControlBodyInput\n onChange?: (newVal: CR.ControlBodyInput) => void\n}> = function ({ value, onChange }) {\n return (\n <>\n <FormGroup label=\"Control body notes:\">\n <TransitionInputTextArea\n value={value.controlBodyNotes}\n required\n onChange={evt =>\n onChange?.({\n controlBodyNotes: evt.currentTarget.value,\n controlBodyDecisionEvent: value.controlBodyDecisionEvent,\n })\n }\n />\n </FormGroup>\n <FormGroup label=\"Control body decision event:\">\n <TransitionInputTextArea\n value={value.controlBodyDecisionEvent}\n required\n onChange={evt =>\n onChange?.({\n controlBodyNotes: value.controlBodyNotes,\n controlBodyDecisionEvent: evt.currentTarget.value,\n })\n }\n />\n </FormGroup>\n </>\n );\n};\n\n\nconst AppealRequestWidget: React.FC<{\n value: CR.AppealRequest\n onChange?: (newVal: CR.AppealRequest) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Appeal reasoning:\">\n <TransitionInputTextArea\n value={value.appealReason}\n required\n onChange={evt =>\n onChange?.({ appealReason: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst RegisterOwnerNotesWidget: React.FC<{\n value: CR.RegisterOwnerInput\n onChange?: (newVal: CR.RegisterOwnerInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Register owner notes:\">\n <TransitionInputTextArea\n value={value.registerOwnerNotes}\n required\n onChange={evt =>\n onChange?.({ registerOwnerNotes: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nexport const STATE_INTENT: { [key in CR.StateType]?: Intent } = {\n [CR.State.PROPOSED]: 'primary',\n [CR.State.RETURNED_FOR_CLARIFICATION]: 'primary',\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: 'primary',\n [CR.State.APPEALED]: 'warning',\n};\n\n\n\n/** Associates transition implementation with source/target states. */\nconst TRANSITIONS: CR.Transitions = {\n [CR.State.DRAFT]: {\n [CR.State.PROPOSED]: PROPOSAL_TRANSITION,\n },\n [CR.State.PROPOSED]: {\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n title: \"Submit for control body review\",\n targetState: CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW,\n canBeTransitionedBy: (stakeholder) => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,\n Widget: RegisterManagerNotesWidget,\n func: applyRegisterManagerDecision,\n },\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n title: \"Return for clarification\",\n targetState: CR.State.RETURNED_FOR_CLARIFICATION,\n canBeTransitionedBy: (stakeholder) => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,\n Widget: RegisterManagerNotesWidget,\n func: applyRegisterManagerDecision,\n },\n },\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n title: \"Return for clarification\",\n targetState: CR.State.RETURNED_FOR_CLARIFICATION,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: applyControlBodyDecision,\n },\n [CR.State.ACCEPTED]: {\n title: \"Accept\",\n targetState: CR.State.ACCEPTED,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: (cr, controlBodyInput) => ({\n ...applyControlBodyDecision(cr, controlBodyInput),\n timeDisposed: new Date(),\n }),\n },\n [CR.State.REJECTED]: {\n title: \"Reject\",\n targetState: CR.State.REJECTED,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: (cr, controlBodyInput) => ({\n ...applyControlBodyDecision(cr, controlBodyInput),\n timeDisposed: new Date(),\n }),\n },\n },\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n [CR.State.PROPOSED]: PROPOSAL_TRANSITION,\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n },\n [CR.State.REJECTED]: {\n [CR.State.APPEALED]: {\n title: \"Appeal\",\n targetState: CR.State.APPEALED,\n canBeTransitionedBy: CR.isSubmittedBy,\n Widget: AppealRequestWidget,\n func: applyAppeal,\n },\n },\n [CR.State.APPEALED]: {\n [CR.State.APPEAL_WITHDRAWN]: {\n title: \"Withdraw appeal\",\n targetState: CR.State.APPEAL_WITHDRAWN,\n canBeTransitionedBy: CR.isSubmittedBy,\n Widget: null,\n func: (cr) => ({\n ...cr,\n timeDisposed: new Date(),\n }),\n },\n [CR.State.ACCEPTED_ON_APPEAL]: {\n title: \"Accept on appeal\",\n targetState: CR.State.ACCEPTED_ON_APPEAL,\n canBeTransitionedBy: (stakeholder) => stakeholder.role === 'owner',\n Widget: RegisterOwnerNotesWidget,\n func: applyRegisterOwnerDecision,\n },\n [CR.State.REJECTION_UPHELD_ON_APPEAL]: {\n title: \"Uphold rejection\",\n targetState: CR.State.REJECTION_UPHELD_ON_APPEAL,\n canBeTransitionedBy: (stakeholder) => stakeholder.role === 'owner',\n Widget: RegisterOwnerNotesWidget,\n func: applyRegisterOwnerDecision,\n },\n },\n} as const;\n"]}
1
+ {"version":3,"file":"transitions.js","sourceRoot":"","sources":["../../../../src/views/detail/ChangeRequest/transitions.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useEffect, useMemo, useCallback } from 'react';\nimport { jsx, css } from '@emotion/react';\nimport { Button, RadioGroup, Radio, FormGroup, TextArea, TextAreaProps, Intent } from '@blueprintjs/core';\nimport { Tooltip2 as Tooltip } from '@blueprintjs/popover2';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport type { PersistentStateReducerHook } from '@riboseinc/paneron-extension-kit/usePersistentStateReducer';\nimport type { ObjectChangeset } from '@riboseinc/paneron-extension-kit/types/objects';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport type { RegisterItem, RegisterStakeholder, Supersession } from '../../../types';\nimport { itemPathInCR, crIDToCRPath } from '../../itemPathUtils';\nimport * as CR from '../../../types/cr';\nimport { proposalsToObjectChangeset } from '../../change-request/objectChangeset';\n\n\n// XXX: simplify\n//type TransitionInputWidget<TO extends BaseCR, FROM extends BaseCR> =\n// TO[\"state\"] extends keyof Transitions\n// ? FROM[\"state\"] extends keyof Transitions[TO[\"state\"]]\n// ? Transitions[TO[\"state\"]][FROM[\"state\"]] extends Transition<any, any, infer P>\n// ? React.FC<{\n// inputData: P;\n// onConfirm: (inputData: P) => Promise<void>;\n// }>\n// : never\n// : never\n// : never\n\n// type TransitionInputWidget<P extends Record<string, any> | undefined> =\n// React.FC<{\n// //inputData: P;\n// onConfirm: (inputData: P) => Promise<void>;\n// }>\n// \n// \n// type TransitionWidgetConfiguration<T> =\n// T extends Transition<infer C, infer C2, infer P>\n// ? {\n// title: JSX.Element | string\n// hint?: JSX.Element | string\n// Widget: TransitionInputWidget<P>;\n// stakeholderCanTransition: (stakeholder: RegisterStakeholder, cr: C) => boolean;\n// typeGuard: (c: BaseCR) => c is C;\n// targetState: C2[\"state\"];\n// }\n// : never\n// \n// //const SubmitterInput: TransitionInputWidget<SubmitterInput> = function ({ inputData, onConfirm }) {\n// // return <></>;\n// //}\n// \n// const ProposalInput: TransitionInputWidget<SubmitterInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// const DraftInput: TransitionInputWidget<SubmitterInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// const SubmitToControlBodyInput: TransitionInputWidget<RegisterManagerInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// //type C = Transitions[typeof State.DRAFT][typeof State.PROPOSED]\n// \n// const propose: TransitionWidgetConfiguration<Transitions[typeof State.DRAFT][typeof State.PROPOSED]> = {\n// Widget: ProposalInput,\n// title: \"Propose\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isDrafted,\n// targetState: State.PROPOSED,\n// };\n// const updateDraft: TransitionWidgetConfiguration<Transitions[typeof State.DRAFT][typeof State.DRAFT]> = {\n// Widget: DraftInput,\n// title: \"Update draft\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isDrafted,\n// targetState: State.DRAFT,\n// };\n// const submitToControlBody: TransitionWidgetConfiguration<Transitions[typeof State.PROPOSED][typeof State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]> = {\n// Widget: SubmitToControlBodyInput,\n// title: \"Update draft\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isProposed,\n// targetState: State.SUBMITTED_FOR_CONTROL_BODY_REVIEW,\n// };\n// \n// const options = [updateDraft, propose, submitToControlBody];\n// \n// const RegisterManagerInput: TransitionInputWidget<RegisterManagerInput> = function ({ onConfirm }) {\n// return (\n// <FormGroup label=\"Content summary:\">\n// <TextArea\n// fill\n// value={value.contentSummary || ''} readOnly={!onChange}\n// onChange={handleSummaryChange} />\n// </FormGroup>\n// );\n// }\n//type TransitionWidgetsConfiguration = {\n// [Statuses in `${keyof Transitions}_${keyof Transitions}`]:\n// Statuses extends `${infer F}_${infer T}`\n// ? F extends keyof Transitions\n// ? T extends keyof Transitions[F]\n// ? TransitionWidgetConfiguration<Transitions[F][T]>\n// : never\n// : never\n// : never\n//}\n\ninterface State {\n chosenNextState?: CR.StateType;\n\n /**\n * Can contain any fields. Upon transition,\n * they will be validated against selected `chosenNextState`.\n */\n stateInput: Partial<CR.StateInput>;\n}\n\ntype Action =\n | { type: 'unset-next-state' }\n | { type: 'choose-next-state'; payload: { state: CR.StateType } }\n | { type: 'update-next-state-input'; payload: Record<string, any> }\n\n//export const TransitionOptions: C extends CR.Base ? C[\"state\"] extends keyof CR.Transitions ? React.FC<{ cr: CR.Base }> : never : never = function ({ cr }) {\nexport const TransitionOptions: React.FC<{ cr: CR.Base, className?: string }> =\nfunction ({ cr, className }) {\n const { stakeholder, subregisters } = useContext(BrowserCtx);\n const {\n getObjectData,\n updateObjects,\n performOperation,\n operationKey,\n usePersistentDatasetStateReducer,\n } = useContext(DatasetContext);\n\n const isBusy = operationKey !== undefined;\n\n const transitions = useMemo((\n () => stakeholder\n ? getTransitions(cr, stakeholder)\n : []\n ), [JSON.stringify(stakeholder), JSON.stringify(cr)]);\n\n const initialState: State = {\n // Pre-select next state to first available transition\n chosenNextState: transitions.length > 0\n ? transitions[0][0]\n : undefined,\n stateInput: {},\n };\n\n const [ state, dispatch, stateRecalled ] =\n (usePersistentDatasetStateReducer as PersistentStateReducerHook<State, Action>)(\n `${cr.id}-${cr.state}`,\n undefined,\n undefined,\n (prevState, action) => {\n switch (action.type) {\n case 'unset-next-state':\n return {\n ...prevState,\n chosenNextState: undefined,\n };\n case 'choose-next-state':\n return {\n ...prevState,\n chosenNextState: action.payload.state,\n };\n case 'update-next-state-input':\n return {\n ...prevState,\n stateInput: action.payload,\n };\n default:\n throw new Error(\"Unexpected state\");\n }\n },\n initialState,\n null);\n\n const selectedTransitionCfg = (stateRecalled && state.chosenNextState\n ? transitions.find(([t, ]) => t === state.chosenNextState)?.[1]\n : undefined\n ) ?? undefined;\n\n useEffect(() => {\n if (stateRecalled && state.chosenNextState) {\n if (!selectedTransitionCfg) {\n dispatch({ type: 'unset-next-state' });\n }\n }\n }, [\n stateRecalled,\n state.chosenNextState,\n JSON.stringify(selectedTransitionCfg),\n ]);\n\n const [validatedStateInput, stateInputValidationErrors]:\n [CR.StateInput, undefined] | [undefined, string] =\n useMemo(() => {\n if (cr && selectedTransitionCfg) {\n try {\n selectedTransitionCfg.func(cr, state.stateInput);\n } catch (e) {\n return [undefined, (e as any).message ?? `${e}`];\n }\n return [state.stateInput as CR.StateInput, undefined];\n } else {\n return [undefined, \"no CR or no transition selected\"];\n }\n }, [JSON.stringify(cr), JSON.stringify(selectedTransitionCfg), JSON.stringify(state.stateInput)]);\n\n const getItemChangesetAsApproved = useCallback(\n async function (cr: CR.Accepted | CR.AcceptedOnAppeal): Promise<ObjectChangeset> {\n const origItemData = (await getObjectData({\n objectPaths: [\n ...Object.entries(cr.items).\n filter(([, prop]) => prop.type !== 'addition').\n map(([itemPath, ]) => itemPath),\n ...Object.values(cr.items).\n filter(prop => prop.type === 'amendment' && prop.amendmentType === 'supersession').\n flatMap(prop => (prop as Supersession).supersedingItemIDs),\n ],\n })).data as Record<string, RegisterItem<any> | null>;\n //console.debug(\"Got orig item data\", origItemData);\n const newItemData = (await getObjectData({\n objectPaths: Object.entries(cr.items).\n filter(([, prop]) => prop.type === 'clarification' || prop.type === 'addition').\n map(([itemPath, ]) => itemPathInCR(itemPath, cr.id)),\n })).data as Record<string, RegisterItem<any> | null>;\n //console.debug(\"Got new item data\", newItemData);\n return await proposalsToObjectChangeset(\n cr.id,\n subregisters !== undefined,\n cr.items,\n origItemData,\n newItemData);\n }, [JSON.stringify(cr), JSON.stringify(subregisters)]);\n\n const handleTransition = useCallback(\n async function (transitionCfg: typeof selectedTransitionCfg, stateInput: CR.StateInput) {\n if (transitionCfg && updateObjects && stakeholder && transitionCfg.canBeTransitionedBy(stakeholder, cr)) {\n const newCR = {\n ...(transitionCfg.func(cr, stateInput) as Omit<CR.SomeCR, 'state'>),\n state: transitionCfg.targetState,\n };\n //console.debug(\"Transitioning CR\", JSON.stringify(cr), JSON.stringify(newCR));\n const changeset: ObjectChangeset = {\n [crIDToCRPath(cr.id)]: {\n oldValue: cr,\n newValue: newCR,\n },\n };\n if (CR.isAccepted(newCR) || CR.isAcceptedOnAppeal(newCR)) {\n Object.assign(changeset, await getItemChangesetAsApproved(newCR));\n }\n await updateObjects({\n commitMessage: `${transitionCfg.title} CR`,\n objectChangeset: changeset,\n });\n } else {\n throw new Error(\"Either transition is not specified or dataset is read-only\");\n }\n }, [updateObjects, JSON.stringify(stakeholder), JSON.stringify(cr)]);\n\n const canTransition = selectedTransitionCfg !== undefined && !isBusy && validatedStateInput !== undefined;\n\n return (\n <div css={css`display: flex; flex-flow: column nowrap;`} className={className}>\n {transitions.length > 0\n ? <RadioGroup\n selectedValue={state.chosenNextState}\n onChange={(evt) => CR.isState(evt.currentTarget.value)\n ? dispatch({\n type: 'choose-next-state',\n payload: { state: evt.currentTarget.value },\n })\n : void 0}>\n {transitions.map(([state, cfg]) => \n <Radio\n key={state}\n label={cfg.title}\n value={state}\n disabled={isBusy}\n large\n />\n )}\n </RadioGroup>\n : null}\n {selectedTransitionCfg?.Widget\n ? <Tooltip\n isOpen={stateInputValidationErrors !== undefined}\n placement='bottom'\n targetTagName='div'\n intent='warning'\n content={<>{stateInputValidationErrors}</>}>\n <selectedTransitionCfg.Widget\n value={Object.keys(state.stateInput).length > 0\n ? state.stateInput\n : cr}\n onChange={!isBusy\n ? (payload) => dispatch({\n type: 'update-next-state-input',\n payload,\n })\n : undefined}\n />\n </Tooltip>\n : null}\n {selectedTransitionCfg\n ? <Button\n disabled={!canTransition}\n intent={canTransition ? 'primary' : undefined}\n onClick={() =>\n validatedStateInput\n ? performOperation('transitioning CR state', handleTransition)\n (selectedTransitionCfg, validatedStateInput)\n : void 0\n }>\n {selectedTransitionCfg.title}\n </Button>\n : null}\n </div>\n );\n};\n\n\nexport function getPastTransitions(cr: CR.Base): [key: string, el: JSX.Element][] {\n const els: [key: string, el: JSX.Element][] = [];\n if (CR.hasSubmitterInput(cr)) {\n els.push(['Submitter’s justification', <>{cr.justification}</>]);\n }\n if (CR.hasRegisterManagerInput(cr)) {\n els.push(['Register manager’s notes', <>{cr.registerManagerNotes}</>]);\n }\n if (CR.hasControlBodyInput(cr)) {\n els.push(['Control body decision', <>{cr.controlBodyNotes}</>]);\n }\n if (CR.hasAppealRequest(cr)) {\n els.push(['Reason for appeal', <>{cr.appealReason}</>]);\n }\n if (CR.hasRegisterOwnerInput(cr)) {\n els.push(['Register owner notes', <>{cr.registerOwnerNotes}</>]);\n }\n return els;\n}\n\n//export const PastTransitions: React.FC<{ cr: CR.Base }> = function ({ cr }) {\n// const els: JSX.Element[] = [];\n// if (CR.hasSubmitterInput(cr)) {\n// els.push(<SubmitterInputWidget value={cr} />);\n// }\n// if (CR.hasRegisterManagerInput(cr)) {\n// els.push(<RegisterManagerNotesWidget value={cr} />);\n// }\n// if (CR.hasControlBodyInput(cr)) {\n// els.push(<ControlBodyNotesWidget value={cr} />);\n// }\n// if (CR.hasAppealRequest(cr)) {\n// els.push(<AppealRequestWidget value={cr} />);\n// }\n// if (CR.hasRegisterOwnerInput(cr)) {\n// els.push(<RegisterOwnerNotesWidget value={cr} />);\n// }\n// return <>{els}</>;\n//}\n\n\ntype PossibleTransitionForCR<CR extends CR.Base> = [\n targetState: CR.StateType,\n cfg: CR.TransitionConfig<CR, CR.SomeCR, any>,\n];\n\n/**\n * Returns a list of transitions\n * that can be performed on given CR by given stakeholder.\n */\nexport function getTransitions<CR extends CR.Base>(\n cr: CR,\n stakeholder: RegisterStakeholder,\n): PossibleTransitionForCR<CR>[] {\n const possibleTransitions = TRANSITIONS[cr.state as keyof CR.Transitions];\n if (possibleTransitions) {\n return (\n (Object.entries(possibleTransitions) as PossibleTransitionForCR<CR>[]).\n filter(([, t]) => t.canBeTransitionedBy(stakeholder, cr))\n );\n } else {\n return [];\n }\n}\n\n\n/**\n * Returns True if there is no possible transition for given state.\n */\nexport function isFinalState(state: CR.StateType): boolean {\n return (Object.keys(TRANSITIONS[state as keyof CR.Transitions] ?? {})).length < 1;\n}\n\n\nconst applyRegisterManagerDecision: CR.Transition<\n CR.Proposed,\n CR.SubmittedForControlBodyReview\n| CR.ReturnedForClarificationByManager,\n CR.RegisterManagerInput> =\nfunction applyRegisterManagerDecision (cr, { registerManagerNotes }) {\n return {\n ...cr,\n registerManagerNotes: registerManagerNotes ?? '',\n };\n}\n\n\nconst applyControlBodyDecision: CR.Transition<\n CR.SubmittedForControlBodyReview,\n CR.Accepted\n| CR.Rejected\n| CR.ReturnedForClarificationByControlBody,\n CR.ControlBodyInput> =\nfunction applyControlBodyDecision (cr, { controlBodyNotes }) {\n if (!controlBodyNotes?.trim()) {\n throw new Error(\"Control body decision is required.\");\n }\n return {\n ...cr,\n controlBodyNotes,\n };\n}\n\n\nconst applyAppeal: CR.Transition<\n CR.Rejected,\n CR.Appealed,\n CR.AppealRequest> =\nfunction applyAppeal (cr, { appealReason }) {\n if (!appealReason?.trim()) {\n throw new Error(\"Appeal reason is required.\");\n }\n return {\n ...cr,\n appealReason,\n timeDisposed: undefined,\n };\n}\n\n\nconst applyRegisterOwnerDecision: CR.Transition<\n CR.Appealed,\n CR.AcceptedOnAppeal\n| CR.RejectionUpheld,\n CR.RegisterOwnerInput> =\nfunction applyRegisterOwnerDecision (cr, { registerOwnerNotes }) {\n if (!registerOwnerNotes?.trim()) {\n throw new Error(\"Register owner note is required.\");\n }\n return {\n ...cr,\n registerOwnerNotes,\n timeDisposed: new Date(),\n };\n}\n\n\nconst WITHDRAWAL_TRANSITION:\nCR.TransitionConfig<CR.Withdrawable, CR.Withdrawn, null> = {\n title: \"Withdraw\",\n targetState: CR.State.WITHDRAWN,\n Widget: null,\n canBeTransitionedBy: (stakeholder, cr) => cr.timeProposed && CR.isSubmittedBy(stakeholder, cr),\n func: (cr: CR.Withdrawable) => ({\n ...cr,\n timeDisposed: new Date(),\n }),\n} as const;\n\n\nconst SubmitterInputWidget: React.FC<{\n value: CR.SubmitterInput\n onChange?: (newVal: CR.SubmitterInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Justification:\">\n <TransitionInputTextArea\n required\n value={value.justification}\n onChange={(evt) =>\n onChange?.({ justification: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst TransitionInputTextArea: React.FC<TextAreaProps> = function (props) {\n return <TextArea\n fill\n css={css`resize: vertical;`}\n readOnly={!props.onChange}\n {...props}\n />;\n};\n\n\nconst PROPOSAL_TRANSITION:\nCR.TransitionConfig<CR.Proposable, CR.Proposed, CR.SubmitterInput> = {\n title: \"Propose\",\n targetState: CR.State.PROPOSED,\n canBeTransitionedBy: ((stakeholder, cr) =>\n CR.isSubmittedBy(stakeholder, cr) && Object.keys(cr.items).length > 0\n ),\n Widget: SubmitterInputWidget,\n func: (cr, submitterInput) => {\n if (!submitterInput?.justification?.trim()) {\n throw new Error(\"Justification is required.\");\n }\n return {\n ...cr,\n ...submitterInput,\n timeProposed: new Date(),\n }\n },\n}\n\n\nconst RegisterManagerNotesWidget: React.FC<{\n value: CR.RegisterManagerInput\n onChange?: (newVal: CR.RegisterManagerInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Register manager notes:\">\n <TransitionInputTextArea\n value={value.registerManagerNotes}\n required\n onChange={evt =>\n onChange?.({ registerManagerNotes: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst ControlBodyNotesWidget: React.FC<{\n value: CR.ControlBodyInput\n onChange?: (newVal: CR.ControlBodyInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Control body decision:\">\n <TransitionInputTextArea\n value={value.controlBodyNotes}\n required\n onChange={evt =>\n onChange?.({\n controlBodyNotes: evt.currentTarget.value,\n })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst AppealRequestWidget: React.FC<{\n value: CR.AppealRequest\n onChange?: (newVal: CR.AppealRequest) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Appeal reasoning:\">\n <TransitionInputTextArea\n value={value.appealReason}\n required\n onChange={evt =>\n onChange?.({ appealReason: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst RegisterOwnerNotesWidget: React.FC<{\n value: CR.RegisterOwnerInput\n onChange?: (newVal: CR.RegisterOwnerInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Register owner notes:\">\n <TransitionInputTextArea\n value={value.registerOwnerNotes}\n required\n onChange={evt =>\n onChange?.({ registerOwnerNotes: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nexport const STATE_INTENT: { [key in CR.StateType]?: Intent } = {\n [CR.State.PROPOSED]: 'primary',\n [CR.State.RETURNED_FOR_CLARIFICATION]: 'primary',\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: 'primary',\n [CR.State.APPEALED]: 'warning',\n};\n\n\n\n/** Associates transition implementation with source/target states. */\nconst TRANSITIONS: CR.Transitions = {\n [CR.State.DRAFT]: {\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n [CR.State.PROPOSED]: PROPOSAL_TRANSITION,\n },\n [CR.State.PROPOSED]: {\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n title: \"Submit for control body review\",\n targetState: CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW,\n canBeTransitionedBy: (stakeholder) => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,\n Widget: RegisterManagerNotesWidget,\n func: applyRegisterManagerDecision,\n },\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n title: \"Return for clarification\",\n targetState: CR.State.RETURNED_FOR_CLARIFICATION,\n canBeTransitionedBy: (stakeholder) => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,\n Widget: RegisterManagerNotesWidget,\n func: function applyRegisterManagerReturnDecision(cr, payload) {\n if ((payload.registerManagerNotes ?? '').trim() === '') {\n throw new Error(\"Register manager notes are required if returning for clarification\");\n }\n return applyRegisterManagerDecision(cr, payload);\n },\n },\n },\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n title: \"Return for clarification\",\n targetState: CR.State.RETURNED_FOR_CLARIFICATION,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: applyControlBodyDecision,\n },\n [CR.State.ACCEPTED]: {\n title: \"Accept\",\n targetState: CR.State.ACCEPTED,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: (cr, controlBodyInput) => ({\n ...applyControlBodyDecision(cr, controlBodyInput),\n timeDisposed: new Date(),\n }),\n },\n [CR.State.REJECTED]: {\n title: \"Reject\",\n targetState: CR.State.REJECTED,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: (cr, controlBodyInput) => ({\n ...applyControlBodyDecision(cr, controlBodyInput),\n timeDisposed: new Date(),\n }),\n },\n },\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n [CR.State.PROPOSED]: PROPOSAL_TRANSITION,\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n },\n [CR.State.REJECTED]: {\n [CR.State.APPEALED]: {\n title: \"Appeal\",\n targetState: CR.State.APPEALED,\n canBeTransitionedBy: CR.isSubmittedBy,\n Widget: AppealRequestWidget,\n func: applyAppeal,\n },\n },\n [CR.State.APPEALED]: {\n [CR.State.APPEAL_WITHDRAWN]: {\n title: \"Withdraw appeal\",\n targetState: CR.State.APPEAL_WITHDRAWN,\n canBeTransitionedBy: CR.isSubmittedBy,\n Widget: null,\n func: (cr) => ({\n ...cr,\n timeDisposed: new Date(),\n }),\n },\n [CR.State.ACCEPTED_ON_APPEAL]: {\n title: \"Accept on appeal\",\n targetState: CR.State.ACCEPTED_ON_APPEAL,\n canBeTransitionedBy: (stakeholder) => stakeholder.role === 'owner',\n Widget: RegisterOwnerNotesWidget,\n func: applyRegisterOwnerDecision,\n },\n [CR.State.REJECTION_UPHELD_ON_APPEAL]: {\n title: \"Uphold rejection\",\n targetState: CR.State.REJECTION_UPHELD_ON_APPEAL,\n canBeTransitionedBy: (stakeholder) => stakeholder.role === 'owner',\n Widget: RegisterOwnerNotesWidget,\n func: applyRegisterOwnerDecision,\n },\n },\n} as const;\n"]}