Bỏ qua tới nội dung
Component / 063 / NEXOFRAME

AgendaItem

Mẫu chuẩn

Một dòng trong buổi Họp 1:1: loại mục, một câu nói việc gì, một liên kết tới bằng chứng trên dòng thời gian, và — chỉ với đề xuất — ba nút quyết: Duyệt, Từ chối, Để sau. Composite báo quyết định qua một callback onDecide; nó không gọi server.

Composite tầng 2Dựng từ Card, Badge, Button, StatusDot4 kind~10 dòng/buổi

Playground

Chọn kind "proposal" và "Chưa quyết" để thấy ba nút quyết; chọn một quyết định để thấy StatusDot thay rail.

LIVE PREVIEW
Đề xuất

Đề xuất giảm giá tới 10% cho khách hỏi lại lần hai

Nexi đã áp dụng thử trên 6 hội thoại tuần này, không có khiếu nại.

Đánh giá độc lập: đạt 9/10

Xem trên dòng thời gian

Chưa quyết.

import { AgendaItem } from "@nexobox/ui";

<AgendaItem
  id="agenda-1"
  kind="proposal"
  title="Đề xuất giảm giá tới 10% cho khách hỏi lại lần hai"
  description="Nexi đã áp dụng thử trên 6 hội thoại tuần này, không có khiếu nại."
  evidenceHref="/timeline/agenda-1"
  evaluation={{ label: "9/10", passed: true }}
  decision={null}
  onDecide={(id, decision) => handleDecide(id, decision)}
/>

Bài toán

Chủ shop không đọc danh sách learning candidate. Họ ngồi xuống mười phút mỗi tuần với nhân viên. Mỗi dòng trong buổi đó phải đọc được trong hai giây và quyết được trong một cú bấm, kèm đường về bằng chứng để không phải tin suông.

Khi nào sử dụng

Nên dùng

Trang Họp 1:1, bốn nhóm: Làm tốt, Sự cố, Đang chờ bạn, Đề xuất thay đổi. Tối đa khoảng mười dòng một buổi.

Khi nào không dùng

Tránh dùng

Không dùng choDùng thay
Hàng đợi phê duyệtdecision-card của Decision Spine
Thông báoNotification Feed theo decision-contract.md

Dựng từ

Primitive tầng 1Vai trong composite
CardHàng
BadgeLoại mục, 72px cố định bên trái
ButtonBa nút quyết — secondary cho Duyệt, ghost cho Từ chối và Để sau, size sm
StatusDotTrạng thái sau khi đã quyết
Ghi chú triển khai
StatusDot không có variant "danger"; quyết định "Đã từ chối" dùng gần nhất là inactive (chấm xám) thay vì một chấm đỏ.

Anatomy

#PhầnGhi chú
1Kind badgeTrái, 72px cố định: Làm tốt (success), Sự cố (danger), Đang chờ (warning), Đề xuất (information)
2BodyTiêu đề một dòng, mô tả tối đa hai dòng; với đề xuất thêm dòng "Đánh giá độc lập" từ evaluation
3Evidence linkIcon mũi tên và "Xem trên dòng thời gian", href do caller truyền
4Decision railPhải, chỉ khi kind === "proposal" và decision == null: ba Button size sm
5RecalledKhi recalledFrom có giá trị, một dòng nhạt trên cùng

States

StateHành viTrợ năng
Open proposalBa nút hiệnrole="listitem"; nhóm nút role="group" aria-label="Quyết định cho {title}"
BusyNút disabled, Button loading statearia-busy
DecidedRail thành StatusDot + chữaria-live="polite" khi đổi
Not a proposalKhông có rail—

Bàn phím & trợ năng

Tab vào từng nút theo thứ tự Duyệt, Từ chối, Để sau; Enter/Space kích hoạt.
Liên kết bằng chứng là <a> thường, tab tới được, Enter mở.

Seam — host sở hữu gì

Composite không gọi server. Host sở hữu onDecide và đưa quyết định vào approveRelease rồi vào Decision Spine như mọi quyết định khác (ADR-WF-003 clause 5).

API & triển khai

PropMặc địnhQuy ước
id—Bắt buộc.
kind—"well" | "incident" | "waiting" | "proposal".
title—Bắt buộc, một dòng.
descriptionundefinedTối đa hai dòng.
evidenceHrefundefinedKhông hiện liên kết nếu bỏ trống.
evaluationundefinedChỉ đọc khi kind là proposal.
decisionnull{ value, at } | null.
recalledFromundefinedNhãn tuần ISO.
onDecideundefined(id, decision) => void.
busyfalseVô hiệu cả ba nút và bật loading.

Design tokens

--nf-semantic-text-muted (thay cho foreground-muted), --nf-foundation-space-3, --nf-foundation-typography-caption-*. Badge dùng trực tiếp bốn variant success, danger, warning, information — không cần token màu rời. Qua Card: --nf-component-card-*. Qua Button: --nf-component-button-*.

Do / Don't

Nên dùng

Mỗi dòng đọc được trong hai giây. Luôn kèm evidenceHref. Tối đa mười dòng một buổi.

Tránh dùng

Hiện rail quyết cho kind không phải proposal. Nhồi quá mười dòng — đó là lỗi của bộ soạn, không phải của composite.