Since #3610065 retired handler_url and the built-in review form, an operator or reviewer screen is now an interaction. The recurring shape is "render the thing being reviewed, then decide": one button per node outcome, with an optional or required note.

WebformInteraction review mode already hand-rolls exactly this. It renders the submission read-only and embeds CommentForm (through the form builder, carrying the context continuation handle and return URL) as the decision form. Downstream consumers need the same thing: a booking order-review that lost its screen when handler_url went must show the order before the operator approves or rejects it.

The wiring is identical every time: build a render array for the content, then embed CommentForm under it with the continuation handle and return URL. Nothing captures that pattern, so each interaction repeats both the embed and the comment configuration.

Proposed: an abstract ReviewInteractionBase in orchestra_interaction that owns the comment configuration (the required flag and comment_variable, as CommentInteraction does) and the embed, exposing one hook for the domain body:

abstract class ReviewInteractionBase extends InteractionBase implements ResultVariablesInterface {
  use CommentVariableTrait;
  // 'required' + 'comment_variable' config, as CommentInteraction has.

  // What is being reviewed: the subclass renders its domain content.
  abstract protected function reviewBody(InteractionContext $context): array;

  public function respond(InteractionContext $context): mixed {
    return [
      "body" => $this->reviewBody($context),
      "decide" => $this->formBuilder->getForm(
        CommentForm::class,
        $context->continuationHandle(),
        $context->returnUrl(),
        !empty($this->configuration["required"]),
      ),
    ];
  }
}

Because it embeds CommentForm, completion still flows through the context continuation handle, so the same subclass works under every doorway with no per-doorway code: a bearer capability link, an assigned interaction_task, or a pulled interaction_operation. It also fits the existing model, where a review is only a comment interaction with approved and rejected outcomes; this adds the one missing piece, showing what is being reviewed.

Consumers:

  • WebformInteraction review mode can fold onto it, with reviewBody() returning the submission view, retiring the duplicated embed.
  • The yoyaku booking module order-review interaction (the first external consumer) returns the order summary from reviewBody(), restoring the review screen it lost when handler_url was retired.

Open design questions:

  • Hook name: reviewBody() vs preamble() vs context().
  • Should CommentInteraction itself derive from the base (a review with an empty body), or stay a standalone interaction that redirects to the comment page?
  • Refactor WebformInteraction onto the base in this change, or leave it as a follow-up to keep this reviewable?
  • Where the comment configuration lives: a shared trait reused by both CommentInteraction and ReviewInteractionBase, or duplicated in each.

Issue fork orchestra-3610434

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

  • mably committed 5aaf547e on 1.x
    feat: #3610434 Add a reusable ReviewInteractionBase: render domain...
mably’s picture

Status: Active » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.