@agent-native/core-corpus 0.210.2 → 0.211.0
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +41 -2
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +4 -2
- package/corpus/templates/analytics/CHANGELOG.md +18 -0
- package/corpus/templates/analytics/actions/build-data-index.ts +11 -2
- package/corpus/templates/analytics/actions/configure-content-collection.ts +29 -4
- package/corpus/templates/analytics/actions/configure-first-party-events-model.ts +9 -7
- package/corpus/templates/analytics/actions/create-analytics-public-key.ts +4 -0
- package/corpus/templates/analytics/actions/estimate-content-signups-cost.ts +72 -0
- package/corpus/templates/analytics/actions/estimate-query-cost.ts +16 -134
- package/corpus/templates/analytics/actions/list-sigma-workbooks.ts +123 -42
- package/corpus/templates/analytics/actions/migrate-sigma-workbook.ts +20 -17
- package/corpus/templates/analytics/actions/revoke-analytics-public-key.ts +4 -0
- package/corpus/templates/analytics/app/components/dashboard/SigmaMigrationDialog.tsx +246 -680
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/analytics/app/i18n/en-US.ts +54 -55
- package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +0 -1
- package/corpus/templates/analytics/app/pages/DataSources.tsx +56 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/filter-vars.ts +4 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +26 -8
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/interpolate.ts +3 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/panel-cost-notice.ts +172 -0
- package/corpus/templates/analytics/app/pages/data-sources/SearchConsoleDetail.tsx +441 -0
- package/corpus/templates/analytics/changelog/2026-10-15-a-content-dashboard-lists-every-blog-article-with-its-author.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-15-data-sources-has-a-google-search-console-card-that-shows-the.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-16-the-content-dashboard-can-show-signups-per-blog-article.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-19-creating-or-revoking-a-public-analytics-key-now-asks-you-to-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-19-search-sigma-workbooks-by-name-and-open-ones-a-teammate-alre.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-blog-signup-attribution-excludes-signups-before-the-first-vi.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-collapsed-analytics-navigation-starts-at-the-top.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-content-keeps-successful-coverage-dates-and-missing-day-gaps.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-private-github-repositories-can-be-indexed-with-your-connect.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-search-console-preserves-backfill-and-paused-collection.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-search-console-refreshes-historical-coverage-when-properties.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-search-console-setup-keeps-saved-properties-readable-and-sup.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/content-view.json +182 -0
- package/corpus/templates/analytics/server/db/schema.ts +1 -0
- package/corpus/templates/analytics/server/lib/bi-migration/external-dashboards-store.ts +56 -18
- package/corpus/templates/analytics/server/lib/bi-migration/unfinished-import.ts +64 -0
- package/corpus/templates/analytics/server/lib/builtin-dashboard-pass.ts +17 -2
- package/corpus/templates/analytics/server/lib/content-metrics/collect.ts +2 -0
- package/corpus/templates/analytics/server/lib/content-metrics/config.ts +92 -3
- package/corpus/templates/analytics/server/lib/content-metrics/legacy-content-view.json +172 -0
- package/corpus/templates/analytics/server/lib/content-metrics/migration.ts +2 -0
- package/corpus/templates/analytics/server/lib/content-metrics/steps/daily-metrics.ts +8 -3
- package/corpus/templates/analytics/server/lib/content-metrics/steps/search-console.ts +16 -3
- package/corpus/templates/analytics/server/lib/content-metrics/steps/signups.ts +240 -0
- package/corpus/templates/analytics/server/lib/content-metrics/store.ts +5 -0
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +21 -0
- package/corpus/templates/analytics/server/lib/dashboard-panel-verification.ts +300 -5
- package/corpus/templates/analytics/server/lib/dashboard-seeds.ts +2 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +28 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +128 -24
- package/corpus/templates/analytics/server/lib/google-analytics.ts +56 -16
- package/corpus/templates/analytics/server/lib/index-build-github.ts +5 -0
- package/corpus/templates/analytics/server/lib/provider-credentials.ts +47 -2
- package/corpus/templates/analytics/server/lib/query-cost-estimate.ts +184 -5
- package/corpus/templates/analytics/server/plugins/db.ts +9 -1
- package/corpus/templates/analytics/shared/builtin-dashboard-ids.ts +2 -0
- package/corpus/templates/analytics/shared/search-console-property.ts +78 -0
- package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/calendar/actions/delete-event.ts +1 -3
- package/corpus/templates/calendar/actions/delete-events.ts +1 -2
- package/corpus/templates/calendar/actions/event-action-helpers.ts +0 -4
- package/corpus/templates/calendar/actions/update-event.ts +2 -6
- package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/clips/CHANGELOG.md +11 -24
- package/corpus/templates/clips/actions/create-recording-upload.ts +5 -1
- package/corpus/templates/clips/app/components/player/chapter-list.tsx +7 -6
- package/corpus/templates/clips/app/components/player/comment-composer.tsx +5 -1
- package/corpus/templates/clips/app/components/player/player-controls.tsx +1 -0
- package/corpus/templates/clips/app/components/player/scrubber.tsx +4 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +3 -3
- package/corpus/templates/clips/app/lib/extension-auth.ts +70 -0
- package/corpus/templates/clips/app/root.tsx +22 -10
- package/corpus/templates/clips/app/routes/_app.notifications.tsx +3 -0
- package/corpus/templates/clips/app/routes/import.tsx +115 -110
- package/corpus/templates/clips/changelog/2026-10-16-agent-uploads-can-use-free-clips-storage.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-19-agents-see-a-clip-s-frames-as-soon-as-it-finishes-processing.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-19-chapter-list-times-now-match-the-player-s-clock-and-each-cha.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-19-editing-a-comment-puts-the-cursor-after-its-text-and-reply-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-19-youtube-import-followups.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-20-locally-saved-desktop-recordings-now-appear-in-the-recovery-.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +29 -186
- package/corpus/templates/clips/desktop/src/components/RecordingRecovery.tsx +171 -16
- package/corpus/templates/clips/desktop/src/lib/record-first.ts +9 -32
- package/corpus/templates/clips/desktop/src/lib/recording-recovery.ts +30 -1
- package/corpus/templates/clips/server/lib/agent-frame-request.ts +5 -2
- package/corpus/templates/clips/server/lib/recording-upload-ticket.ts +8 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +2 -0
- package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/content/CHANGELOG.md +12 -0
- package/corpus/templates/content/actions/_content-database-personal-view.ts +5 -15
- package/corpus/templates/content/actions/_database-navigation.ts +3 -3
- package/corpus/templates/content/actions/_database-utils.ts +10 -22
- package/corpus/templates/content/actions/_database-view-setup.ts +16 -76
- package/corpus/templates/content/actions/create-comment-ai-suggestion.ts +93 -44
- package/corpus/templates/content/actions/export-document.ts +2 -14
- package/corpus/templates/content/actions/suggest-document-edit.ts +5 -7
- package/corpus/templates/content/actions/update-content-database-view.ts +2 -14
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +86 -30
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +64 -28
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +6 -46
- package/corpus/templates/content/app/components/editor/PageDraftRecovery.tsx +72 -7
- package/corpus/templates/content/app/components/editor/TableHoverControls.tsx +292 -103
- package/corpus/templates/content/app/components/editor/ThreadSuggestion.tsx +147 -40
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +108 -11
- package/corpus/templates/content/app/components/editor/database/ContentTable.tsx +2 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +150 -166
- package/corpus/templates/content/app/components/editor/database/database-cell-comments.tsx +515 -0
- package/corpus/templates/content/app/components/editor/database/database-item-comments.tsx +5 -43
- package/corpus/templates/content/app/components/editor/database/filter-sort.ts +8 -783
- package/corpus/templates/content/app/components/editor/live-editor-session.ts +5 -1
- package/corpus/templates/content/app/components/editor/page-draft-journal.ts +61 -1
- package/corpus/templates/content/app/components/editor/property-comments.tsx +35 -4
- package/corpus/templates/content/app/components/editor/property-date-format.ts +45 -0
- package/corpus/templates/content/app/components/editor/thread-suggestions.ts +30 -0
- package/corpus/templates/content/app/components/editor/useDocumentReconcileRecovery.ts +23 -4
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +36 -10
- package/corpus/templates/content/app/global.css +23 -0
- package/corpus/templates/content/app/i18n-data.ts +1 -0
- package/corpus/templates/content/changelog/2026-10-16-opening-a-page-in-a-new-tab-while-another-tab-is-still-savin.md +6 -0
- package/corpus/templates/content/changelog/2026-10-16-typing-steadily-in-one-tab-no-longer-makes-another-open-tab-.md +6 -0
- package/corpus/templates/content/changelog/2026-10-19-database-views-can-filter-the-same-property-more-than-once-n.md +6 -0
- package/corpus/templates/content/changelog/2026-10-19-edits-made-from-a-block-s-menu-or-a-table-s-row-and-column-m.md +6 -0
- package/corpus/templates/content/changelog/2026-10-19-starting-a-comment-puts-the-cursor-in-the-comment-box-ready-.md +6 -0
- package/corpus/templates/content/changelog/2026-10-19-table-row-and-column-options-now-appear-for-the-row-or-colum.md +6 -0
- package/corpus/templates/content/docs/product/capabilities/content.comment.page-owned.md +5 -1
- package/corpus/templates/content/docs/product/capabilities/content.revision.suggestions.md +3 -1
- package/corpus/templates/content/e2e/helpers.ts +10 -0
- package/corpus/templates/content/shared/api.ts +18 -12
- package/corpus/templates/content/shared/database-query.ts +107 -13
- package/corpus/templates/content/shared/suggestion-diff.ts +35 -0
- package/corpus/templates/crm/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/design/CHANGELOG.md +2 -0
- package/corpus/templates/design/actions/delete-file.ts +1 -4
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +10 -1
- package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +24 -4
- package/corpus/templates/design/app/pages/design-editor/commands/mode-change.ts +14 -9
- package/corpus/templates/design/app/pages/design-editor/domains/use-editor-modes.ts +23 -2
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +29 -0
- package/corpus/templates/design/changelog/2026-10-19-reply-and-edit-on-a-comment-in-the-sidebar-or-on-a-canvas-pi.md +6 -0
- package/corpus/templates/design/changelog/2026-10-20-comments-return-to-the-mode-they-came-from-and-layers-search.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +185 -85
- package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/dispatch/CHANGELOG.md +4 -0
- package/corpus/templates/dispatch/actions/apply-workspace-connection-setup.ts +4 -0
- package/corpus/templates/dispatch/actions/delete-workspace-connection.ts +4 -0
- package/corpus/templates/dispatch/actions/set-workspace-connection-grant.ts +4 -0
- package/corpus/templates/dispatch/actions/upsert-workspace-connection.ts +4 -0
- package/corpus/templates/dispatch/changelog/2026-10-19-vault-secrets-grants-link-tokens-app-access-and-workspace-co.md +6 -0
- package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +105 -33
- package/corpus/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +128 -74
- package/corpus/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +39 -11
- package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/mail/.agents/skills/contacts-and-crm/SKILL.md +22 -17
- package/corpus/templates/mail/AGENTS.md +1 -1
- package/corpus/templates/mail/CHANGELOG.md +14 -0
- package/corpus/templates/mail/actions/provider-api-request.ts +3 -3
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +211 -54
- package/corpus/templates/mail/app/hooks/use-inbox-threads.ts +26 -2
- package/corpus/templates/mail/app/i18n/en-US.ts +5 -1
- package/corpus/templates/mail/app/lib/gong-connection.ts +27 -0
- package/corpus/templates/mail/app/lib/thread-cache.ts +110 -9
- package/corpus/templates/mail/app/root.tsx +10 -2
- package/corpus/templates/mail/changelog/2026-10-20-connected-gong-settings-now-open-the-shared-integration-mana.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-gong-connection-details-now-match-the-call-data-available-in.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-improve-gong-setup-with-a-click-to-connect-flow-and-permissi.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-mail-lets-you-retry-when-it-cannot-check-your-gong-access.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-mail-thread-cache-stays-isolated-when-mailbox-scope-changes.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-the-inbox-and-recently-opened-threads-now-open-instantly-fro.md +6 -0
- package/corpus/templates/mail/server/handlers/emails.ts +9 -0
- package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/plan/CHANGELOG.md +4 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +173 -33
- package/corpus/templates/plan/changelog/2026-10-19-opening-a-comment-thread-puts-the-cursor-in-the-reply-box-an.md +6 -0
- package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +6 -42
- package/corpus/templates/slides/app/components/editor/FloatingToolbar.tsx +3 -7
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +5 -14
- package/corpus/templates/slides/app/i18n/en-US.ts +0 -2
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +27 -33
- package/corpus/templates/slides/scripts/edit-fidelity/run.ts +1 -3
- package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +5 -3
- package/package.json +1 -1
|
@@ -349,7 +349,12 @@ export {
|
|
|
349
349
|
};
|
|
350
350
|
export type { NativeMarkerPlacement } from "@/lib/plan-native-anchors";
|
|
351
351
|
export type { PlanOrgAccessPrompt } from "@/lib/plan-access-prompt";
|
|
352
|
-
export {
|
|
352
|
+
export {
|
|
353
|
+
AnnotationPopover,
|
|
354
|
+
canSubmitInlineCommentDraft,
|
|
355
|
+
CommentMentionEditor,
|
|
356
|
+
mentionQueryAtCaret,
|
|
357
|
+
};
|
|
353
358
|
export type { CommentDraft } from "@/lib/plan-comment-editor-helpers";
|
|
354
359
|
|
|
355
360
|
export function buildPlanEmailVerificationCallbackURL(
|
|
@@ -5742,6 +5747,7 @@ export function PlansPage({ localPlanSlug }: { localPlanSlug?: string } = {}) {
|
|
|
5742
5747
|
) : (
|
|
5743
5748
|
<InlineCommentPopover
|
|
5744
5749
|
key={failedCommentDraft ? "retry" : "new"}
|
|
5750
|
+
anchor={pendingAnnotation}
|
|
5745
5751
|
position={inlineCommentPosition}
|
|
5746
5752
|
initialDraft={
|
|
5747
5753
|
failedCommentDraft ?? defaultInlineCommentDraft
|
|
@@ -5749,6 +5755,7 @@ export function PlansPage({ localPlanSlug }: { localPlanSlug?: string } = {}) {
|
|
|
5749
5755
|
onCancel={closeInlineComment}
|
|
5750
5756
|
onSubmit={submitInlineComment}
|
|
5751
5757
|
lockToAgent={localPlanMode}
|
|
5758
|
+
reopened={Boolean(failedCommentDraft)}
|
|
5752
5759
|
/>
|
|
5753
5760
|
)}
|
|
5754
5761
|
</>
|
|
@@ -8930,9 +8937,26 @@ function CreatePlanDialog({
|
|
|
8930
8937
|
);
|
|
8931
8938
|
}
|
|
8932
8939
|
|
|
8940
|
+
/** Nothing on the page holds focus, so taking it moves nobody's caret. */
|
|
8941
|
+
function focusIsFree() {
|
|
8942
|
+
const active = document.activeElement;
|
|
8943
|
+
return !active || active === document.body;
|
|
8944
|
+
}
|
|
8945
|
+
|
|
8946
|
+
function focusCommentEditorAtEnd(root: HTMLElement) {
|
|
8947
|
+
root.focus();
|
|
8948
|
+
const selection = window.getSelection();
|
|
8949
|
+
const range = document.createRange();
|
|
8950
|
+
range.selectNodeContents(root);
|
|
8951
|
+
range.collapse(false);
|
|
8952
|
+
selection?.removeAllRanges();
|
|
8953
|
+
selection?.addRange(range);
|
|
8954
|
+
}
|
|
8955
|
+
|
|
8933
8956
|
function CommentMentionEditor({
|
|
8934
8957
|
initialMessage,
|
|
8935
8958
|
resetKey,
|
|
8959
|
+
focusKey,
|
|
8936
8960
|
placeholder,
|
|
8937
8961
|
className,
|
|
8938
8962
|
autoFocus,
|
|
@@ -8941,9 +8965,12 @@ function CommentMentionEditor({
|
|
|
8941
8965
|
}: {
|
|
8942
8966
|
initialMessage?: string;
|
|
8943
8967
|
resetKey?: string;
|
|
8968
|
+
/** A new value puts the caret back in the editor and keeps its text. */
|
|
8969
|
+
focusKey?: unknown;
|
|
8944
8970
|
placeholder: string;
|
|
8945
8971
|
className?: string;
|
|
8946
|
-
|
|
8972
|
+
/** "if-free" only takes focus nobody holds, for a box reopened after a failed save. */
|
|
8973
|
+
autoFocus?: boolean | "if-free";
|
|
8947
8974
|
onChange: (draft: Pick<CommentDraft, "message" | "mentions">) => void;
|
|
8948
8975
|
onSubmitShortcut?: () => void;
|
|
8949
8976
|
}) {
|
|
@@ -8975,19 +9002,36 @@ function CommentMentionEditor({
|
|
|
8975
9002
|
useEffect(() => {
|
|
8976
9003
|
const root = editorRef.current;
|
|
8977
9004
|
if (!root) return;
|
|
9005
|
+
const hadFocus = root.contains(document.activeElement);
|
|
8978
9006
|
appendMessageToEditor(root, initialMessage ?? "");
|
|
8979
9007
|
emitChange();
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
9008
|
+
// Reloading the text keeps the caret in an editor that had it.
|
|
9009
|
+
if (hadFocus) focusCommentEditorAtEnd(root);
|
|
9010
|
+
if (!autoFocus || (autoFocus === "if-free" && !focusIsFree())) return;
|
|
9011
|
+
// An Edit menu item mounts this editor while its menu still traps focus,
|
|
9012
|
+
// so keep trying for a few frames until focus lands.
|
|
9013
|
+
let attempts = 0;
|
|
9014
|
+
let frame = 0;
|
|
9015
|
+
const focusEditor = () => {
|
|
9016
|
+
focusCommentEditorAtEnd(root);
|
|
9017
|
+
if (document.activeElement !== root && ++attempts < 10)
|
|
9018
|
+
frame = requestAnimationFrame(focusEditor);
|
|
9019
|
+
};
|
|
9020
|
+
focusEditor();
|
|
9021
|
+
return () => cancelAnimationFrame(frame);
|
|
8989
9022
|
}, [autoFocus, emitChange, initialMessage, resetKey]);
|
|
8990
9023
|
|
|
9024
|
+
// Only a new key moves the caret; mounting is autoFocus's job.
|
|
9025
|
+
const focusKeyRef = useRef(focusKey);
|
|
9026
|
+
useEffect(() => {
|
|
9027
|
+
if (focusKeyRef.current === focusKey) return;
|
|
9028
|
+
focusKeyRef.current = focusKey;
|
|
9029
|
+
const root = editorRef.current;
|
|
9030
|
+
if (!root || focusKey === undefined) return;
|
|
9031
|
+
if (root.contains(document.activeElement)) return;
|
|
9032
|
+
focusCommentEditorAtEnd(root);
|
|
9033
|
+
}, [focusKey]);
|
|
9034
|
+
|
|
8991
9035
|
const selectMember = (member: OrgMemberSuggestion) => {
|
|
8992
9036
|
const root = editorRef.current;
|
|
8993
9037
|
const active = activeQueryRef.current;
|
|
@@ -9158,17 +9202,22 @@ function ResolutionTargetToggle({
|
|
|
9158
9202
|
}
|
|
9159
9203
|
|
|
9160
9204
|
function InlineCommentPopover({
|
|
9205
|
+
anchor,
|
|
9161
9206
|
position,
|
|
9162
9207
|
initialDraft,
|
|
9163
9208
|
onCancel,
|
|
9164
9209
|
onSubmit,
|
|
9165
9210
|
lockToAgent = false,
|
|
9211
|
+
reopened = false,
|
|
9166
9212
|
}: {
|
|
9213
|
+
anchor: PlanAnnotationAnchor;
|
|
9167
9214
|
position: InlineCommentPosition;
|
|
9168
9215
|
initialDraft: CommentDraft;
|
|
9169
9216
|
onCancel: () => void;
|
|
9170
9217
|
onSubmit: (draft: CommentDraft) => Promise<void>;
|
|
9171
9218
|
lockToAgent?: boolean;
|
|
9219
|
+
/** Shown again after a failed save, when the person may have moved on. */
|
|
9220
|
+
reopened?: boolean;
|
|
9172
9221
|
}) {
|
|
9173
9222
|
const t = useT();
|
|
9174
9223
|
const initialMessageRef = useRef(initialDraft.message);
|
|
@@ -9249,7 +9298,10 @@ function InlineCommentPopover({
|
|
|
9249
9298
|
<CommentMentionEditor
|
|
9250
9299
|
initialMessage={initialMessageRef.current}
|
|
9251
9300
|
placeholder={t("plansPage.comments.addPlaceholder")}
|
|
9252
|
-
autoFocus
|
|
9301
|
+
autoFocus={reopened ? "if-free" : true}
|
|
9302
|
+
// Commenting somewhere else moves this popover instead of
|
|
9303
|
+
// remounting it, so the draft keeps its text and gets the caret.
|
|
9304
|
+
focusKey={anchor}
|
|
9253
9305
|
onSubmitShortcut={submit}
|
|
9254
9306
|
onChange={(value) =>
|
|
9255
9307
|
setDraft((current) => {
|
|
@@ -9387,42 +9439,110 @@ function CommentDeleteButton({
|
|
|
9387
9439
|
);
|
|
9388
9440
|
}
|
|
9389
9441
|
|
|
9442
|
+
/** What a reply box shows: the editor reloads `loadedMessage` when `version` changes. */
|
|
9443
|
+
function loadReplyBox({
|
|
9444
|
+
threadId,
|
|
9445
|
+
message,
|
|
9446
|
+
version,
|
|
9447
|
+
takeFocus,
|
|
9448
|
+
}: {
|
|
9449
|
+
threadId: string;
|
|
9450
|
+
message: string;
|
|
9451
|
+
version: number;
|
|
9452
|
+
takeFocus: boolean;
|
|
9453
|
+
}) {
|
|
9454
|
+
const draft: Pick<CommentDraft, "message" | "mentions"> = {
|
|
9455
|
+
message,
|
|
9456
|
+
mentions: extractCommentMentions(message),
|
|
9457
|
+
};
|
|
9458
|
+
return { threadId, loadedMessage: message, version, takeFocus, draft };
|
|
9459
|
+
}
|
|
9460
|
+
|
|
9390
9461
|
function ReplyComposer({
|
|
9391
9462
|
author,
|
|
9392
9463
|
isPending,
|
|
9393
9464
|
placeholder,
|
|
9465
|
+
autoFocus,
|
|
9466
|
+
threadId = "",
|
|
9394
9467
|
onSubmit,
|
|
9395
9468
|
}: {
|
|
9396
9469
|
author: CommentAuthorPresentation;
|
|
9397
9470
|
isPending: boolean;
|
|
9398
9471
|
placeholder?: string;
|
|
9472
|
+
autoFocus?: boolean;
|
|
9473
|
+
/** One box can reply to several threads in turn; each keeps its own draft. */
|
|
9474
|
+
threadId?: string;
|
|
9399
9475
|
onSubmit: (message: string) => Promise<void>;
|
|
9400
9476
|
}) {
|
|
9401
9477
|
const t = useT();
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
const [
|
|
9410
|
-
const [
|
|
9478
|
+
// Unsent replies by thread, including the one on screen.
|
|
9479
|
+
const [drafts] = useState(() => new Map<string, string>());
|
|
9480
|
+
// The thread on screen and its draft change together, so Send always
|
|
9481
|
+
// pairs them.
|
|
9482
|
+
const [box, setBox] = useState(() =>
|
|
9483
|
+
loadReplyBox({ threadId, message: "", version: 0, takeFocus: true }),
|
|
9484
|
+
);
|
|
9485
|
+
const [sendingThreadIds, setSendingThreadIds] = useState<string[]>([]);
|
|
9486
|
+
const [failedThreadIds, setFailedThreadIds] = useState<string[]>([]);
|
|
9487
|
+
|
|
9488
|
+
if (box.threadId !== threadId) {
|
|
9489
|
+
// Opening another thread brings back that thread's own reply.
|
|
9490
|
+
setBox(
|
|
9491
|
+
loadReplyBox({
|
|
9492
|
+
threadId,
|
|
9493
|
+
message: drafts.get(threadId) ?? "",
|
|
9494
|
+
version: box.version + 1,
|
|
9495
|
+
takeFocus: true,
|
|
9496
|
+
}),
|
|
9497
|
+
);
|
|
9498
|
+
}
|
|
9411
9499
|
|
|
9500
|
+
const isSubmitting = sendingThreadIds.includes(box.threadId);
|
|
9412
9501
|
const canSubmit =
|
|
9413
|
-
commentBodyText(draft.message).length > 0 &&
|
|
9502
|
+
commentBodyText(box.draft.message).length > 0 &&
|
|
9503
|
+
!isSubmitting &&
|
|
9504
|
+
!isPending;
|
|
9414
9505
|
const submit = async () => {
|
|
9415
9506
|
if (!canSubmit) return;
|
|
9416
|
-
|
|
9417
|
-
|
|
9507
|
+
const sentThreadId = box.threadId;
|
|
9508
|
+
const message = box.draft.message;
|
|
9509
|
+
setFailedThreadIds((ids) => ids.filter((id) => id !== sentThreadId));
|
|
9510
|
+
setSendingThreadIds((ids) => [...ids, sentThreadId]);
|
|
9511
|
+
// Empty the box right away. The reply shows in the thread while it
|
|
9512
|
+
// sends, and anything typed meanwhile is a new draft.
|
|
9513
|
+
drafts.set(sentThreadId, "");
|
|
9514
|
+
setBox((current) =>
|
|
9515
|
+
loadReplyBox({
|
|
9516
|
+
threadId: current.threadId,
|
|
9517
|
+
message: "",
|
|
9518
|
+
version: current.version + 1,
|
|
9519
|
+
takeFocus: true,
|
|
9520
|
+
}),
|
|
9521
|
+
);
|
|
9418
9522
|
try {
|
|
9419
|
-
await onSubmit(
|
|
9420
|
-
setDraft({ message: "", mentions: [] });
|
|
9421
|
-
setResetKey((key) => key + 1);
|
|
9523
|
+
await onSubmit(message.trim());
|
|
9422
9524
|
} catch {
|
|
9423
|
-
|
|
9525
|
+
// Put the reply back in its thread's box, ahead of anything typed
|
|
9526
|
+
// since, wherever that box is now.
|
|
9527
|
+
const typedSince = drafts.get(sentThreadId)?.trim();
|
|
9528
|
+
const restored = typedSince ? `${message} ${typedSince}` : message;
|
|
9529
|
+
drafts.set(sentThreadId, restored);
|
|
9530
|
+
setFailedThreadIds((ids) => [
|
|
9531
|
+
...ids.filter((id) => id !== sentThreadId),
|
|
9532
|
+
sentThreadId,
|
|
9533
|
+
]);
|
|
9534
|
+
setBox((current) =>
|
|
9535
|
+
current.threadId === sentThreadId
|
|
9536
|
+
? loadReplyBox({
|
|
9537
|
+
threadId: sentThreadId,
|
|
9538
|
+
message: restored,
|
|
9539
|
+
version: current.version + 1,
|
|
9540
|
+
takeFocus: false,
|
|
9541
|
+
})
|
|
9542
|
+
: current,
|
|
9543
|
+
);
|
|
9424
9544
|
} finally {
|
|
9425
|
-
|
|
9545
|
+
setSendingThreadIds((ids) => ids.filter((id) => id !== sentThreadId));
|
|
9426
9546
|
}
|
|
9427
9547
|
};
|
|
9428
9548
|
|
|
@@ -9435,9 +9555,16 @@ function ReplyComposer({
|
|
|
9435
9555
|
placeholder={
|
|
9436
9556
|
placeholder ?? t("plansPage.comments.replyPlaceholder")
|
|
9437
9557
|
}
|
|
9438
|
-
|
|
9558
|
+
initialMessage={box.loadedMessage}
|
|
9559
|
+
resetKey={`reply-${box.version}`}
|
|
9560
|
+
// Only opening the thread or pressing Send pulls focus here; a
|
|
9561
|
+
// reply put back after a failed send takes only free focus.
|
|
9562
|
+
autoFocus={!autoFocus ? false : box.takeFocus ? true : "if-free"}
|
|
9439
9563
|
className="min-h-10 border-0 bg-transparent px-0 py-2 shadow-none focus-visible:ring-0"
|
|
9440
|
-
onChange={
|
|
9564
|
+
onChange={(next) => {
|
|
9565
|
+
setBox((current) => ({ ...current, draft: next }));
|
|
9566
|
+
drafts.set(box.threadId, next.message);
|
|
9567
|
+
}}
|
|
9441
9568
|
onSubmitShortcut={() => void submit()}
|
|
9442
9569
|
/>
|
|
9443
9570
|
<Button
|
|
@@ -9456,7 +9583,7 @@ function ReplyComposer({
|
|
|
9456
9583
|
</Button>
|
|
9457
9584
|
</div>
|
|
9458
9585
|
</div>
|
|
9459
|
-
{
|
|
9586
|
+
{failedThreadIds.includes(box.threadId) && (
|
|
9460
9587
|
<p className="ml-11 text-xs text-destructive">
|
|
9461
9588
|
{t("plansPage.comments.sendFailed")}
|
|
9462
9589
|
</p>
|
|
@@ -9500,6 +9627,7 @@ function AnnotationPopover({
|
|
|
9500
9627
|
}) {
|
|
9501
9628
|
const t = useT();
|
|
9502
9629
|
const popoverRef = useRef<HTMLDivElement>(null);
|
|
9630
|
+
const editChosenFromMenuRef = useRef(false);
|
|
9503
9631
|
const [editing, setEditing] = useState(false);
|
|
9504
9632
|
const [messageDraft, setMessageDraft] = useState<
|
|
9505
9633
|
Pick<CommentDraft, "message" | "mentions">
|
|
@@ -9612,6 +9740,12 @@ function AnnotationPopover({
|
|
|
9612
9740
|
align="end"
|
|
9613
9741
|
className="w-48 rounded-xl"
|
|
9614
9742
|
data-comment-popover-portal
|
|
9743
|
+
onCloseAutoFocus={(event) => {
|
|
9744
|
+
// Edit puts focus in its editor; leave it there. Other
|
|
9745
|
+
// actions return to the button.
|
|
9746
|
+
if (editChosenFromMenuRef.current) event.preventDefault();
|
|
9747
|
+
editChosenFromMenuRef.current = false;
|
|
9748
|
+
}}
|
|
9615
9749
|
>
|
|
9616
9750
|
{canResolve && (
|
|
9617
9751
|
<DropdownMenuItem
|
|
@@ -9629,7 +9763,10 @@ function AnnotationPopover({
|
|
|
9629
9763
|
{canEditRootComment && (
|
|
9630
9764
|
<DropdownMenuItem
|
|
9631
9765
|
className="gap-2"
|
|
9632
|
-
onClick={() =>
|
|
9766
|
+
onClick={() => {
|
|
9767
|
+
editChosenFromMenuRef.current = true;
|
|
9768
|
+
setEditing(true);
|
|
9769
|
+
}}
|
|
9633
9770
|
>
|
|
9634
9771
|
<IconPencil className="size-4" />
|
|
9635
9772
|
{t("plansPage.comments.editFirstComment")}
|
|
@@ -9759,6 +9896,9 @@ function AnnotationPopover({
|
|
|
9759
9896
|
<ReplyComposer
|
|
9760
9897
|
author={pendingAuthor}
|
|
9761
9898
|
isPending={isPending}
|
|
9899
|
+
autoFocus
|
|
9900
|
+
// Opening another thread reuses this popover and its reply box.
|
|
9901
|
+
threadId={annotation.id}
|
|
9762
9902
|
onSubmit={(reply) => onReply(annotation.id, reply)}
|
|
9763
9903
|
/>
|
|
9764
9904
|
</div>
|
|
@@ -95,9 +95,9 @@ MCP clients see no `outputSchema` by default. Set `mcpOutputSchema: true` (requi
|
|
|
95
95
|
|
|
96
96
|
`authorize` decides whether the caller may run the action at all. It wraps
|
|
97
97
|
`run`, so it holds at **all six dispatch sites** — agent tool, HTTP, frontend
|
|
98
|
-
hook, MCP, A2A, CLI
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
hook, MCP, A2A, CLI. Use `authorize` for "not everyone may do this"; use
|
|
99
|
+
`needsApproval` to ask a human to bless one call a permitted caller is already
|
|
100
|
+
allowed to make.
|
|
101
101
|
|
|
102
102
|
```ts
|
|
103
103
|
import { coachAccess } from "../lib/access.js"; // defineAppRoles(...)
|
|
@@ -140,4 +140,6 @@ export default defineAction({
|
|
|
140
140
|
|
|
141
141
|
When the gate is truthy and the call isn't yet approved, the loop emits an `approval_required` event and **stops the turn — `run()` never executes**. A predicate gates conditionally (e.g. only external recipients) and **fails closed**: a throw is treated as "approval required". It receives its own copy of the prepared snapshot of the validated arguments, defaults applied, and the approval binds to the snapshot's hash, so an approved call runs only with the arguments that were approved (a Date binds by its time). The human approves via the chat UI's Approve affordance, which re-issues the turn with the call's `approvalKey`, and only then does the action run.
|
|
142
142
|
|
|
143
|
+
Approval is given in the app, so HTTP never grants it. The HTTP action route and the generated Workers entry run a gated call only for the proven app UI (a frontend call from the signed-in user, same origin, holding the short-lived UI capability; `isProvenUiRequest`, the proof `uiOnly` uses) or the app's MCP directory widget. Every other HTTP caller (bearer or API key, MCP OAuth token, org service token, A2A, extension iframe, mobile app) gets `409 approval_required`, and a service identity can never approve. The shared client presents the capability with every write from a signed-in session (minted once per user, reused for nine minutes, never for reads or public pages), so a gated button works on its first request. A call without proof gets `403 ui_capability_required`; the client then re-mints and retries once, which is only the fallback for an expired or rejected capability. Every surface evaluates the gate through `preparedCallNeedsApproval`, so a throwing predicate asks there too. A caller that must run unattended needs a different action, never a bypass of the gate.
|
|
144
|
+
|
|
143
145
|
**Keep approvals rare** — the default is off and almost every action should leave it off. The canonical example is Mail's `send-email` (`needsApproval: true`). See the `security` skill and the Human Approval doc.
|
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
IconLoader2,
|
|
31
31
|
IconAdjustments,
|
|
32
32
|
IconPencilPlus,
|
|
33
|
-
IconPin,
|
|
34
33
|
IconBrandGoogle,
|
|
35
34
|
IconCode,
|
|
36
35
|
IconCopy,
|
|
@@ -146,7 +145,6 @@ interface EditorToolbarProps {
|
|
|
146
145
|
deckId: string;
|
|
147
146
|
deckTitle: string;
|
|
148
147
|
canEdit?: boolean;
|
|
149
|
-
canComment?: boolean;
|
|
150
148
|
onTitleChange: (title: string) => void;
|
|
151
149
|
currentSlideIndex: number;
|
|
152
150
|
sidebarOpen: boolean;
|
|
@@ -172,8 +170,6 @@ interface EditorToolbarProps {
|
|
|
172
170
|
onToggleTweaks?: () => void;
|
|
173
171
|
drawMode?: boolean;
|
|
174
172
|
onToggleDrawMode?: () => void;
|
|
175
|
-
pinMode?: boolean;
|
|
176
|
-
onTogglePinMode?: () => void;
|
|
177
173
|
textBoxMode?: boolean;
|
|
178
174
|
onToggleTextBoxMode?: () => void;
|
|
179
175
|
shapeType?: SlideShapeType | null;
|
|
@@ -241,8 +237,6 @@ export default function EditorToolbar({
|
|
|
241
237
|
onToggleTweaks,
|
|
242
238
|
drawMode,
|
|
243
239
|
onToggleDrawMode,
|
|
244
|
-
pinMode,
|
|
245
|
-
onTogglePinMode,
|
|
246
240
|
textBoxMode,
|
|
247
241
|
onToggleTextBoxMode,
|
|
248
242
|
shapeType,
|
|
@@ -269,7 +263,6 @@ export default function EditorToolbar({
|
|
|
269
263
|
onPreviousSlide,
|
|
270
264
|
onNextSlide,
|
|
271
265
|
canEdit = true,
|
|
272
|
-
canComment = canEdit,
|
|
273
266
|
}: EditorToolbarProps) {
|
|
274
267
|
const t = useT();
|
|
275
268
|
// The top bar is the app's own in a widget. It drops only what the host owns
|
|
@@ -359,13 +352,12 @@ export default function EditorToolbar({
|
|
|
359
352
|
|
|
360
353
|
const contextToolbarVisible = canEdit && Boolean(currentSlide);
|
|
361
354
|
const showSlideTools =
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
(canComment && Boolean(onTogglePinMode));
|
|
355
|
+
canEdit &&
|
|
356
|
+
Boolean(
|
|
357
|
+
(currentSlide && onToggleAnimations) ||
|
|
358
|
+
onToggleTweaks ||
|
|
359
|
+
onToggleDrawMode,
|
|
360
|
+
);
|
|
369
361
|
const showCommentsItem = !widgetEmbed && Boolean(onToggleComments);
|
|
370
362
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
371
363
|
const backupInputRef = useRef<HTMLInputElement>(null);
|
|
@@ -646,17 +638,6 @@ export default function EditorToolbar({
|
|
|
646
638
|
});
|
|
647
639
|
}
|
|
648
640
|
}
|
|
649
|
-
if (canComment && onTogglePinMode) {
|
|
650
|
-
commands.push({
|
|
651
|
-
id: "pin-comments",
|
|
652
|
-
group: "slideTools",
|
|
653
|
-
label: t("editorToolbar.pinComments"),
|
|
654
|
-
keywords: ["comment", "pin"],
|
|
655
|
-
icon: IconPin,
|
|
656
|
-
active: pinMode,
|
|
657
|
-
run: onTogglePinMode,
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
641
|
|
|
661
642
|
if (canEdit && currentSlide && onChangeSlideTransition) {
|
|
662
643
|
commands.push(
|
|
@@ -767,7 +748,6 @@ export default function EditorToolbar({
|
|
|
767
748
|
addSlideGenerating,
|
|
768
749
|
animationsOpen,
|
|
769
750
|
layersOpen,
|
|
770
|
-
canComment,
|
|
771
751
|
canEdit,
|
|
772
752
|
commentsOpen,
|
|
773
753
|
currentSlide,
|
|
@@ -789,10 +769,8 @@ export default function EditorToolbar({
|
|
|
789
769
|
onToggleLayers,
|
|
790
770
|
onToggleComments,
|
|
791
771
|
onToggleDrawMode,
|
|
792
|
-
onTogglePinMode,
|
|
793
772
|
onToggleTextBoxMode,
|
|
794
773
|
onToggleTweaks,
|
|
795
|
-
pinMode,
|
|
796
774
|
setTheme,
|
|
797
775
|
shapeType,
|
|
798
776
|
t,
|
|
@@ -1057,20 +1035,6 @@ export default function EditorToolbar({
|
|
|
1057
1035
|
{t("editorToolbar.drawOnSlide")}
|
|
1058
1036
|
</DropdownMenuItem>
|
|
1059
1037
|
)}
|
|
1060
|
-
{canComment && onTogglePinMode && (
|
|
1061
|
-
<DropdownMenuItem
|
|
1062
|
-
onSelect={onTogglePinMode}
|
|
1063
|
-
data-toolbar-pin-button
|
|
1064
|
-
className={
|
|
1065
|
-
pinMode
|
|
1066
|
-
? "bg-accent text-accent-foreground"
|
|
1067
|
-
: undefined
|
|
1068
|
-
}
|
|
1069
|
-
>
|
|
1070
|
-
<IconPin className="size-4" />
|
|
1071
|
-
{t("editorToolbar.pinComments")}
|
|
1072
|
-
</DropdownMenuItem>
|
|
1073
|
-
)}
|
|
1074
1038
|
</DropdownMenuGroup>
|
|
1075
1039
|
</>
|
|
1076
1040
|
)}
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
IconMinus,
|
|
14
14
|
IconOval,
|
|
15
15
|
IconPhotoVideo,
|
|
16
|
-
IconPin,
|
|
17
16
|
IconPointer,
|
|
18
17
|
IconResize,
|
|
19
18
|
IconRobot,
|
|
@@ -55,7 +54,7 @@ export type FloatingToolbarInsertTool =
|
|
|
55
54
|
| "shape"
|
|
56
55
|
| "media";
|
|
57
56
|
export type FloatingToolbarTransition = "none" | AnimationType;
|
|
58
|
-
type FloatingToolbarCommentAction = "comments" | "annotate"
|
|
57
|
+
type FloatingToolbarCommentAction = "comments" | "annotate";
|
|
59
58
|
export type FloatingToolbarAgentAction =
|
|
60
59
|
| "inspiration"
|
|
61
60
|
| "tighten-tone"
|
|
@@ -172,7 +171,6 @@ const COMMENT_ITEMS: MenuItem<FloatingToolbarCommentAction>[] = [
|
|
|
172
171
|
labelKey: "floatingToolbar.annotate",
|
|
173
172
|
icon: IconUserEdit,
|
|
174
173
|
},
|
|
175
|
-
{ value: "pin", labelKey: "floatingToolbar.pinComment", icon: IconPin },
|
|
176
174
|
];
|
|
177
175
|
|
|
178
176
|
const ALL_TRANSITIONS = TRANSITION_ITEMS.map((item) => item.value);
|
|
@@ -348,7 +346,6 @@ export interface FloatingToolbarProps {
|
|
|
348
346
|
onOpenTransitions?: () => void;
|
|
349
347
|
onSelectTransition?: (transition: FloatingToolbarTransition) => void;
|
|
350
348
|
/** True while the comments panel is open. */
|
|
351
|
-
commentsOpen?: boolean;
|
|
352
349
|
/** The armed comment tool, if any. */
|
|
353
350
|
commentToolValue?: FloatingToolbarCommentAction | null;
|
|
354
351
|
/** Rows the viewer lacks the permission for. */
|
|
@@ -370,7 +367,6 @@ export const FloatingToolbar = memo(function FloatingToolbar({
|
|
|
370
367
|
transitionsDisabledReason = null,
|
|
371
368
|
onOpenTransitions,
|
|
372
369
|
onSelectTransition,
|
|
373
|
-
commentsOpen = false,
|
|
374
370
|
commentToolValue = null,
|
|
375
371
|
disabledCommentActions,
|
|
376
372
|
onOpenComments,
|
|
@@ -430,8 +426,8 @@ export const FloatingToolbar = memo(function FloatingToolbar({
|
|
|
430
426
|
tooltip={t("floatingToolbar.comment")}
|
|
431
427
|
menuLabel={t("floatingToolbar.commentMenu")}
|
|
432
428
|
items={COMMENT_ITEMS}
|
|
433
|
-
active={
|
|
434
|
-
value={commentToolValue
|
|
429
|
+
active={commentToolValue !== null}
|
|
430
|
+
value={commentToolValue}
|
|
435
431
|
disabledValues={disabledCommentActions}
|
|
436
432
|
onActivate={onOpenComments}
|
|
437
433
|
onSelect={onCommentAction}
|
|
@@ -1295,11 +1295,9 @@ interface SlideEditorProps {
|
|
|
1295
1295
|
/** Close the document layers panel. */
|
|
1296
1296
|
onCloseLayers?: () => void;
|
|
1297
1297
|
/** Whether the comments panel is open. */
|
|
1298
|
-
commentsOpen?: boolean;
|
|
1299
1298
|
/** Toggles the comments panel. */
|
|
1300
1299
|
onToggleComments?: () => void;
|
|
1301
1300
|
/** Toggles the pin-comment tool. */
|
|
1302
|
-
onTogglePinMode?: () => void;
|
|
1303
1301
|
/** Toggles the draw-on-slide annotation overlay. */
|
|
1304
1302
|
onToggleDrawMode?: () => void;
|
|
1305
1303
|
/** Toggle the transitions panel without a target. */
|
|
@@ -1985,9 +1983,7 @@ export default function SlideEditor({
|
|
|
1985
1983
|
onCloseLayers,
|
|
1986
1984
|
onOpenAnimations,
|
|
1987
1985
|
onToggleAnimations,
|
|
1988
|
-
commentsOpen,
|
|
1989
1986
|
onToggleComments,
|
|
1990
|
-
onTogglePinMode,
|
|
1991
1987
|
onToggleDrawMode,
|
|
1992
1988
|
onSelectedAnimationTargetsChange,
|
|
1993
1989
|
slideId,
|
|
@@ -3426,20 +3422,16 @@ export default function SlideEditor({
|
|
|
3426
3422
|
);
|
|
3427
3423
|
|
|
3428
3424
|
const disabledCommentActions = useMemo(
|
|
3429
|
-
() => [
|
|
3430
|
-
|
|
3431
|
-
...(readOnly ? (["annotate"] as const) : []),
|
|
3432
|
-
],
|
|
3433
|
-
[canComment, readOnly],
|
|
3425
|
+
() => (readOnly ? (["annotate"] as const) : []),
|
|
3426
|
+
[readOnly],
|
|
3434
3427
|
);
|
|
3435
3428
|
|
|
3436
3429
|
const runCommentAction = useCallback(
|
|
3437
|
-
(action: "comments" | "annotate"
|
|
3430
|
+
(action: "comments" | "annotate") => {
|
|
3438
3431
|
if (action === "comments") onToggleComments?.();
|
|
3439
|
-
else if (action === "pin") onTogglePinMode?.();
|
|
3440
3432
|
else onToggleDrawMode?.();
|
|
3441
3433
|
},
|
|
3442
|
-
[onToggleComments,
|
|
3434
|
+
[onToggleComments, onToggleDrawMode],
|
|
3443
3435
|
);
|
|
3444
3436
|
|
|
3445
3437
|
const runAgentAction = useCallback(
|
|
@@ -11344,9 +11336,8 @@ export default function SlideEditor({
|
|
|
11344
11336
|
transitionsDisabledReason={transitionsDisabledReason}
|
|
11345
11337
|
onOpenTransitions={openTransitionsPanel}
|
|
11346
11338
|
onSelectTransition={applyTransitionQuickPick}
|
|
11347
|
-
commentsOpen={Boolean(commentsOpen)}
|
|
11348
11339
|
commentToolValue={
|
|
11349
|
-
pinMode ? "
|
|
11340
|
+
pinMode ? "comments" : drawMode ? "annotate" : null
|
|
11350
11341
|
}
|
|
11351
11342
|
disabledCommentActions={disabledCommentActions}
|
|
11352
11343
|
onOpenComments={onToggleComments}
|
|
@@ -275,7 +275,6 @@ const messages = {
|
|
|
275
275
|
commentMenu: "Comment options",
|
|
276
276
|
comments: "Comments",
|
|
277
277
|
annotate: "Annotate",
|
|
278
|
-
pinComment: "Pin Comment",
|
|
279
278
|
agent: "Agent",
|
|
280
279
|
agentMenu: "Agent options",
|
|
281
280
|
agentUnavailable: "Couldn't reach the agent chat. Try again.",
|
|
@@ -376,7 +375,6 @@ const messages = {
|
|
|
376
375
|
shapeLine: "Line",
|
|
377
376
|
shapeStar: "Star",
|
|
378
377
|
shapePolygon: "Polygon",
|
|
379
|
-
pinComments: "Pin comments",
|
|
380
378
|
undo: "Undo",
|
|
381
379
|
undoWithShortcut: "Undo ({{shortcut}})",
|
|
382
380
|
redo: "Redo",
|