makersclaw 0.7.0 → 0.8.1
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/README.md +17 -4
- package/package.json +1 -1
- package/r/activity-log.json +52 -0
- package/r/agent-changes.json +51 -0
- package/r/agent-chat.json +53 -0
- package/r/agent-column.json +85 -0
- package/r/agent-dock.json +57 -0
- package/r/agent-kit.json +49 -0
- package/r/agent-marks.json +49 -0
- package/r/agent-pane.json +93 -0
- package/r/ai-action.json +56 -0
- package/r/annotate.json +4 -4
- package/r/approval-request.json +2 -2
- package/r/approval.json +54 -0
- package/r/ask-bar.json +50 -0
- package/r/audio-player.json +2 -2
- package/r/auth-form.json +2 -2
- package/r/automation-editor.json +66 -0
- package/r/automation-list.json +57 -0
- package/r/automation-model.json +118 -0
- package/r/automations-screen.json +71 -0
- package/r/board.json +2 -2
- package/r/calendar-view.json +3 -3
- package/r/cart.json +2 -2
- package/r/chart.json +5 -5
- package/r/chat-pane.json +84 -0
- package/r/chat.json +3 -3
- package/r/code-editor.json +2 -2
- package/r/comment-box.json +3 -3
- package/r/connect-card.json +51 -0
- package/r/contact-section.json +2 -2
- package/r/core.json +18 -6
- package/r/cost.json +51 -0
- package/r/csv-import.json +3 -3
- package/r/data-picker.json +60 -0
- package/r/data-table.json +2 -2
- package/r/diagram.json +2 -2
- package/r/doc-editor.json +2 -2
- package/r/doc-page.json +3 -3
- package/r/email-render.json +2 -2
- package/r/faq.json +2 -2
- package/r/file-upload.json +2 -2
- package/r/first-run.json +63 -0
- package/r/fix-note.json +57 -0
- package/r/flow-canvas.json +3 -3
- package/r/flow-editor.json +79 -0
- package/r/footer.json +3 -3
- package/r/gantt.json +3 -3
- package/r/job-panel.json +2 -2
- package/r/json-editor.json +3 -3
- package/r/library-shelf.json +56 -0
- package/r/map.json +2 -2
- package/r/margin-notes.json +67 -0
- package/r/menubar.json +2 -2
- package/r/mind-map.json +4 -4
- package/r/navigation-menu.json +2 -2
- package/r/needs-you.json +55 -0
- package/r/order-detail.json +2 -2
- package/r/org-chart.json +4 -4
- package/r/pace-bar.json +69 -0
- package/r/page-builder.json +3 -3
- package/r/payment-methods.json +2 -2
- package/r/pdf-document.json +2 -2
- package/r/pdf-viewer.json +3 -3
- package/r/product-detail.json +2 -2
- package/r/product-grid.json +3 -3
- package/r/record-form.json +2 -2
- package/r/record-grid.json +52 -0
- package/r/record-notes.json +4 -4
- package/r/registry.json +4089 -1510
- package/r/run-history.json +52 -0
- package/r/run-view.json +80 -0
- package/r/schedule-card.json +54 -0
- package/r/schedule-engine.json +79 -0
- package/r/schedule-gantt.json +83 -0
- package/r/schedule-ruler.json +64 -0
- package/r/search-dialog.json +2 -2
- package/r/settings-list.json +2 -2
- package/r/setup-checklist.json +2 -2
- package/r/share-dialog.json +2 -2
- package/r/sidebar.json +3 -3
- package/r/signature-pad.json +2 -2
- package/r/sketch-canvas.json +3 -3
- package/r/source-receipt.json +52 -0
- package/r/spreadsheet.json +3 -3
- package/r/stat-cards.json +3 -3
- package/r/step-picker.json +53 -0
- package/r/step-settings.json +72 -0
- package/r/suggestion.json +58 -0
- package/r/sum-bar.json +64 -0
- package/r/task-list.json +3 -3
- package/r/task-model.json +2 -2
- package/r/testimonials.json +2 -2
- package/r/tier-map.json +67 -0
- package/r/time-grid.json +73 -0
- package/r/time-strip.json +64 -0
- package/r/top-bar.json +66 -0
- package/r/transaction-list.json +2 -2
- package/r/trigger-picker.json +61 -0
- package/r/whiteboard.json +4 -4
- package/r/workflow-view.json +55 -0
- package/registry/blocks/activity-log/README.md +112 -0
- package/registry/blocks/activity-log/activity-log.jsx +351 -0
- package/registry/blocks/activity-log/block.json +33 -0
- package/registry/blocks/activity-log/demo.jsx +48 -0
- package/registry/blocks/activity-log/index.js +4 -0
- package/registry/blocks/agent-changes/README.md +94 -0
- package/registry/blocks/agent-changes/agent-changes.jsx +118 -0
- package/registry/blocks/agent-changes/block.json +28 -0
- package/registry/blocks/agent-changes/demo.jsx +39 -0
- package/registry/blocks/agent-changes/index.js +3 -0
- package/registry/blocks/agent-chat/README.md +145 -0
- package/registry/blocks/agent-chat/agent-chat.jsx +415 -0
- package/registry/blocks/agent-chat/block.json +30 -0
- package/registry/blocks/agent-chat/demo.jsx +165 -0
- package/registry/blocks/agent-chat/index.js +3 -0
- package/registry/blocks/agent-column/README.md +197 -0
- package/registry/blocks/agent-column/agent-column.jsx +492 -0
- package/registry/blocks/agent-column/block.json +67 -0
- package/registry/blocks/agent-column/column-picker.jsx +163 -0
- package/registry/blocks/agent-column/demo.jsx +50 -0
- package/registry/blocks/agent-column/index.js +7 -0
- package/registry/blocks/agent-column/model.js +164 -0
- package/registry/blocks/agent-column/receipt.jsx +483 -0
- package/registry/blocks/agent-column/spreadsheet-type.jsx +24 -0
- package/registry/blocks/agent-dock/README.md +210 -0
- package/registry/blocks/agent-dock/agent-dock.jsx +356 -0
- package/registry/blocks/agent-dock/block.json +47 -0
- package/registry/blocks/agent-dock/demo.jsx +153 -0
- package/registry/blocks/agent-dock/dock-model.js +118 -0
- package/registry/blocks/agent-dock/index.js +5 -0
- package/registry/blocks/agent-kit/README.md +73 -0
- package/registry/blocks/agent-kit/agent-kit.jsx +86 -0
- package/registry/blocks/agent-kit/block.json +10 -0
- package/registry/blocks/agent-kit/demo.jsx +35 -0
- package/registry/blocks/agent-kit/index.js +3 -0
- package/registry/blocks/agent-marks/README.md +80 -0
- package/registry/blocks/agent-marks/agent-marks.jsx +133 -0
- package/registry/blocks/agent-marks/block.json +27 -0
- package/registry/blocks/agent-marks/demo.jsx +49 -0
- package/registry/blocks/agent-marks/index.js +3 -0
- package/registry/blocks/agent-pane/README.md +225 -0
- package/registry/blocks/agent-pane/agent-pane.jsx +244 -0
- package/registry/blocks/agent-pane/block.json +41 -0
- package/registry/blocks/agent-pane/composer.jsx +6 -0
- package/registry/blocks/agent-pane/demo.jsx +233 -0
- package/registry/blocks/agent-pane/dock-context.js +10 -0
- package/registry/blocks/agent-pane/index.js +4 -0
- package/registry/blocks/agent-pane/prose.jsx +84 -0
- package/registry/blocks/agent-pane/questions.jsx +134 -0
- package/registry/blocks/agent-pane/transcript.jsx +268 -0
- package/registry/blocks/agent-pane/work.jsx +368 -0
- package/registry/blocks/ai-action/README.md +94 -0
- package/registry/blocks/ai-action/ai-action.jsx +188 -0
- package/registry/blocks/ai-action/block.json +34 -0
- package/registry/blocks/ai-action/demo.jsx +93 -0
- package/registry/blocks/ai-action/index.js +3 -0
- package/registry/blocks/annotate/README.md +14 -11
- package/registry/blocks/approval/README.md +145 -0
- package/registry/blocks/approval/approval.jsx +163 -0
- package/registry/blocks/approval/block.json +31 -0
- package/registry/blocks/approval/demo.jsx +121 -0
- package/registry/blocks/approval/index.js +3 -0
- package/registry/blocks/ask-bar/README.md +105 -0
- package/registry/blocks/ask-bar/ask-bar.jsx +166 -0
- package/registry/blocks/ask-bar/block.json +26 -0
- package/registry/blocks/ask-bar/demo.jsx +78 -0
- package/registry/blocks/ask-bar/index.js +3 -0
- package/registry/blocks/automation-editor/README.md +291 -0
- package/registry/blocks/automation-editor/automation-editor.jsx +656 -0
- package/registry/blocks/automation-editor/block.json +39 -0
- package/registry/blocks/automation-editor/demo.jsx +284 -0
- package/registry/blocks/automation-editor/index.js +4 -0
- package/registry/blocks/automation-editor/run-inputs.jsx +82 -0
- package/registry/blocks/automation-list/README.md +129 -0
- package/registry/blocks/automation-list/automation-list.jsx +476 -0
- package/registry/blocks/automation-list/block.json +35 -0
- package/registry/blocks/automation-list/demo.jsx +67 -0
- package/registry/blocks/automation-list/index.js +3 -0
- package/registry/blocks/automation-model/README.md +109 -0
- package/registry/blocks/automation-model/block.json +135 -0
- package/registry/blocks/automation-model/catalog.js +256 -0
- package/registry/blocks/automation-model/check.js +161 -0
- package/registry/blocks/automation-model/demo.jsx +42 -0
- package/registry/blocks/automation-model/edit.js +262 -0
- package/registry/blocks/automation-model/fixes.js +287 -0
- package/registry/blocks/automation-model/glyph.jsx +13 -0
- package/registry/blocks/automation-model/graph.js +410 -0
- package/registry/blocks/automation-model/index.js +33 -0
- package/registry/blocks/automation-model/overlay.js +175 -0
- package/registry/blocks/automation-model/parts.jsx +94 -0
- package/registry/blocks/automation-model/schedule.js +53 -0
- package/registry/blocks/automation-model/templates.js +128 -0
- package/registry/blocks/automation-model/values.js +29 -0
- package/registry/blocks/automation-model/words.js +439 -0
- package/registry/blocks/automations-screen/README.md +207 -0
- package/registry/blocks/automations-screen/automations-screen.jsx +452 -0
- package/registry/blocks/automations-screen/block.json +47 -0
- package/registry/blocks/automations-screen/demo.jsx +364 -0
- package/registry/blocks/automations-screen/index.js +4 -0
- package/registry/blocks/automations-screen/screen-model.js +129 -0
- package/registry/blocks/chart/cartesian.jsx +1 -1
- package/registry/blocks/chart/core.jsx +33 -23
- package/registry/blocks/chart/pie.jsx +1 -1
- package/registry/blocks/chat/README.md +4 -1
- package/registry/blocks/chat/demo.jsx +2 -2
- package/registry/blocks/chat-pane/README.md +143 -0
- package/registry/blocks/chat-pane/block.json +48 -0
- package/registry/blocks/chat-pane/chat-attach.js +166 -0
- package/registry/blocks/chat-pane/chat-composer.jsx +195 -0
- package/registry/blocks/chat-pane/chat-context.js +17 -0
- package/registry/blocks/chat-pane/chat-model.js +43 -0
- package/registry/blocks/chat-pane/chat-pane.jsx +398 -0
- package/registry/blocks/chat-pane/chats-list.jsx +52 -0
- package/registry/blocks/chat-pane/demo.jsx +103 -0
- package/registry/blocks/chat-pane/index.js +9 -0
- package/registry/blocks/connect-card/README.md +99 -0
- package/registry/blocks/connect-card/block.json +10 -0
- package/registry/blocks/connect-card/connect-card.jsx +103 -0
- package/registry/blocks/connect-card/demo.jsx +49 -0
- package/registry/blocks/connect-card/index.js +3 -0
- package/registry/blocks/cost/README.md +115 -0
- package/registry/blocks/cost/block.json +10 -0
- package/registry/blocks/cost/cost.jsx +176 -0
- package/registry/blocks/cost/demo.jsx +66 -0
- package/registry/blocks/cost/index.js +3 -0
- package/registry/blocks/data-picker/README.md +81 -0
- package/registry/blocks/data-picker/block.json +38 -0
- package/registry/blocks/data-picker/data-picker.jsx +210 -0
- package/registry/blocks/data-picker/demo.jsx +34 -0
- package/registry/blocks/data-picker/fields.js +89 -0
- package/registry/blocks/data-picker/index.js +4 -0
- package/registry/blocks/data-table/demo.jsx +1 -1
- package/registry/blocks/first-run/README.md +118 -0
- package/registry/blocks/first-run/block.json +11 -0
- package/registry/blocks/first-run/demo.jsx +88 -0
- package/registry/blocks/first-run/first-run-model.js +51 -0
- package/registry/blocks/first-run/first-run.jsx +156 -0
- package/registry/blocks/first-run/index.js +5 -0
- package/registry/blocks/first-run/probe-rules.js +26 -0
- package/registry/blocks/fix-note/README.md +79 -0
- package/registry/blocks/fix-note/block.json +35 -0
- package/registry/blocks/fix-note/demo.jsx +30 -0
- package/registry/blocks/fix-note/fix-note.jsx +235 -0
- package/registry/blocks/fix-note/index.js +3 -0
- package/registry/blocks/flow-canvas/README.md +15 -8
- package/registry/blocks/flow-editor/README.md +108 -0
- package/registry/blocks/flow-editor/block.json +44 -0
- package/registry/blocks/flow-editor/demo.jsx +115 -0
- package/registry/blocks/flow-editor/flow-canvas.jsx +568 -0
- package/registry/blocks/flow-editor/flow-editor.jsx +154 -0
- package/registry/blocks/flow-editor/index.js +6 -0
- package/registry/blocks/flow-editor/minimap.jsx +78 -0
- package/registry/blocks/flow-editor/outline.jsx +134 -0
- package/registry/blocks/footer/README.md +3 -2
- package/registry/blocks/library-shelf/README.md +117 -0
- package/registry/blocks/library-shelf/block.json +28 -0
- package/registry/blocks/library-shelf/demo.jsx +68 -0
- package/registry/blocks/library-shelf/index.js +3 -0
- package/registry/blocks/library-shelf/library-shelf.jsx +211 -0
- package/registry/blocks/library-shelf/probe-rules.js +15 -0
- package/registry/blocks/margin-notes/README.md +222 -0
- package/registry/blocks/margin-notes/block.json +10 -0
- package/registry/blocks/margin-notes/demo.jsx +144 -0
- package/registry/blocks/margin-notes/index.js +20 -0
- package/registry/blocks/margin-notes/margin-model.js +224 -0
- package/registry/blocks/margin-notes/margin-notes.jsx +465 -0
- package/registry/blocks/mind-map/README.md +4 -2
- package/registry/blocks/needs-you/README.md +177 -0
- package/registry/blocks/needs-you/block.json +34 -0
- package/registry/blocks/needs-you/demo.jsx +143 -0
- package/registry/blocks/needs-you/index.js +3 -0
- package/registry/blocks/needs-you/needs-you.jsx +441 -0
- package/registry/blocks/org-chart/README.md +4 -2
- package/registry/blocks/pace-bar/README.md +230 -0
- package/registry/blocks/pace-bar/block.json +10 -0
- package/registry/blocks/pace-bar/demo.jsx +255 -0
- package/registry/blocks/pace-bar/index.js +22 -0
- package/registry/blocks/pace-bar/pace-bar.jsx +461 -0
- package/registry/blocks/pace-bar/pace-model.js +288 -0
- package/registry/blocks/page-builder/README.md +1 -1
- package/registry/blocks/page-builder/demo.jsx +3 -3
- package/registry/blocks/pdf-viewer/README.md +4 -1
- package/registry/blocks/record-grid/README.md +100 -0
- package/registry/blocks/record-grid/block.json +28 -0
- package/registry/blocks/record-grid/demo.jsx +43 -0
- package/registry/blocks/record-grid/index.js +3 -0
- package/registry/blocks/record-grid/record-grid.jsx +251 -0
- package/registry/blocks/run-history/README.md +138 -0
- package/registry/blocks/run-history/block.json +10 -0
- package/registry/blocks/run-history/demo.jsx +74 -0
- package/registry/blocks/run-history/index.js +3 -0
- package/registry/blocks/run-history/run-history.jsx +218 -0
- package/registry/blocks/run-view/README.md +174 -0
- package/registry/blocks/run-view/block.json +50 -0
- package/registry/blocks/run-view/demo.jsx +286 -0
- package/registry/blocks/run-view/index.js +5 -0
- package/registry/blocks/run-view/run-controls.jsx +266 -0
- package/registry/blocks/run-view/run-view.jsx +236 -0
- package/registry/blocks/run-view/runs-list.jsx +99 -0
- package/registry/blocks/schedule-card/README.md +121 -0
- package/registry/blocks/schedule-card/block.json +10 -0
- package/registry/blocks/schedule-card/demo.jsx +82 -0
- package/registry/blocks/schedule-card/index.js +3 -0
- package/registry/blocks/schedule-card/schedule-card.jsx +136 -0
- package/registry/blocks/schedule-engine/README.md +137 -0
- package/registry/blocks/schedule-engine/block.json +10 -0
- package/registry/blocks/schedule-engine/demo.jsx +82 -0
- package/registry/blocks/schedule-engine/engine.js +769 -0
- package/registry/blocks/schedule-engine/index.js +9 -0
- package/registry/blocks/schedule-engine/ops.js +71 -0
- package/registry/blocks/schedule-engine/place.js +294 -0
- package/registry/blocks/schedule-engine/tree.js +79 -0
- package/registry/blocks/schedule-engine/waits.js +80 -0
- package/registry/blocks/schedule-gantt/README.md +159 -0
- package/registry/blocks/schedule-gantt/block.json +10 -0
- package/registry/blocks/schedule-gantt/demo.jsx +223 -0
- package/registry/blocks/schedule-gantt/gantt-model.js +219 -0
- package/registry/blocks/schedule-gantt/geometry.js +176 -0
- package/registry/blocks/schedule-gantt/index.js +26 -0
- package/registry/blocks/schedule-gantt/schedule-gantt.jsx +882 -0
- package/registry/blocks/schedule-gantt/sheet.jsx +372 -0
- package/registry/blocks/schedule-gantt/track.jsx +190 -0
- package/registry/blocks/schedule-ruler/README.md +148 -0
- package/registry/blocks/schedule-ruler/block.json +10 -0
- package/registry/blocks/schedule-ruler/demo.jsx +181 -0
- package/registry/blocks/schedule-ruler/index.js +21 -0
- package/registry/blocks/schedule-ruler/ruler-model.js +239 -0
- package/registry/blocks/schedule-ruler/schedule-ruler.jsx +548 -0
- package/registry/blocks/sidebar/README.md +23 -13
- package/registry/blocks/sketch-canvas/README.md +15 -9
- package/registry/blocks/source-receipt/README.md +97 -0
- package/registry/blocks/source-receipt/block.json +30 -0
- package/registry/blocks/source-receipt/demo.jsx +71 -0
- package/registry/blocks/source-receipt/index.js +3 -0
- package/registry/blocks/source-receipt/source-receipt.jsx +107 -0
- package/registry/blocks/spreadsheet/spreadsheet.jsx +15 -1
- package/registry/blocks/step-picker/README.md +78 -0
- package/registry/blocks/step-picker/block.json +31 -0
- package/registry/blocks/step-picker/demo.jsx +23 -0
- package/registry/blocks/step-picker/index.js +3 -0
- package/registry/blocks/step-picker/step-picker.jsx +144 -0
- package/registry/blocks/step-settings/README.md +100 -0
- package/registry/blocks/step-settings/block.json +44 -0
- package/registry/blocks/step-settings/demo.jsx +93 -0
- package/registry/blocks/step-settings/fields.jsx +58 -0
- package/registry/blocks/step-settings/flow-settings.jsx +115 -0
- package/registry/blocks/step-settings/index.js +5 -0
- package/registry/blocks/step-settings/step-settings.jsx +290 -0
- package/registry/blocks/suggestion/README.md +171 -0
- package/registry/blocks/suggestion/block.json +40 -0
- package/registry/blocks/suggestion/demo.jsx +91 -0
- package/registry/blocks/suggestion/index.js +3 -0
- package/registry/blocks/suggestion/suggestion.jsx +436 -0
- package/registry/blocks/sum-bar/README.md +122 -0
- package/registry/blocks/sum-bar/block.json +10 -0
- package/registry/blocks/sum-bar/demo.jsx +110 -0
- package/registry/blocks/sum-bar/index.js +5 -0
- package/registry/blocks/sum-bar/sum-bar.jsx +209 -0
- package/registry/blocks/sum-bar/sum-model.js +126 -0
- package/registry/blocks/tier-map/README.md +217 -0
- package/registry/blocks/tier-map/block.json +10 -0
- package/registry/blocks/tier-map/demo.jsx +222 -0
- package/registry/blocks/tier-map/index.js +24 -0
- package/registry/blocks/tier-map/tier-map.jsx +574 -0
- package/registry/blocks/tier-map/tier-model.js +318 -0
- package/registry/blocks/time-grid/README.md +305 -0
- package/registry/blocks/time-grid/block.json +10 -0
- package/registry/blocks/time-grid/demo.jsx +279 -0
- package/registry/blocks/time-grid/grid-model.js +322 -0
- package/registry/blocks/time-grid/index.js +25 -0
- package/registry/blocks/time-grid/time-grid.jsx +1325 -0
- package/registry/blocks/time-strip/README.md +141 -0
- package/registry/blocks/time-strip/block.json +10 -0
- package/registry/blocks/time-strip/demo.jsx +129 -0
- package/registry/blocks/time-strip/index.js +19 -0
- package/registry/blocks/time-strip/strip-model.js +178 -0
- package/registry/blocks/time-strip/time-strip.jsx +260 -0
- package/registry/blocks/top-bar/README.md +149 -0
- package/registry/blocks/top-bar/block.json +35 -0
- package/registry/blocks/top-bar/demo.jsx +78 -0
- package/registry/blocks/top-bar/index.js +5 -0
- package/registry/blocks/top-bar/probe-rules.js +74 -0
- package/registry/blocks/top-bar/top-bar-model.js +152 -0
- package/registry/blocks/top-bar/top-bar.jsx +244 -0
- package/registry/blocks/trigger-picker/README.md +98 -0
- package/registry/blocks/trigger-picker/block.json +38 -0
- package/registry/blocks/trigger-picker/demo.jsx +59 -0
- package/registry/blocks/trigger-picker/index.js +3 -0
- package/registry/blocks/trigger-picker/trigger-picker.jsx +374 -0
- package/registry/blocks/whiteboard/README.md +20 -14
- package/registry/blocks/workflow-view/README.md +123 -0
- package/registry/blocks/workflow-view/block.json +10 -0
- package/registry/blocks/workflow-view/demo.jsx +90 -0
- package/registry/blocks/workflow-view/index.js +3 -0
- package/registry/blocks/workflow-view/workflow-view.jsx +203 -0
- package/src/cli.mjs +2 -2
- package/src/install.mjs +100 -22
- package/src/registry.mjs +37 -3
- package/templates/next/browser/lib/data.js +6 -1
- package/templates/next/files/README.md +909 -26
- package/templates/next/files/app/shell.jsx +54 -37
- package/templates/next/files/check/automation-format.ts +2103 -0
- package/templates/next/files/check/automation-package.ts +142 -0
- package/templates/next/files/check/run.mjs +1043 -12
- package/templates/next/files/components/ui/field.jsx +17 -4
- package/templates/next/files/components/ui/icon.jsx +13 -0
- package/templates/next/files/components/ui/index.js +3 -1
- package/templates/next/files/components/ui/layout.jsx +382 -0
- package/templates/next/files/components/ui/notice.jsx +70 -0
- package/templates/next/files/components/ui/page.jsx +124 -0
- package/templates/next/files/components/ui/stat.jsx +22 -7
- package/templates/next/files/components/ui/toast.jsx +6 -3
- package/templates/next/files/lib/automations.js +660 -0
- package/templates/next/files/lib/claw.js +244 -5
- package/templates/next/files/lib/door.js +92 -0
- package/templates/next/files/lib/hooks.js +1694 -6
- package/templates/next/files/lib/platform.js +611 -14
- package/templates/next/template.json +22 -3
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useId, useState } from "react";
|
|
4
|
+
import { Button, Input, cx } from "../../ui";
|
|
5
|
+
import { AgentMark } from "../agent-marks";
|
|
6
|
+
import { CONFIDENCE, answerState, decidingWords, shortUrl } from "./model";
|
|
7
|
+
|
|
8
|
+
// The receipt: an answer as a claim with its citation (grown in Data
|
|
9
|
+
// Enrichment 0.5.0, the v2 design's signature). In a dense grid the
|
|
10
|
+
// answer shrinks to one line, its value and its trust as a mark and a
|
|
11
|
+
// word (AnswerLine, TrustMark); opened, it is drawn big: the value, how
|
|
12
|
+
// sure, and each source as a clipping (the page's title, its address and
|
|
13
|
+
// date, and the words on it with the deciding ones underlined). Two
|
|
14
|
+
// answers are two clippings to pick from; "not found" is a receipt too,
|
|
15
|
+
// every page the agent tried crossed off. And a column's heading as a job
|
|
16
|
+
// (JobHeader): its name, how far it got, what a row costs, its menu.
|
|
17
|
+
//
|
|
18
|
+
// Every state is a shape and a word, never colour alone. Colours are the
|
|
19
|
+
// theme's slots: chart-1 sure, chart-2 likely, chart-3 guess, chart-4
|
|
20
|
+
// sent, chart-5 typed by a person, success a person's check, warning
|
|
21
|
+
// two answers or a flag, info looking up, destructive failed; the rest
|
|
22
|
+
// muted. Props in, callbacks out. Tokens only.
|
|
23
|
+
|
|
24
|
+
/* ------------------------------ the marks ------------------------------ */
|
|
25
|
+
|
|
26
|
+
// The agent's mark is the platform's one (the agent-marks block): a
|
|
27
|
+
// filled diamond. Re-exported so a screen that took AgentMark from here
|
|
28
|
+
// keeps it.
|
|
29
|
+
export { AgentMark };
|
|
30
|
+
|
|
31
|
+
const Dot = ({ kind }) =>
|
|
32
|
+
kind === "sure" ? (
|
|
33
|
+
<span aria-hidden="true" className="inline-block size-2 shrink-0 rounded-full bg-current" />
|
|
34
|
+
) : kind === "likely" ? (
|
|
35
|
+
<span aria-hidden="true" className="relative inline-block size-2 shrink-0 overflow-hidden rounded-full border-[1.5px] border-current">
|
|
36
|
+
<span className="absolute inset-y-0 left-0 w-1/2 bg-current" />
|
|
37
|
+
</span>
|
|
38
|
+
) : kind === "guess" ? (
|
|
39
|
+
<span aria-hidden="true" className="inline-block size-[9px] shrink-0 rounded-full border-[1.5px] border-dashed border-current" />
|
|
40
|
+
) : kind === "two" ? (
|
|
41
|
+
<span aria-hidden="true" className="relative inline-block size-[9px] shrink-0 border-[1.5px] border-current">
|
|
42
|
+
<span className="absolute inset-y-0 left-1/2 w-[1.5px] -translate-x-1/2 bg-current" />
|
|
43
|
+
</span>
|
|
44
|
+
) : kind === "wait" ? (
|
|
45
|
+
<span aria-hidden="true" className="inline-block size-2 shrink-0 rounded-full border-[1.5px] border-current border-t-transparent" />
|
|
46
|
+
) : kind === "none" ? (
|
|
47
|
+
<span aria-hidden="true" className="relative inline-block size-[9px] shrink-0 overflow-hidden rounded-full border-[1.5px] border-current">
|
|
48
|
+
<span className="absolute left-1/2 top-[-2px] h-[13px] w-[1.5px] -translate-x-1/2 rotate-45 bg-current" />
|
|
49
|
+
</span>
|
|
50
|
+
) : kind === "looking" ? (
|
|
51
|
+
<span aria-hidden="true" className="relative inline-block h-[3px] w-[18px] shrink-0 overflow-hidden rounded-full border border-current">
|
|
52
|
+
<span className="absolute inset-y-0 left-0 w-1/3 animate-pulse bg-current motion-reduce:animate-none" />
|
|
53
|
+
</span>
|
|
54
|
+
) : kind === "failed" ? (
|
|
55
|
+
<span aria-hidden="true" className="text-[10px] leading-none">▲</span>
|
|
56
|
+
) : kind === "typed" ? (
|
|
57
|
+
<span aria-hidden="true" className="text-[11px] leading-none">✎</span>
|
|
58
|
+
) : kind === "sent" ? (
|
|
59
|
+
<span aria-hidden="true" className="text-[11px] leading-none">↗</span>
|
|
60
|
+
) : kind === "stale" ? (
|
|
61
|
+
<span aria-hidden="true" className="text-[11px] leading-none">↻</span>
|
|
62
|
+
) : null;
|
|
63
|
+
|
|
64
|
+
const TONE = {
|
|
65
|
+
sure: "text-chart-1",
|
|
66
|
+
likely: "text-chart-2",
|
|
67
|
+
guess: "text-chart-3",
|
|
68
|
+
two: "text-warning",
|
|
69
|
+
warn: "text-warning",
|
|
70
|
+
looking: "text-info",
|
|
71
|
+
failed: "text-destructive",
|
|
72
|
+
typed: "text-chart-5",
|
|
73
|
+
sent: "text-chart-4",
|
|
74
|
+
ok: "text-success",
|
|
75
|
+
quiet: "text-muted-foreground",
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* A trust mark and its word, in the state's tone: sure ●, likely ◐,
|
|
80
|
+
* guess ◌ (never shown as verified), two answers ▣, looking up ▬, waits
|
|
81
|
+
* ◔, not found ⊘, failed ▲, typed ✎, sent ↗, out of date ↻.
|
|
82
|
+
*
|
|
83
|
+
* kind sure · likely · guess · two · warn · looking · wait · none ·
|
|
84
|
+
* failed · typed · sent · stale · quiet
|
|
85
|
+
* word the word beside it ("" for the mark alone, which still names
|
|
86
|
+
* itself to a screen reader)
|
|
87
|
+
* check a person's tick after it
|
|
88
|
+
*/
|
|
89
|
+
export function TrustMark({ kind, word, check = false, className }) {
|
|
90
|
+
const glyph = { warn: "two", quiet: null }[kind] ?? kind;
|
|
91
|
+
const tone = TONE[kind] ?? TONE.quiet;
|
|
92
|
+
const said = word ?? CONFIDENCE[kind]?.label ?? "";
|
|
93
|
+
const aria = [said || CONFIDENCE[kind]?.label || kind, check ? "checked" : ""].filter(Boolean).join(", ");
|
|
94
|
+
return (
|
|
95
|
+
<span className={cx("relative inline-flex shrink-0 items-center gap-1 whitespace-nowrap text-[11px]", tone, className)}>
|
|
96
|
+
{glyph ? <Dot kind={glyph === "wait" || glyph === "none" ? glyph : glyph} /> : null}
|
|
97
|
+
{said ? <span>{said}</span> : <span className="sr-only">{aria}</span>}
|
|
98
|
+
{check ? (
|
|
99
|
+
<span className="text-[11px] font-bold text-success" aria-label="checked">
|
|
100
|
+
✓
|
|
101
|
+
</span>
|
|
102
|
+
) : null}
|
|
103
|
+
</span>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const sureKind = (c) => (c === "sure" || c === "likely" || c === "guess" ? c : "quiet");
|
|
108
|
+
|
|
109
|
+
/* ------------------------------ the line ------------------------------ */
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* One answer on one line, as a dense grid draws it: the value at the
|
|
113
|
+
* start, its trust at the end (a person's check after it); a state with
|
|
114
|
+
* no value says the state in words.
|
|
115
|
+
*
|
|
116
|
+
* answer the answer (model.js), or null for not asked yet
|
|
117
|
+
* type text · link · email · number · domain
|
|
118
|
+
* onRetry a failed answer's "Try again"
|
|
119
|
+
* queuedWord what a queued answer says ("queued", "back in the queue")
|
|
120
|
+
*/
|
|
121
|
+
export function AnswerLine({ answer, onRetry, queuedWord = "queued", className }) {
|
|
122
|
+
const st = answerState(answer);
|
|
123
|
+
const a = answer ?? {};
|
|
124
|
+
const value = (v, struck) => <span className={cx("min-w-0 flex-[0_1_auto] truncate", struck && "text-muted-foreground line-through decoration-muted-foreground")}>{v}</span>;
|
|
125
|
+
const row = (children) => <span className={cx("flex w-full min-w-0 items-center gap-1.5", className)}>{children}</span>;
|
|
126
|
+
const end = (node) => <span className="ml-auto flex shrink-0 items-center gap-1">{node}</span>;
|
|
127
|
+
switch (st) {
|
|
128
|
+
case "empty":
|
|
129
|
+
return row(<span className="text-input">—</span>);
|
|
130
|
+
case "queued":
|
|
131
|
+
return row(<TrustMark kind="quiet" word={a.value ? `${queuedWord} · ${a.value}` : queuedWord} />);
|
|
132
|
+
case "waiting":
|
|
133
|
+
return row(<TrustMark kind="wait" word={a.waitsFor?.length ? `waits for ${a.waitsFor.join(", ")}` : "waits for the row"} className="text-muted-foreground" />);
|
|
134
|
+
case "blocked":
|
|
135
|
+
return row(<TrustMark kind="wait" word={`can't fill · needs ${(a.blockedBy ?? []).join(" and ")}`} className="text-muted-foreground" />);
|
|
136
|
+
case "working":
|
|
137
|
+
return row(<TrustMark kind="looking" word={a.value ? "writing" : a.looking ? `looking up · ${a.looking}` : "looking up"} className="min-w-0 truncate" />);
|
|
138
|
+
case "not_found":
|
|
139
|
+
return row(<TrustMark kind="none" word={a.checked ? "not found, kept empty" : "not found"} check={a.checked} className="text-muted-foreground" />);
|
|
140
|
+
case "failed":
|
|
141
|
+
return row(
|
|
142
|
+
<>
|
|
143
|
+
<TrustMark kind="failed" word={`failed${a.detail || a.note ? ` · ${a.detail || a.note}` : ""}`} className="min-w-0 truncate" />
|
|
144
|
+
{onRetry ? (
|
|
145
|
+
<span className="ml-auto shrink-0">
|
|
146
|
+
<Button variant="link" size="inherit" onClick={(e) => (e.stopPropagation(), onRetry())} className="text-xs">
|
|
147
|
+
Try again
|
|
148
|
+
</Button>
|
|
149
|
+
</span>
|
|
150
|
+
) : null}
|
|
151
|
+
</>,
|
|
152
|
+
);
|
|
153
|
+
case "two_answers":
|
|
154
|
+
return row(
|
|
155
|
+
<>
|
|
156
|
+
{value(`${a.value} · ${a.other?.value ?? ""}`)}
|
|
157
|
+
{end(<TrustMark kind="two" word="2 answers" />)}
|
|
158
|
+
</>,
|
|
159
|
+
);
|
|
160
|
+
case "stale":
|
|
161
|
+
return row(
|
|
162
|
+
<>
|
|
163
|
+
{value(a.value, true)}
|
|
164
|
+
{end(<TrustMark kind="stale" word="out of date" className="text-muted-foreground" />)}
|
|
165
|
+
</>,
|
|
166
|
+
);
|
|
167
|
+
case "typed":
|
|
168
|
+
return row(
|
|
169
|
+
<>
|
|
170
|
+
{value(a.value)}
|
|
171
|
+
{end(<TrustMark kind="typed" word="typed" />)}
|
|
172
|
+
</>,
|
|
173
|
+
);
|
|
174
|
+
default: {
|
|
175
|
+
if (a.flag && !a.checked) return row(<TrustMark kind="warn" word={a.flag === "left" ? `${a.value}${a.movedTo ? ` · ${a.movedTo}` : ""}` : `${a.value ?? ""}${a.flag === "may_not_fit" ? ": may not fit" : ""}`} className="min-w-0 truncate" />);
|
|
176
|
+
const checked = st === "checked";
|
|
177
|
+
const kind = sureKind(a.confidence);
|
|
178
|
+
return row(
|
|
179
|
+
<>
|
|
180
|
+
{value(a.value)}
|
|
181
|
+
{end(<TrustMark kind={kind} word={checked && kind !== "guess" ? "" : CONFIDENCE[kind]?.label ?? ""} check={checked} />)}
|
|
182
|
+
</>,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* ------------------------------ the heading ------------------------------ */
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* A column's heading as a job: the agent's mark and its name, its menu,
|
|
192
|
+
* then a bar of how far it got, the words ("138 of 480 · 2 to check")
|
|
193
|
+
* and what a row costs. A person's own column says where it came from.
|
|
194
|
+
*
|
|
195
|
+
* name "Headcount"
|
|
196
|
+
* agent false: a person's own column
|
|
197
|
+
* source for a person's column, the line under its name ("yours ·
|
|
198
|
+
* summit-leads.csv"; default "yours")
|
|
199
|
+
* progress "21 of 22 · 3 to check"; part 0 to 1 for the bar
|
|
200
|
+
* cost "40 cr/row"
|
|
201
|
+
* menu a node at the end of the first line (a kit Menu)
|
|
202
|
+
*/
|
|
203
|
+
export function JobHeader({ name, agent = true, source, progress, part, cost, menu, className }) {
|
|
204
|
+
return (
|
|
205
|
+
<div className={cx("grid min-w-0 gap-1.5", className)}>
|
|
206
|
+
<div className={cx("flex min-w-0 items-center gap-1.5", agent ? "font-semibold" : "font-medium")}>
|
|
207
|
+
{agent ? <AgentMark /> : null}
|
|
208
|
+
<span className="min-w-0 flex-1 truncate">{name}</span>
|
|
209
|
+
{menu ?? null}
|
|
210
|
+
</div>
|
|
211
|
+
<div className={cx("flex min-w-0 items-center gap-1.5 whitespace-nowrap text-[11px] font-normal", agent ? "text-muted-foreground" : "text-chart-5")}>
|
|
212
|
+
{agent ? (
|
|
213
|
+
<>
|
|
214
|
+
<span aria-hidden="true" className="relative inline-block h-[3px] w-[30px] shrink-0 overflow-hidden rounded-full bg-muted">
|
|
215
|
+
<span className="absolute inset-y-0 left-0 bg-primary" style={{ width: `${Math.round(Math.max(0, Math.min(1, part ?? 0)) * 100)}%` }} />
|
|
216
|
+
</span>
|
|
217
|
+
<span className="min-w-0 truncate">{progress}</span>
|
|
218
|
+
{cost ? <span className="ml-auto shrink-0">{cost}</span> : null}
|
|
219
|
+
</>
|
|
220
|
+
) : (
|
|
221
|
+
<span className="truncate">{source ?? "yours"}</span>
|
|
222
|
+
)}
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* ------------------------------ the receipt ------------------------------ */
|
|
229
|
+
|
|
230
|
+
/** The words on the page, the deciding ones underlined: `[[…]]` in the
|
|
231
|
+
* words marks them, else the answer's value where it appears. */
|
|
232
|
+
function Quote({ words, mark }) {
|
|
233
|
+
const parts = decidingWords(words, mark);
|
|
234
|
+
return (
|
|
235
|
+
<q className="block leading-normal [quotes:none] before:content-['\201C'] after:content-['\201D']">
|
|
236
|
+
{parts.map((p, i) =>
|
|
237
|
+
p.marked ? (
|
|
238
|
+
<mark key={i} className="bg-accent px-px text-accent-foreground underline decoration-primary decoration-2 underline-offset-[3px]">
|
|
239
|
+
{p.text}
|
|
240
|
+
</mark>
|
|
241
|
+
) : (
|
|
242
|
+
<span key={i}>{p.text}</span>
|
|
243
|
+
),
|
|
244
|
+
)}
|
|
245
|
+
</q>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* A source as a clipping: its trust, the page's title, an action at the
|
|
251
|
+
* end (Pick 85), the address and when it was read, the words on it with
|
|
252
|
+
* the deciding ones underlined, and a footnote.
|
|
253
|
+
*
|
|
254
|
+
* source { url, title, evidence, read } (read: "read 22 Sep")
|
|
255
|
+
* trust sure · likely · guess (the dot before the title), or null
|
|
256
|
+
* mark the value to underline when the words carry no [[…]]
|
|
257
|
+
* title overrides source.title ("62 people · likely")
|
|
258
|
+
* action a node at the head's end
|
|
259
|
+
* footnote a muted line under the words
|
|
260
|
+
* picked drawn as the one chosen
|
|
261
|
+
*/
|
|
262
|
+
export function Clipping({ source, trust, mark, title, action, footnote, picked = false, children, className }) {
|
|
263
|
+
const s = source ?? {};
|
|
264
|
+
const url = s.url ? shortUrl(s.url) : null;
|
|
265
|
+
return (
|
|
266
|
+
<div className={cx("grid gap-1.5 rounded-[var(--radius)] border bg-card px-3 py-2.5 text-card-foreground", picked ? "border-primary ring-1 ring-primary" : "border-border", className)}>
|
|
267
|
+
<div className="flex min-w-0 items-center gap-2">
|
|
268
|
+
{trust ? <TrustMark kind={sureKind(trust)} word="" /> : null}
|
|
269
|
+
<b className="min-w-0 flex-1 truncate font-semibold">{title ?? s.title ?? url ?? "A page"}</b>
|
|
270
|
+
{action ?? null}
|
|
271
|
+
</div>
|
|
272
|
+
{url || s.read ? (
|
|
273
|
+
<div className="min-w-0 truncate text-xs text-muted-foreground">
|
|
274
|
+
{url ? (
|
|
275
|
+
<a href={/^https?:/i.test(s.url) ? s.url : `https://${s.url}`} target="_blank" rel="noreferrer" className="underline-offset-2 outline-none hover:underline focus-visible:ring-2 focus-visible:ring-ring">
|
|
276
|
+
{url}
|
|
277
|
+
</a>
|
|
278
|
+
) : null}
|
|
279
|
+
{url && s.read ? " · " : null}
|
|
280
|
+
{s.read ?? null}
|
|
281
|
+
</div>
|
|
282
|
+
) : null}
|
|
283
|
+
{s.evidence ? <Quote words={s.evidence} mark={mark} /> : null}
|
|
284
|
+
{footnote ? <div className="text-xs text-muted-foreground">{footnote}</div> : null}
|
|
285
|
+
{children}
|
|
286
|
+
</div>
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** What the agent tried, each page crossed off, with why it gave up. */
|
|
291
|
+
export function TriedList({ tried = [], className }) {
|
|
292
|
+
if (!tried.length) return null;
|
|
293
|
+
return (
|
|
294
|
+
<ul className={cx("grid gap-1 text-xs", className)}>
|
|
295
|
+
{tried.map((t, i) => (
|
|
296
|
+
<li key={i} className="flex min-w-0 items-baseline gap-2">
|
|
297
|
+
<s className="min-w-0 truncate text-muted-foreground">{t.title || shortUrl(t.url) || "a page"}</s>
|
|
298
|
+
{t.evidence ? <span className="min-w-0 truncate">{t.evidence}</span> : null}
|
|
299
|
+
</li>
|
|
300
|
+
))}
|
|
301
|
+
</ul>
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* The receipt: one answer opened, drawn big. Its head (the record, the
|
|
307
|
+
* question, the row), the value and its state in words, then the
|
|
308
|
+
* clippings: one for a found answer, two to pick from for two answers,
|
|
309
|
+
* the page that says a person left and who holds the role now, or what
|
|
310
|
+
* was tried for not found.
|
|
311
|
+
*
|
|
312
|
+
* answer the answer (model.js)
|
|
313
|
+
* title the record ("Klarwerk"); question ("Headcount"); where ("row 2")
|
|
314
|
+
* onPick(which) "one" | "other": Pick on each of two answers
|
|
315
|
+
* pickWords(value) the Pick button's words (default "Pick <value>")
|
|
316
|
+
* picked which of two was picked ("one" | "other"), drawn chosen
|
|
317
|
+
* read the date the pages were read ("read 22 Sep")
|
|
318
|
+
* by who found it, a node ("Found by the agent · 22 Sep, 10:31")
|
|
319
|
+
* valueLabel overrides the big value ("Head of Product, or Product Lead")
|
|
320
|
+
* stateWords overrides the state's words beside it
|
|
321
|
+
* leftTitle for a person who left: the title over who holds the role now
|
|
322
|
+
* children your actions, under the receipt
|
|
323
|
+
*/
|
|
324
|
+
export function Receipt({ answer, title, question, where, onPick, pickWords, picked, read, by, valueLabel, stateWords, leftTitle = "Now in the role", busy = false, children, className }) {
|
|
325
|
+
const st = answerState(answer);
|
|
326
|
+
const a = answer ?? {};
|
|
327
|
+
const two = st === "two_answers" || (a.other?.value && picked);
|
|
328
|
+
const left = a.flag === "left";
|
|
329
|
+
const kind = left || st === "two_answers" ? "two" : st === "not_found" ? "none" : st === "failed" ? "failed" : st === "typed" ? "typed" : st === "working" ? "looking" : sureKind(a.confidence);
|
|
330
|
+
const big =
|
|
331
|
+
valueLabel ??
|
|
332
|
+
(st === "two_answers" ? `${a.value} or ${a.other?.value ?? ""}` : st === "not_found" ? "Not found" : st === "failed" ? "Failed" : st === "working" ? "Looking up" : st === "empty" ? "Not asked yet" : a.value);
|
|
333
|
+
const words =
|
|
334
|
+
stateWords ??
|
|
335
|
+
(left
|
|
336
|
+
? "left the company · needs you"
|
|
337
|
+
: st === "two_answers"
|
|
338
|
+
? "two answers · the sources disagree"
|
|
339
|
+
: st === "checked"
|
|
340
|
+
? `${CONFIDENCE[a.confidence]?.label ?? "found"} · checked`
|
|
341
|
+
: st === "typed"
|
|
342
|
+
? "typed by a person · never overwritten"
|
|
343
|
+
: st === "not_found"
|
|
344
|
+
? a.checked
|
|
345
|
+
? "kept empty"
|
|
346
|
+
: "what it tried, crossed off"
|
|
347
|
+
: st === "failed"
|
|
348
|
+
? "a page didn't answer"
|
|
349
|
+
: CONFIDENCE[a.confidence]
|
|
350
|
+
? `${CONFIDENCE[a.confidence].label} · ${CONFIDENCE[a.confidence].words}`
|
|
351
|
+
: "");
|
|
352
|
+
const pickLabel = (v) => (pickWords ? pickWords(v) : `Pick ${v}`);
|
|
353
|
+
const withRead = (s) => (s ? { ...s, read: s.read ?? read } : s);
|
|
354
|
+
return (
|
|
355
|
+
<div className={cx("grid min-w-0 gap-3", className)}>
|
|
356
|
+
{title || question ? (
|
|
357
|
+
<div className="flex min-w-0 flex-wrap items-baseline gap-x-1.5">
|
|
358
|
+
{title ? <b className="text-sm font-semibold">{title}</b> : null}
|
|
359
|
+
{question || where ? <span className="text-muted-foreground">· {[question, where].filter(Boolean).join(" · ")}</span> : null}
|
|
360
|
+
</div>
|
|
361
|
+
) : null}
|
|
362
|
+
<div className="grid gap-1">
|
|
363
|
+
<span className={cx("break-words font-semibold leading-tight", String(big ?? "").length > 24 ? "text-xl" : "text-2xl", a.confidence === "guess" && st === "found" && "italic")}>{big}</span>
|
|
364
|
+
{words ? <TrustMark kind={kind} word={words} check={st === "checked"} className="text-xs" /> : null}
|
|
365
|
+
{a.detail && !two && st !== "failed" ? <span className="text-xs text-muted-foreground">{a.detail}</span> : null}
|
|
366
|
+
</div>
|
|
367
|
+
{two && !left ? (
|
|
368
|
+
<>
|
|
369
|
+
<Clipping
|
|
370
|
+
source={withRead(a.source)}
|
|
371
|
+
trust={a.confidence ?? "likely"}
|
|
372
|
+
mark={a.value}
|
|
373
|
+
picked={picked === "one"}
|
|
374
|
+
action={onPick ? (picked === "one" ? <Button size="sm" variant="primary" disabled>Picked</Button> : <Button size="sm" onClick={() => onPick("one")} disabled={busy}>{pickLabel(a.value)}</Button>) : null}
|
|
375
|
+
footnote={a.detail}
|
|
376
|
+
/>
|
|
377
|
+
<Clipping
|
|
378
|
+
source={withRead(a.other?.source)}
|
|
379
|
+
trust={a.other?.confidence ?? a.confidence ?? "likely"}
|
|
380
|
+
mark={a.other?.value}
|
|
381
|
+
picked={picked === "other"}
|
|
382
|
+
action={onPick ? (picked === "other" ? <Button size="sm" variant="primary" disabled>Picked</Button> : <Button size="sm" onClick={() => onPick("other")} disabled={busy}>{pickLabel(a.other?.value)}</Button>) : null}
|
|
383
|
+
footnote={a.other?.detail}
|
|
384
|
+
/>
|
|
385
|
+
</>
|
|
386
|
+
) : left ? (
|
|
387
|
+
<>
|
|
388
|
+
{a.source ? <Clipping source={withRead(a.source)} trust={a.confidence ?? "sure"} mark={a.value} footnote={a.note} /> : null}
|
|
389
|
+
{a.other?.value ? (
|
|
390
|
+
<>
|
|
391
|
+
<span className="text-[11px] uppercase tracking-[0.04em] text-muted-foreground">{leftTitle}</span>
|
|
392
|
+
<Clipping source={withRead(a.other.source)} trust="sure" title={`${a.other.value}${a.other.detail ? `, ${a.other.detail}` : ""}`} mark={a.other.value} />
|
|
393
|
+
</>
|
|
394
|
+
) : null}
|
|
395
|
+
</>
|
|
396
|
+
) : st === "not_found" || st === "failed" ? (
|
|
397
|
+
<Clipping source={{ title: st === "failed" ? "What it read" : "What it tried", read }} title={st === "failed" ? "What it read" : "What it tried"} footnote={a.note}>
|
|
398
|
+
<TriedList tried={a.tried?.length ? a.tried : a.source?.url ? [{ title: a.source.title, url: a.source.url, evidence: a.detail }] : []} />
|
|
399
|
+
</Clipping>
|
|
400
|
+
) : a.source?.url || a.source?.evidence ? (
|
|
401
|
+
<Clipping source={withRead(a.source)} trust={a.confidence} mark={a.value} footnote={st === "stale" ? "Out of date: its question or its row changed since. It keeps this until a new answer lands." : undefined} />
|
|
402
|
+
) : null}
|
|
403
|
+
{a.note && st !== "not_found" && st !== "failed" && !left ? (
|
|
404
|
+
<div className="text-xs">
|
|
405
|
+
<span className="text-[11px] uppercase tracking-[0.04em] text-muted-foreground">How it was found</span>
|
|
406
|
+
<br />
|
|
407
|
+
{a.note}
|
|
408
|
+
</div>
|
|
409
|
+
) : null}
|
|
410
|
+
{by ? <div className="flex flex-wrap items-center gap-1.5 text-xs text-muted-foreground">{by}</div> : null}
|
|
411
|
+
{children}
|
|
412
|
+
</div>
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* What a person can do with an answer: type their own (theirs, never
|
|
418
|
+
* overwritten), or ask again with a hint, its price said.
|
|
419
|
+
*
|
|
420
|
+
* onType(value) · typePlaceholder
|
|
421
|
+
* onAskAgain(hint) · hintPlaceholder · askCost ("about 40 credits")
|
|
422
|
+
* askNote a line under it ("The old answers go into this answer's history.")
|
|
423
|
+
* askLabel the button's words (default "Ask again")
|
|
424
|
+
* busy
|
|
425
|
+
*/
|
|
426
|
+
export function ReceiptActions({ onType, typePlaceholder = "Your answer", onAskAgain, hintPlaceholder = "Ask again with a hint", askCost, askNote, askLabel = "Ask again", hint: initialHint = "", busy = false, className }) {
|
|
427
|
+
const [typing, setTyping] = useState(false);
|
|
428
|
+
const [own, setOwn] = useState("");
|
|
429
|
+
const [hint, setHint] = useState(initialHint ?? "");
|
|
430
|
+
const ownId = useId();
|
|
431
|
+
const hintId = useId();
|
|
432
|
+
return (
|
|
433
|
+
<div className={cx("grid gap-2", className)}>
|
|
434
|
+
{onType ? (
|
|
435
|
+
typing ? (
|
|
436
|
+
<form
|
|
437
|
+
className="relative flex gap-2"
|
|
438
|
+
onSubmit={(e) => {
|
|
439
|
+
e.preventDefault();
|
|
440
|
+
if (own.trim()) onType(own.trim());
|
|
441
|
+
}}
|
|
442
|
+
>
|
|
443
|
+
<label htmlFor={ownId} className="sr-only">
|
|
444
|
+
Your own answer
|
|
445
|
+
</label>
|
|
446
|
+
<Input id={ownId} value={own} onChange={(e) => setOwn(e.target.value)} placeholder={typePlaceholder} className="min-w-0 flex-1" autoFocus />
|
|
447
|
+
<Button type="submit" size="sm" disabled={busy || !own.trim()}>
|
|
448
|
+
Save
|
|
449
|
+
</Button>
|
|
450
|
+
</form>
|
|
451
|
+
) : (
|
|
452
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
453
|
+
<Button size="sm" onClick={() => setTyping(true)} disabled={busy}>
|
|
454
|
+
Type my own
|
|
455
|
+
</Button>
|
|
456
|
+
<span className="text-xs text-muted-foreground">yours, never overwritten</span>
|
|
457
|
+
</div>
|
|
458
|
+
)
|
|
459
|
+
) : null}
|
|
460
|
+
{onAskAgain ? (
|
|
461
|
+
<form
|
|
462
|
+
className="relative grid gap-1"
|
|
463
|
+
onSubmit={(e) => {
|
|
464
|
+
e.preventDefault();
|
|
465
|
+
onAskAgain(hint.trim());
|
|
466
|
+
}}
|
|
467
|
+
>
|
|
468
|
+
<div className="flex gap-2">
|
|
469
|
+
<label htmlFor={hintId} className="sr-only">
|
|
470
|
+
A hint for the agent
|
|
471
|
+
</label>
|
|
472
|
+
<Input id={hintId} value={hint} onChange={(e) => setHint(e.target.value)} placeholder={hintPlaceholder} className="min-w-0 flex-1" />
|
|
473
|
+
<Button type="submit" size="sm" disabled={busy}>
|
|
474
|
+
<AgentMark />
|
|
475
|
+
{askLabel}
|
|
476
|
+
</Button>
|
|
477
|
+
</div>
|
|
478
|
+
{askCost || askNote ? <span className="text-xs text-muted-foreground">{[askCost, askNote].filter(Boolean).join(". ")}</span> : null}
|
|
479
|
+
</form>
|
|
480
|
+
) : null}
|
|
481
|
+
</div>
|
|
482
|
+
);
|
|
483
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { AnswerCell } from "./agent-column";
|
|
4
|
+
import { answerWords } from "./model";
|
|
5
|
+
|
|
6
|
+
// A column type for the spreadsheet block (and base-view, which passes
|
|
7
|
+
// `types` through): the value is an answer, drawn by AnswerCell. A person
|
|
8
|
+
// who types in the cell sets their own value (setBy "person"), which the
|
|
9
|
+
// app saves and the agent never overwrites.
|
|
10
|
+
//
|
|
11
|
+
// <Spreadsheet types={{ answer: answerColumnType }}
|
|
12
|
+
// columns={[{ key: "headcount", name: "Headcount", type: "answer", answerType: "number" }]} … />
|
|
13
|
+
export const answerColumnType = {
|
|
14
|
+
label: "Agent answer",
|
|
15
|
+
icon: "sparkles",
|
|
16
|
+
width: 200,
|
|
17
|
+
editor: "text",
|
|
18
|
+
empty: (v) => v == null || (v.value == null && v.status == null),
|
|
19
|
+
parse: (text) => ({ value: { status: "found", value: String(text ?? "").trim(), setBy: "person" } }),
|
|
20
|
+
toText: (v) => (v?.value == null ? "" : String(v.value)),
|
|
21
|
+
format: (v) => (v?.value != null ? String(v.value) : answerWords(v)),
|
|
22
|
+
compare: (a, b) => String(a?.value ?? "").localeCompare(String(b?.value ?? ""), undefined, { numeric: true }),
|
|
23
|
+
render: (v, column) => <AnswerCell answer={v} type={column?.answerType ?? "text"} lines={1} />,
|
|
24
|
+
};
|