Klarhimmel UI

Approval

App, assistant approval preview

Install

npx shadcn add @klarhimmel/app-assistant-approval

Usage

import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import AppAssistantApproval from '@/components/klarhimmel/blocks/app-assistant-approval';

export default function Section() {
  return (
    <Theme theme="brand">
      <BlockSurface>
        <AppAssistantApproval props={{
          "state": "pending",
          "risk": "medium",
          "title": "Cancel booking 4821 and email the guest",
          "description": "The guest asked to cancel by message. The rate is refundable until 7 November, so the full amount goes back to the card.",
          "scope": [
            {
              "label": "Touches",
              "value": "Booking 4821, room 204, 14 to 16 November"
            },
            {
              "label": "Changes",
              "value": "Frees the room and refunds 2 380 SEK"
            },
            {
              "label": "Sends",
              "value": "One cancellation email to the guest"
            },
            {
              "label": "Undo",
              "value": "The room can be booked again, the email cannot be recalled"
            }
          ],
          "action": "cancel booking 4821",
          "approve": "Approve",
          "deny": "Deny",
          "labels": {
            "approved": "Approved",
            "denied": "Denied",
            "low": "Low risk",
            "medium": "Medium risk",
            "high": "High risk"
          }
        }} />
      </BlockSurface>
    </Theme>
  );
}

States

assistant approval in 3 forms: pending, approved, denied.

  • state: pending

    Cancel booking 4821 and email the guest

    Medium risk

    The guest asked to cancel by message. The rate is refundable until 7 November, so the full amount goes back to the card.

    cancel booking 4821

    Touches
    Booking 4821, room 204, 14 to 16 November
    Changes
    Frees the room and refunds 2 380 SEK
    Sends
    One cancellation email to the guest
    Undo
    The room can be booked again, the email cannot be recalled

  • state: approved

    Cancel booking 4821 and email the guest

    Medium risk

    The guest asked to cancel by message. The rate is refundable until 7 November, so the full amount goes back to the card.

    cancel booking 4821

    Touches
    Booking 4821, room 204, 14 to 16 November
    Changes
    Frees the room and refunds 2 380 SEK
    Sends
    One cancellation email to the guest
    Undo
    The room can be booked again, the email cannot be recalled

    Approved

  • state: denied

    Cancel booking 4821 and email the guest

    Medium risk

    The guest asked to cancel by message. The rate is refundable until 7 November, so the full amount goes back to the card.

    cancel booking 4821

    Touches
    Booking 4821, room 204, 14 to 16 November
    Changes
    Frees the room and refunds 2 380 SEK
    Sends
    One cancellation email to the guest
    Undo
    The room can be booked again, the email cannot be recalled

    Denied

Notes

When to use it

A card where the assistant asks a person to allow one specific action before it runs, with a risk level and a scope list. For a plain status line of something the assistant already did, use `app-assistant-tool-call`; for the whole conversation, `app-assistant-thread`.

Writing for it

- Write the title as the action itself in plain words, up to 80 characters, and repeat it in `action` (60 characters): the buttons are read to screen readers as the button text plus that action. - The scope list takes 1 to 4 label and value pairs, labels up to 30 characters and values up to 300. Use labels like Touches, Changes, Sends and Undo so the person sees the blast radius before choosing. - Set `risk` to match the real consequence. High adds a warning icon beside the badge, so reserve it for things that cannot be taken back.

Watch out for

This block is strict. If any text field breaks its limit or is missing, it does not fall back to default copy: it shows a notice that the request could not be shown, with Approve and Deny disabled. Once a person decides, the buttons disappear and `resolvedNote` is shown next to the outcome.

Usage

The block in a page, with its default content (long lists shortened). Every prop is in the table below.

section.tsx
import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import AppAssistantApproval from '@/components/klarhimmel/blocks/app-assistant-approval';

export default function Section() {
  return (
    <Theme theme="brand">
      <BlockSurface>
        <AppAssistantApproval props={{
          "state": "pending",
          "risk": "medium",
          "title": "Cancel booking 4821 and email the guest",
          "description": "The guest asked to cancel by message. The rate is refundable until 7 November, so the full amount goes back to the card.",
          "scope": [
            {
              "label": "Touches",
              "value": "Booking 4821, room 204, 14 to 16 November"
            },
            {
              "label": "Changes",
              "value": "Frees the room and refunds 2 380 SEK"
            },
            {
              "label": "Sends",
              "value": "One cancellation email to the guest"
            },
            {
              "label": "Undo",
              "value": "The room can be booked again, the email cannot be recalled"
            }
          ],
          "action": "cancel booking 4821",
          "approve": "Approve",
          "deny": "Deny",
          "labels": {
            "approved": "Approved",
            "denied": "Denied",
            "low": "Low risk",
            "medium": "Medium risk",
            "high": "High risk"
          }
        }} />
      </BlockSurface>
    </Theme>
  );
}

Props

Title, action and the scope list are the text a person agrees to: they are never replaced by defaults, and invalid text shows an invalid state instead. State and risk set the look; labels are the status words.

PropTypeDefaultDescription
state'pending' | 'approved' | 'denied''pending'One of 'pending', 'approved', 'denied'.
risk'low' | 'medium' | 'high''medium'One of 'low', 'medium', 'high'.
titlestring'Cancel booking 4821 and email the g…'Text, up to 80 characters.
descriptionstring'The guest asked to cancel by messag…'Text, up to 240 characters.
scope{ label, value }[]4 itemsList of 1 to 4. Each item: label, value.
actionstring'cancel booking 4821'Text, up to 60 characters.
approvestring'Approve'Text, up to 24 characters.
denystring'Deny'Text, up to 24 characters.
resolvedNotestring-Text, up to 200 characters. Optional; empty is not rendered.
labels{ approved, denied, low, medium, high }{…}Fields: approved, denied, low, medium, high.
headingLevel'1' | '2'-One of '1', '2'. Optional; empty is not rendered.

Other states

The states of every assistant component, side by side.

Install

Installs

app-assistant-approval
Uses
  • Button
About
An action the assistant wants to take and needs a person to allow: title, why, scoped detail, a risk level and Approve / Deny buttons named after the action. Pending, approved and denied via the state prop.
States
Pending, approved, denied; low, medium and high risk. The buttons are named after the action.