@beyondwork/docx-react-component 1.0.105 → 1.0.108
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/package.json +19 -5
- package/src/api/geometry-overlay-rects.ts +5 -0
- package/src/api/package-version.ts +1 -1
- package/src/api/page-anchor-id.ts +5 -0
- package/src/api/public-types.ts +16 -9
- package/src/api/table-node-specs.ts +6 -0
- package/src/api/v3/_create.ts +10 -2
- package/src/api/v3/_page-anchor-id.ts +52 -0
- package/src/api/v3/_runtime-handle.ts +92 -1
- package/src/api/v3/ai/_audit-reference.ts +28 -0
- package/src/api/v3/ai/_audit-time.ts +5 -0
- package/src/api/v3/ai/_pe2-evidence.ts +310 -6
- package/src/api/v3/ai/attach.ts +29 -4
- package/src/api/v3/ai/bundle.ts +6 -2
- package/src/api/v3/ai/inspect.ts +6 -2
- package/src/api/v3/ai/replacement.ts +112 -18
- package/src/api/v3/ai/resolve.ts +2 -2
- package/src/api/v3/ai/review.ts +177 -3
- package/src/api/v3/index.ts +8 -0
- package/src/api/v3/runtime/collab.ts +462 -0
- package/src/api/v3/runtime/document.ts +503 -20
- package/src/api/v3/runtime/geometry.ts +97 -0
- package/src/api/v3/runtime/layout.ts +744 -0
- package/src/api/v3/runtime/perf-probe.ts +14 -0
- package/src/api/v3/runtime/viewport.ts +9 -8
- package/src/api/v3/ui/_types.ts +202 -55
- package/src/api/v3/ui/chrome-preset-model.ts +5 -5
- package/src/api/v3/ui/debug.ts +115 -2
- package/src/api/v3/ui/index.ts +17 -0
- package/src/api/v3/ui/overlays.ts +0 -8
- package/src/api/v3/ui/surface.ts +56 -0
- package/src/api/v3/ui/viewport.ts +119 -9
- package/src/core/commands/image-commands.ts +1 -0
- package/src/core/commands/index.ts +6 -0
- package/src/core/schema/text-schema.ts +43 -5
- package/src/core/selection/mapping.ts +8 -1
- package/src/core/selection/review-anchors.ts +5 -1
- package/src/core/state/text-transaction.ts +8 -2
- package/src/io/export/serialize-revisions.ts +149 -1
- package/src/io/normalize/normalize-text.ts +6 -0
- package/src/io/ooxml/parse-bookmark-references.ts +55 -0
- package/src/io/ooxml/parse-fields.ts +24 -2
- package/src/io/ooxml/parse-headers-footers.ts +38 -5
- package/src/io/ooxml/parse-main-document.ts +153 -9
- package/src/io/ooxml/parse-numbering.ts +20 -0
- package/src/io/ooxml/parse-revisions.ts +19 -8
- package/src/io/opc/package-reader.ts +98 -8
- package/src/model/anchor.ts +4 -3
- package/src/model/canonical-document.ts +220 -2
- package/src/model/canonical-hash.ts +221 -0
- package/src/model/canonical-layout-inputs.ts +245 -6
- package/src/model/layout/index.ts +1 -0
- package/src/model/layout/page-graph-types.ts +147 -1
- package/src/model/review/revision-types.ts +14 -3
- package/src/preservation/store.ts +20 -4
- package/src/review/README.md +1 -1
- package/src/review/store/revision-actions.ts +14 -2
- package/src/runtime/collab/event-types.ts +67 -1
- package/src/runtime/collab/runtime-collab-sync.ts +177 -5
- package/src/runtime/diagnostics/layout-guard-warning.ts +18 -0
- package/src/runtime/document-heading-outline.ts +147 -0
- package/src/runtime/document-navigation.ts +8 -243
- package/src/runtime/document-runtime.ts +279 -115
- package/src/runtime/edit-dispatch/dispatch-text-command.ts +11 -0
- package/src/runtime/formatting/layout-inputs.ts +38 -5
- package/src/runtime/formatting/numbering/geometry.ts +28 -2
- package/src/runtime/geometry/adjacent-geometry-intake.ts +835 -0
- package/src/runtime/geometry/caret-geometry.ts +5 -6
- package/src/runtime/geometry/geometry-facet.ts +60 -10
- package/src/runtime/geometry/geometry-index.ts +661 -16
- package/src/runtime/geometry/geometry-types.ts +59 -0
- package/src/runtime/geometry/hit-test.ts +11 -1
- package/src/runtime/geometry/overlay-rects.ts +5 -3
- package/src/runtime/geometry/project-anchors.ts +1 -1
- package/src/runtime/geometry/word-layout-v2-line-intake.ts +323 -0
- package/src/runtime/layout/index.ts +6 -0
- package/src/runtime/layout/layout-engine-instance.ts +6 -1
- package/src/runtime/layout/layout-engine-version.ts +188 -16
- package/src/runtime/layout/layout-facet-types.ts +6 -0
- package/src/runtime/layout/page-graph.ts +23 -4
- package/src/runtime/layout/paginated-layout-engine.ts +149 -15
- package/src/runtime/layout/project-block-fragments.ts +351 -14
- package/src/runtime/layout/public-facet.ts +162 -24
- package/src/runtime/layout/table-row-continuation-contract.ts +107 -0
- package/src/runtime/layout/table-row-split.ts +92 -35
- package/src/runtime/prerender/cache-envelope.ts +2 -2
- package/src/runtime/prerender/cache-key.ts +5 -4
- package/src/runtime/prerender/customxml-cache.ts +0 -1
- package/src/runtime/render/render-kernel.ts +1 -1
- package/src/runtime/revision-runtime.ts +112 -10
- package/src/runtime/scopes/_scope-dependencies.ts +1 -0
- package/src/runtime/scopes/action-validation.ts +22 -2
- package/src/runtime/scopes/capabilities.ts +316 -0
- package/src/runtime/scopes/compile-scope-bundle.ts +14 -0
- package/src/runtime/scopes/compiler-service.ts +108 -4
- package/src/runtime/scopes/content-control-evidence.ts +79 -0
- package/src/runtime/scopes/create-issue.ts +5 -5
- package/src/runtime/scopes/evidence.ts +91 -0
- package/src/runtime/scopes/formatting/apply.ts +2 -0
- package/src/runtime/scopes/geometry-evidence.ts +130 -0
- package/src/runtime/scopes/index.ts +54 -0
- package/src/runtime/scopes/issue-lifecycle.ts +224 -0
- package/src/runtime/scopes/layout-evidence.ts +374 -0
- package/src/runtime/scopes/multi-paragraph-refusal.ts +37 -0
- package/src/runtime/scopes/preservation-boundary.ts +7 -1
- package/src/runtime/scopes/replacement/apply.ts +97 -34
- package/src/runtime/scopes/scope-kinds/paragraph.ts +108 -12
- package/src/runtime/scopes/semantic-scope-types.ts +242 -3
- package/src/runtime/scopes/visualization.ts +28 -0
- package/src/runtime/surface-projection.ts +44 -5
- package/src/runtime/telemetry/perf-probe.ts +216 -0
- package/src/runtime/virtualized-rendering.ts +36 -1
- package/src/runtime/workflow/ai-issue-lifecycle.ts +253 -0
- package/src/runtime/workflow/coordinator.ts +39 -11
- package/src/runtime/workflow/derived-scope-resolver.ts +63 -9
- package/src/runtime/workflow/index.ts +4 -0
- package/src/runtime/workflow/overlay-lane-types.ts +58 -0
- package/src/runtime/workflow/overlay-lanes.ts +386 -0
- package/src/runtime/workflow/overlay-store.ts +2 -2
- package/src/runtime/workflow/redline-posture-calibration.ts +257 -0
- package/src/runtime/workflow/word-field-matrix-calibration.ts +231 -0
- package/src/session/_sync-legacy.ts +17 -27
- package/src/session/import/loader.ts +6 -4
- package/src/session/import/source-package-evidence.ts +186 -2
- package/src/session/index.ts +5 -6
- package/src/session/session.ts +30 -56
- package/src/session/types.ts +8 -13
- package/src/shell/session-bootstrap.ts +155 -81
- package/src/ui/WordReviewEditor.tsx +520 -12
- package/src/ui/editor-shell-view.tsx +14 -4
- package/src/ui/editor-surface-controller.tsx +5 -3
- package/src/ui/headless/selection-tool-resolver.ts +1 -2
- package/src/ui/presence-overlay-lane.ts +130 -0
- package/src/ui/ui-controller-factory.ts +17 -0
- package/src/ui-tailwind/chrome/build-context-menu-entries.ts +5 -1
- package/src/ui-tailwind/chrome/editor-action-registry.ts +105 -5
- package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +7 -0
- package/src/ui-tailwind/chrome/layer-debug-contracts.ts +208 -0
- package/src/ui-tailwind/chrome/resolve-target-kind.ts +13 -0
- package/src/ui-tailwind/chrome/tw-alert-banner.tsx +11 -3
- package/src/ui-tailwind/chrome/tw-command-palette.tsx +36 -6
- package/src/ui-tailwind/chrome/tw-context-menu.tsx +6 -1
- package/src/ui-tailwind/chrome/tw-display-mode-selector.tsx +42 -109
- package/src/ui-tailwind/chrome/tw-inline-find-bar.tsx +26 -6
- package/src/ui-tailwind/chrome/tw-navigation-command-bar.tsx +328 -0
- package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +8 -4
- package/src/ui-tailwind/chrome/tw-runtime-repl-dialog.tsx +129 -1
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +19 -5
- package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +5 -1
- package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +28 -12
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +30 -3
- package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +116 -10
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +223 -94
- package/src/ui-tailwind/chrome-overlay/tw-presence-overlay-lane.tsx +157 -0
- package/src/ui-tailwind/chrome-overlay/tw-review-overlay-lane-markers.tsx +259 -0
- package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +5 -2
- package/src/ui-tailwind/chrome-overlay/tw-substrate-overlay-lanes.tsx +314 -0
- package/src/ui-tailwind/debug/README.md +4 -1
- package/src/ui-tailwind/debug/layer11-consumer-readiness.ts +272 -0
- package/src/ui-tailwind/debug/layer11-word-field-matrix-evidence.ts +160 -0
- package/src/ui-tailwind/editor-surface/perf-probe.ts +14 -215
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +42 -0
- package/src/ui-tailwind/editor-surface/pm-position-map.ts +38 -2
- package/src/ui-tailwind/editor-surface/pm-schema.ts +14 -4
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +34 -5
- package/src/ui-tailwind/editor-surface/runtime-decoration-plugin.ts +9 -19
- package/src/ui-tailwind/editor-surface/surface-build-keys.ts +2 -2
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +145 -0
- package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +16 -11
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +8 -10
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +3 -0
- package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +4 -2
- package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +60 -20
- package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +16 -11
- package/src/ui-tailwind/review/tw-health-panel.tsx +36 -17
- package/src/ui-tailwind/review/tw-review-rail.tsx +7 -4
- package/src/ui-tailwind/review-workspace/diagnostics-visibility.ts +44 -0
- package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +11 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +16 -1
- package/src/ui-tailwind/review-workspace/types.ts +26 -12
- package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +40 -11
- package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +2 -1
- package/src/ui-tailwind/review-workspace/use-page-markers.ts +15 -26
- package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +35 -18
- package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +41 -32
- package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +2 -1
- package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +2 -1
- package/src/ui-tailwind/status/tw-status-bar.tsx +6 -5
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +52 -80
- package/src/ui-tailwind/toolbar/tw-shell-header.tsx +12 -48
- package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +9 -4
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +328 -361
- package/src/ui-tailwind/tw-review-workspace.tsx +152 -286
|
@@ -8,7 +8,6 @@ import React, {
|
|
|
8
8
|
} from "react";
|
|
9
9
|
|
|
10
10
|
import * as Tooltip from "@radix-ui/react-tooltip";
|
|
11
|
-
import { ChevronRight } from "lucide-react";
|
|
12
11
|
|
|
13
12
|
import { sliceBlocksForPage } from "./editor-surface/page-slice-util.ts";
|
|
14
13
|
import {
|
|
@@ -19,7 +18,6 @@ import { TwPageBlockView } from "./editor-surface/tw-page-block-view.tsx";
|
|
|
19
18
|
import { computeLineMarkersIfEnabled } from "./page-chrome-model.ts";
|
|
20
19
|
import { shouldRenderSelectionToolKind } from "../ui/headless/scoped-chrome-policy";
|
|
21
20
|
import type { EditorCommandBag } from "../ui/editor-command-bag.ts";
|
|
22
|
-
import { preserveEditorSelectionMouseDown } from "../ui/headless/preserve-editor-selection";
|
|
23
21
|
import { TwAlertBanner } from "./chrome/tw-alert-banner";
|
|
24
22
|
import { TwPageRuler } from "./chrome/tw-page-ruler";
|
|
25
23
|
import { ChromePresetToolbar } from "./chrome/chrome-preset-toolbar";
|
|
@@ -35,13 +33,6 @@ import {
|
|
|
35
33
|
type TwReviewWorkspaceRailMode,
|
|
36
34
|
} from "./review-workspace/tw-review-workspace-rail.tsx";
|
|
37
35
|
import { TwStatusBar } from "./status/tw-status-bar";
|
|
38
|
-
import {
|
|
39
|
-
TwShellHeader,
|
|
40
|
-
type ShellHeaderMode,
|
|
41
|
-
type ShellHeaderModeOption,
|
|
42
|
-
} from "./toolbar/tw-shell-header";
|
|
43
|
-
import { TwContextBand } from "./chrome/tw-context-band";
|
|
44
|
-
import { TwRoleActionRegion } from "./toolbar/tw-role-action-region";
|
|
45
36
|
import { LocalSurfaceArbiterContext } from "./chrome/local-surface-arbiter";
|
|
46
37
|
import {
|
|
47
38
|
TwWorkspaceChromeHost,
|
|
@@ -62,14 +53,20 @@ import { useViewportDimensions } from "./review-workspace/use-viewport-dimension
|
|
|
62
53
|
import { useScopeCardState } from "./review-workspace/use-scope-card-state.ts";
|
|
63
54
|
import { usePageMarkers } from "./review-workspace/use-page-markers.ts";
|
|
64
55
|
import { useDiagnosticsSignal } from "./review-workspace/use-diagnostics-signal.ts";
|
|
56
|
+
import {
|
|
57
|
+
filterProductCompatibility,
|
|
58
|
+
filterProductWarnings,
|
|
59
|
+
} from "./review-workspace/diagnostics-visibility.ts";
|
|
65
60
|
import { useWorkspaceComposition } from "./review-workspace/use-workspace-composition.ts";
|
|
66
61
|
import { useWorkspaceArbiter } from "./review-workspace/use-workspace-arbiter.ts";
|
|
67
62
|
import { useLayoutFacetRenderSignal } from "./review-workspace/use-layout-facet-render-signal.ts";
|
|
68
63
|
import { useScrollRootCapture } from "./review-workspace/use-scroll-root-capture.ts";
|
|
69
64
|
import { usePmSurfaceCapture } from "./review-workspace/use-pm-surface-capture.ts";
|
|
70
65
|
import { TwReviewWorkspaceNavigator } from "./review-workspace/tw-review-workspace-navigator.tsx";
|
|
66
|
+
import { DEFAULT_CANVAS_BODY_WIDTH_PX } from "./review-workspace/page-shell-metrics.ts";
|
|
71
67
|
|
|
72
68
|
export {
|
|
69
|
+
DEFAULT_CANVAS_BODY_WIDTH_PX,
|
|
73
70
|
FRAME_PX_PER_TWIP_AT_96DPI,
|
|
74
71
|
MIN_BAND_HEIGHT_PX,
|
|
75
72
|
buildPageShellMetrics,
|
|
@@ -85,82 +82,23 @@ export type {
|
|
|
85
82
|
TwReviewWorkspaceProps,
|
|
86
83
|
} from "./review-workspace/types.ts";
|
|
87
84
|
|
|
88
|
-
import type {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// uses `ChromeCompositionInput.modeOverride` instead of changing runtime role.
|
|
94
|
-
const DEFAULT_WORKSPACE_SHELL_MODES: readonly ShellHeaderModeOption[] = [
|
|
95
|
-
{ id: "edit", label: "Edit" },
|
|
96
|
-
{ id: "review", label: "Review" },
|
|
97
|
-
{ id: "workflow", label: "Workflow" },
|
|
98
|
-
{ id: "more", label: "More" },
|
|
99
|
-
];
|
|
85
|
+
import type {
|
|
86
|
+
EditorRole,
|
|
87
|
+
EditorStoryTarget,
|
|
88
|
+
WorkflowScopeSnapshot,
|
|
89
|
+
} from "../api/public-types.ts";
|
|
100
90
|
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
case "workflow":
|
|
108
|
-
return "workflow";
|
|
91
|
+
function resolveRoleChromePreset(
|
|
92
|
+
basePreset: ReturnType<typeof resolveChromePreset>,
|
|
93
|
+
role: EditorRole,
|
|
94
|
+
): ReturnType<typeof resolveChromePreset> {
|
|
95
|
+
if (role === "workflow") {
|
|
96
|
+
return "workflow";
|
|
109
97
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
function shellModeToEditorRole(mode: ShellHeaderMode): EditorRole | null {
|
|
113
|
-
switch (mode) {
|
|
114
|
-
case "edit":
|
|
115
|
-
return "editor";
|
|
116
|
-
case "review":
|
|
117
|
-
return "review";
|
|
118
|
-
case "workflow":
|
|
119
|
-
return "workflow";
|
|
120
|
-
case "more":
|
|
121
|
-
return null;
|
|
98
|
+
if (role === "review") {
|
|
99
|
+
return "review";
|
|
122
100
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
function TwMoreContextBandContent(props: {
|
|
126
|
-
onOpenDiagnostics: () => void;
|
|
127
|
-
onOpenCompatibility: () => void;
|
|
128
|
-
onOpenOutline: () => void;
|
|
129
|
-
onOpenSearch?: () => void;
|
|
130
|
-
}): React.JSX.Element {
|
|
131
|
-
return (
|
|
132
|
-
<div
|
|
133
|
-
className="flex min-w-0 items-center gap-1"
|
|
134
|
-
data-testid="more-context-band-content"
|
|
135
|
-
>
|
|
136
|
-
<ContextBandButton label="Diagnostics" onClick={props.onOpenDiagnostics} />
|
|
137
|
-
<ContextBandButton label="Compatibility" onClick={props.onOpenCompatibility} />
|
|
138
|
-
<ContextBandButton label="Outline" onClick={props.onOpenOutline} />
|
|
139
|
-
<ContextBandButton
|
|
140
|
-
label="Search"
|
|
141
|
-
onClick={props.onOpenSearch}
|
|
142
|
-
disabled={!props.onOpenSearch}
|
|
143
|
-
/>
|
|
144
|
-
</div>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function ContextBandButton(props: {
|
|
149
|
-
label: string;
|
|
150
|
-
onClick?: () => void;
|
|
151
|
-
disabled?: boolean;
|
|
152
|
-
}): React.JSX.Element {
|
|
153
|
-
return (
|
|
154
|
-
<button
|
|
155
|
-
type="button"
|
|
156
|
-
disabled={props.disabled}
|
|
157
|
-
onMouseDown={preserveEditorSelectionMouseDown}
|
|
158
|
-
onClick={props.onClick}
|
|
159
|
-
className="inline-flex h-7 items-center rounded-[var(--radius-md)] px-2.5 text-xs font-medium text-secondary transition-colors hover:bg-hover focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)] disabled:cursor-not-allowed disabled:opacity-40"
|
|
160
|
-
>
|
|
161
|
-
{props.label}
|
|
162
|
-
</button>
|
|
163
|
-
);
|
|
101
|
+
return basePreset;
|
|
164
102
|
}
|
|
165
103
|
|
|
166
104
|
export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
@@ -172,8 +110,6 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
172
110
|
const selectionToolbarRootRef = useRef<HTMLDivElement>(null);
|
|
173
111
|
const workspaceChromeControllerRef =
|
|
174
112
|
useRef<TwWorkspaceChromeHostController | null>(null);
|
|
175
|
-
const [shellModeOverride, setShellModeOverride] =
|
|
176
|
-
useState<ShellHeaderMode | null>(null);
|
|
177
113
|
// P8.11 — body slot wrapping `{props.document}` (the PM surface) + scroll
|
|
178
114
|
// root ref. The chrome layer's `TwPageStackChromeLayer` needs both to
|
|
179
115
|
// measure per-page rects and to reparent PM's DOM node across band
|
|
@@ -215,7 +151,6 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
215
151
|
handleScopeCardRejectSuggestionGroup,
|
|
216
152
|
handleScopeCardAskAgent,
|
|
217
153
|
} = useScopeCardState({
|
|
218
|
-
layoutFacet: props.layoutFacet,
|
|
219
154
|
workflowFacet: props.workflowFacet,
|
|
220
155
|
onScopeModeChangeRequested: props.onScopeModeChangeRequested,
|
|
221
156
|
onScopeIssueActionRequested: props.onScopeIssueActionRequested,
|
|
@@ -229,17 +164,19 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
229
164
|
// `pageShellMetrics` has been computed (P2.c).
|
|
230
165
|
const numericZoomScale = typeof zoomLevel === "number" ? zoomLevel / 100 : 1;
|
|
231
166
|
const chromePreset = resolveChromePreset(props.chromePreset, props.reviewMode);
|
|
232
|
-
const
|
|
167
|
+
const productChromePreset = resolveRoleChromePreset(chromePreset, viewState.editorRole);
|
|
168
|
+
const chromeOptions = resolveChromePresetOptions(productChromePreset, props.chromeOptions, viewState.editorRole);
|
|
233
169
|
const preserveOnlyCount = caps?.preserveOnlyCount ??
|
|
234
170
|
snapshot.compatibility.featureEntries.filter(
|
|
235
171
|
(entry) => entry.featureClass === "preserve-only",
|
|
236
172
|
).length;
|
|
173
|
+
const showDebugDiagnostics = props.showDebugDiagnostics === true;
|
|
237
174
|
const blockedReasons =
|
|
238
175
|
props.interactionGuardSnapshot?.blockedReasons ??
|
|
239
176
|
props.workflowScopeSnapshot?.blockedReasons ??
|
|
240
177
|
[];
|
|
241
178
|
const chromeVisibility = resolveChromeVisibilityForPreset({
|
|
242
|
-
chromePreset,
|
|
179
|
+
chromePreset: productChromePreset,
|
|
243
180
|
chromeOptions,
|
|
244
181
|
chromeVisibility: props.chromeVisibility,
|
|
245
182
|
});
|
|
@@ -265,7 +202,11 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
265
202
|
const element = event.target as HTMLElement | null;
|
|
266
203
|
const revisionId =
|
|
267
204
|
element?.closest?.("[data-revision-id]")?.getAttribute("data-revision-id") ?? null;
|
|
268
|
-
if (
|
|
205
|
+
if (
|
|
206
|
+
viewState.editorRole === "editor" ||
|
|
207
|
+
!revisionId ||
|
|
208
|
+
(revisionId === lastHoveredRevisionIdRef.current && reviewRailOpen)
|
|
209
|
+
) {
|
|
269
210
|
return;
|
|
270
211
|
}
|
|
271
212
|
lastHoveredRevisionIdRef.current = revisionId;
|
|
@@ -274,7 +215,13 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
274
215
|
props.onActiveRailTabChange?.("changes");
|
|
275
216
|
}
|
|
276
217
|
},
|
|
277
|
-
[
|
|
218
|
+
[
|
|
219
|
+
props.onActiveRailTabChange,
|
|
220
|
+
reviewRailAvailable,
|
|
221
|
+
reviewRailOpen,
|
|
222
|
+
setReviewRailOpen,
|
|
223
|
+
viewState.editorRole,
|
|
224
|
+
],
|
|
278
225
|
);
|
|
279
226
|
// Incremented on zoom_changed / render_frame_ready so the placement
|
|
280
227
|
// useMemo below re-executes when the render kernel emits new rects.
|
|
@@ -303,11 +250,18 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
303
250
|
}, [renderFrameRevision, uiApi, shellChannels]);
|
|
304
251
|
const scopeRailSegments = useMemo(
|
|
305
252
|
() =>
|
|
253
|
+
// Mounted path: current scope rail truth flows through Layer 10
|
|
254
|
+
// `ui.scope.rail()`. The workflow facet remains only as the
|
|
255
|
+
// compatibility fallback when no UiApiProvider is mounted.
|
|
306
256
|
uiApi?.scope.rail().segments ??
|
|
307
257
|
props.workflowFacet?.getAllRailSegments() ??
|
|
308
258
|
[],
|
|
309
259
|
[uiApi, props.workflowFacet, renderFrameRevision],
|
|
310
260
|
);
|
|
261
|
+
const mountedSemanticScopeCount = useMemo(
|
|
262
|
+
() => uiApi?.scope.list().length,
|
|
263
|
+
[uiApi, renderFrameRevision],
|
|
264
|
+
);
|
|
311
265
|
const headings = props.documentNavigation?.headings ?? [];
|
|
312
266
|
const headerVariant = snapshot.pageLayout?.headerVariants[0]?.variant ?? "default";
|
|
313
267
|
const footerVariant = snapshot.pageLayout?.footerVariants[0]?.variant ?? "default";
|
|
@@ -345,6 +299,30 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
345
299
|
viewportHeight,
|
|
346
300
|
isPageWorkspace,
|
|
347
301
|
});
|
|
302
|
+
const canvasDocumentColumnStyle = useMemo<CSSProperties | undefined>(() => {
|
|
303
|
+
if (isPageWorkspace) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
const contentWidthPx =
|
|
307
|
+
pageShellMetrics.contentWidthPx || DEFAULT_CANVAS_BODY_WIDTH_PX;
|
|
308
|
+
return { maxWidth: `${contentWidthPx}px` };
|
|
309
|
+
}, [isPageWorkspace, pageShellMetrics.contentWidthPx]);
|
|
310
|
+
const documentColumnStyle = useMemo<CSSProperties | undefined>(() => {
|
|
311
|
+
if (isPageWorkspace) {
|
|
312
|
+
return pageChromeModel.documentGridStyle;
|
|
313
|
+
}
|
|
314
|
+
if (!canvasDocumentColumnStyle && !pageChromeModel.documentGridStyle) {
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
...(canvasDocumentColumnStyle ?? {}),
|
|
319
|
+
...(pageChromeModel.documentGridStyle ?? {}),
|
|
320
|
+
};
|
|
321
|
+
}, [
|
|
322
|
+
canvasDocumentColumnStyle,
|
|
323
|
+
isPageWorkspace,
|
|
324
|
+
pageChromeModel.documentGridStyle,
|
|
325
|
+
]);
|
|
348
326
|
// DS-C1 — publish the current selection anchor so
|
|
349
327
|
// `ui.overlays.getAnchor({ kind: "selection" })` resolves to a real
|
|
350
328
|
// rect on the mounted path (designsystem.md §8.8.1 "Selection toolbar"
|
|
@@ -391,7 +369,6 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
391
369
|
snapshot.activeStory.kind !== "main" ||
|
|
392
370
|
effectiveSelectionMode !== "edit";
|
|
393
371
|
const hasEditableSelectionTarget =
|
|
394
|
-
viewState.isFocused &&
|
|
395
372
|
viewState.selection.activeRange.kind === "range" &&
|
|
396
373
|
viewState.activeObjectFrame === null;
|
|
397
374
|
const hasSidebarPanelAccess = Boolean(
|
|
@@ -402,7 +379,7 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
402
379
|
viewportWidth,
|
|
403
380
|
reviewRailAvailable,
|
|
404
381
|
reviewRailOpen,
|
|
405
|
-
chromePreset,
|
|
382
|
+
chromePreset: productChromePreset,
|
|
406
383
|
caps,
|
|
407
384
|
interactionGuardSnapshot: props.interactionGuardSnapshot,
|
|
408
385
|
workflowScopeSnapshot: props.workflowScopeSnapshot,
|
|
@@ -412,11 +389,19 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
412
389
|
effectiveSelectionMode,
|
|
413
390
|
activeStoryKind: snapshot.activeStory.kind,
|
|
414
391
|
});
|
|
392
|
+
const suppressFloatingToolDuringEditorInput =
|
|
393
|
+
viewState.editorRole === "editor" &&
|
|
394
|
+
viewState.selection.isCollapsed;
|
|
395
|
+
const shouldRenderFloatingSelectionTool =
|
|
396
|
+
chromeVisibility.selectionOverlay &&
|
|
397
|
+
gatedSelectionTool &&
|
|
398
|
+
!suppressFloatingToolDuringEditorInput &&
|
|
399
|
+
shouldRenderSelectionToolKind(scopedChromePolicy, gatedSelectionTool.kind);
|
|
415
400
|
|
|
416
401
|
// L7 Phase 2 Task 2.2.4a — viewport-scroll wiring. Page marker
|
|
417
402
|
// collection, selection-backed visible block/page ranges, and the
|
|
418
403
|
// facet push all live in the hook.
|
|
419
|
-
const {
|
|
404
|
+
const { visiblePageIndexRange } = usePageMarkers({
|
|
420
405
|
pageStackScrollRoot,
|
|
421
406
|
snapshot,
|
|
422
407
|
layoutFacet: props.layoutFacet,
|
|
@@ -510,56 +495,14 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
510
495
|
[],
|
|
511
496
|
);
|
|
512
497
|
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
//
|
|
516
|
-
// the mode tabs actually change the active role instead of being
|
|
517
|
-
// decorative. The "more" tab is shell-owned diagnostics/search posture:
|
|
518
|
-
// it drives composition mode via `modeOverride` and does not mutate the
|
|
519
|
-
// runtime editor role.
|
|
520
|
-
// Host-supplied shells continue to win (back-compat).
|
|
521
|
-
const defaultShellModes: readonly ShellHeaderModeOption[] =
|
|
522
|
-
DEFAULT_WORKSPACE_SHELL_MODES;
|
|
523
|
-
const defaultShellActiveMode: ShellHeaderMode = editorRoleToShellMode(
|
|
524
|
-
viewState.editorRole,
|
|
525
|
-
);
|
|
526
|
-
const activeShellMode: ShellHeaderMode =
|
|
527
|
-
shellModeOverride === "more" ? "more" : defaultShellActiveMode;
|
|
528
|
-
// coord-11 §21 — host-supplied shellHeader wins; otherwise the default
|
|
529
|
-
// TwShellHeader mounts only when `chromeVisibility.shellHeader === true`
|
|
530
|
-
// (default for every preset except `selection`). The `selection` preset
|
|
531
|
-
// is intended for minimal embeds (incl. visual-fidelity `chrome=none`)
|
|
532
|
-
// and must not paint a workspace mode-tab header.
|
|
498
|
+
// Host-supplied shells continue to win, but the product no longer mounts
|
|
499
|
+
// a default top mode-strip. Edit / Review / Workflow switching lives in
|
|
500
|
+
// the main toolbar so the document opens with one chrome row.
|
|
533
501
|
const renderedShell =
|
|
534
|
-
props.shellHeader !== undefined
|
|
502
|
+
chromeVisibility.shellHeader && props.shellHeader !== undefined
|
|
535
503
|
? props.shellHeader
|
|
536
|
-
:
|
|
537
|
-
? (
|
|
538
|
-
<TwShellHeader
|
|
539
|
-
modes={defaultShellModes}
|
|
540
|
-
activeMode={activeShellMode}
|
|
541
|
-
onModeChange={(mode) => {
|
|
542
|
-
if (mode === "more") {
|
|
543
|
-
setShellModeOverride("more");
|
|
544
|
-
setReviewRailOpen(true);
|
|
545
|
-
props.onActiveRailTabChange?.("health");
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
setShellModeOverride(null);
|
|
549
|
-
const nextRole = shellModeToEditorRole(mode);
|
|
550
|
-
if (nextRole !== null && nextRole !== viewState.editorRole) {
|
|
551
|
-
props.onEditorRoleChange?.(nextRole);
|
|
552
|
-
}
|
|
553
|
-
}}
|
|
554
|
-
/>
|
|
555
|
-
)
|
|
556
|
-
: null;
|
|
504
|
+
: null;
|
|
557
505
|
|
|
558
|
-
// Audit §2.5 — context band mounts as a composition-level sibling below
|
|
559
|
-
// the shell header only when the active mode has meaningful mode-owned
|
|
560
|
-
// content. Plain editor mode keeps its authoring controls in the toolbar
|
|
561
|
-
// and intentionally does not render an empty "Edit" ribbon.
|
|
562
|
-
//
|
|
563
506
|
// `resolveChromeComposition` is pure but each call allocates new Sets +
|
|
564
507
|
// arrays. `TwReviewWorkspace` re-renders on every PM transaction (the
|
|
565
508
|
// inverted-truth architecture calls `view.updateState()` wholesale) so
|
|
@@ -573,12 +516,36 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
573
516
|
snapshot,
|
|
574
517
|
caps,
|
|
575
518
|
preserveOnlyCount,
|
|
576
|
-
blockedReasonsCount: blockedReasons.length,
|
|
519
|
+
blockedReasonsCount: showDebugDiagnostics ? blockedReasons.length : 0,
|
|
520
|
+
includePreservationDiagnostics: showDebugDiagnostics,
|
|
577
521
|
});
|
|
578
522
|
const healthIssueCount = diagnosticsSignal.count;
|
|
523
|
+
const diagnosticsCompatibility = useMemo(
|
|
524
|
+
() =>
|
|
525
|
+
showDebugDiagnostics
|
|
526
|
+
? snapshot.compatibility
|
|
527
|
+
: filterProductCompatibility(snapshot.compatibility),
|
|
528
|
+
[showDebugDiagnostics, snapshot.compatibility],
|
|
529
|
+
);
|
|
530
|
+
const diagnosticsWarnings = useMemo(
|
|
531
|
+
() =>
|
|
532
|
+
showDebugDiagnostics
|
|
533
|
+
? snapshot.warnings
|
|
534
|
+
: filterProductWarnings(snapshot.warnings),
|
|
535
|
+
[showDebugDiagnostics, snapshot.warnings],
|
|
536
|
+
);
|
|
537
|
+
const diagnosticsBlockedReasons = showDebugDiagnostics ? blockedReasons : [];
|
|
538
|
+
const chromeCapabilities = useMemo(() => {
|
|
539
|
+
if (!caps) return caps;
|
|
540
|
+
return {
|
|
541
|
+
...caps,
|
|
542
|
+
healthIssueCount,
|
|
543
|
+
preserveOnlyCount: showDebugDiagnostics ? caps.preserveOnlyCount : 0,
|
|
544
|
+
};
|
|
545
|
+
}, [caps, healthIssueCount, showDebugDiagnostics]);
|
|
579
546
|
|
|
580
547
|
const composition = useWorkspaceComposition({
|
|
581
|
-
chromePreset,
|
|
548
|
+
chromePreset: productChromePreset,
|
|
582
549
|
chromeOptions: props.chromeOptions,
|
|
583
550
|
chromeVisibility: props.chromeVisibility,
|
|
584
551
|
reviewMode: props.reviewMode,
|
|
@@ -590,137 +557,18 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
590
557
|
density: props.density,
|
|
591
558
|
containerWidth: viewportWidth,
|
|
592
559
|
diagnosticsSignal,
|
|
593
|
-
modeOverride: shellModeOverride === "more" ? "more" : undefined,
|
|
594
560
|
});
|
|
595
561
|
const showHealthRailTab = composition.rail.visibleTabs.has("health");
|
|
596
|
-
const showContextBand =
|
|
597
|
-
chromeVisibility.toolbar &&
|
|
598
|
-
(composition.mode === "more" || viewState.editorRole !== "editor");
|
|
599
|
-
|
|
600
562
|
const arbiter = useWorkspaceArbiter();
|
|
601
563
|
|
|
602
564
|
return (
|
|
603
565
|
<LocalSurfaceArbiterContext.Provider value={arbiter}>
|
|
604
566
|
<Tooltip.Provider delayDuration={400}>
|
|
605
|
-
<div
|
|
567
|
+
<div
|
|
568
|
+
className="flex h-full min-h-0 flex-col overflow-hidden bg-canvas text-primary"
|
|
569
|
+
data-testid="tw-review-workspace"
|
|
570
|
+
>
|
|
606
571
|
{renderedShell}
|
|
607
|
-
{/*
|
|
608
|
-
* The context band is a workspace-layer surface (DESIGN-EDITOR.md
|
|
609
|
-
* §4.2) and therefore gated on the toolbar-layer visibility flag
|
|
610
|
-
* — the `selection` chrome preset suppresses both toolbar and
|
|
611
|
-
* band so minimal embeds stay chrome-free. If a future preset
|
|
612
|
-
* wants the band without the formatting toolbar, introduce a
|
|
613
|
-
* dedicated `chromeVisibility.contextBand` flag rather than
|
|
614
|
-
* decoupling this branch.
|
|
615
|
-
*/}
|
|
616
|
-
{/*
|
|
617
|
-
* Chrome Closure Pass · Task 1 (designsystem.md §6.3) — review,
|
|
618
|
-
* workflow, and More mode actions live in `TwContextBand`; editor
|
|
619
|
-
* mode stays toolbar-only unless a future pass adds real contextual
|
|
620
|
-
* authoring content.
|
|
621
|
-
*/}
|
|
622
|
-
{showContextBand ? (
|
|
623
|
-
<TwContextBand mode={composition.mode}>
|
|
624
|
-
{composition.mode === "more" ? (
|
|
625
|
-
<TwMoreContextBandContent
|
|
626
|
-
onOpenDiagnostics={() => {
|
|
627
|
-
setReviewRailOpen(true);
|
|
628
|
-
props.onActiveRailTabChange?.("health");
|
|
629
|
-
}}
|
|
630
|
-
onOpenCompatibility={() => {
|
|
631
|
-
setReviewRailOpen(true);
|
|
632
|
-
props.onActiveRailTabChange?.("health");
|
|
633
|
-
}}
|
|
634
|
-
onOpenOutline={() => setNavOpen(true)}
|
|
635
|
-
onOpenSearch={props.onOpenInlineFind ?? props.reviewRailFooter?.onSearch}
|
|
636
|
-
/>
|
|
637
|
-
) : viewState.editorRole ? (
|
|
638
|
-
<TwRoleActionRegion
|
|
639
|
-
role={viewState.editorRole}
|
|
640
|
-
policy={scopedChromePolicy}
|
|
641
|
-
compactMode={responsiveChrome.isNarrow}
|
|
642
|
-
reviewQueue={props.reviewQueue}
|
|
643
|
-
markupDisplay={markupDisplay}
|
|
644
|
-
canAddComment={
|
|
645
|
-
toolbarInteractionPolicy?.canAddComment ??
|
|
646
|
-
(caps ? caps.canAddComment : false)
|
|
647
|
-
}
|
|
648
|
-
showTrackedChanges={trackedChangesAuthoringEnabled}
|
|
649
|
-
capabilities={caps}
|
|
650
|
-
onAddComment={
|
|
651
|
-
props.onAddComment
|
|
652
|
-
? runWithSelectionToolbarDismiss(props.onAddComment)
|
|
653
|
-
: undefined
|
|
654
|
-
}
|
|
655
|
-
onShowTrackedChangesChange={(show) => {
|
|
656
|
-
dismissSelectionToolbar();
|
|
657
|
-
props.onShowTrackedChangesChange(show);
|
|
658
|
-
}}
|
|
659
|
-
onReviewMarkupMode={(mode) => {
|
|
660
|
-
dismissSelectionToolbar();
|
|
661
|
-
props.onReviewMarkupModeChange?.(mode);
|
|
662
|
-
}}
|
|
663
|
-
onReviewSidebarTrackedChanges={
|
|
664
|
-
props.onReviewSidebarTrackedChanges
|
|
665
|
-
? runWithSelectionToolbarDismiss(props.onReviewSidebarTrackedChanges)
|
|
666
|
-
: undefined
|
|
667
|
-
}
|
|
668
|
-
onReviewSidebarComments={
|
|
669
|
-
props.onReviewSidebarComments
|
|
670
|
-
? runWithSelectionToolbarDismiss(props.onReviewSidebarComments)
|
|
671
|
-
: undefined
|
|
672
|
-
}
|
|
673
|
-
onMarkScopePosture={
|
|
674
|
-
props.onMarkSectionForReview
|
|
675
|
-
? runWithSelectionToolbarDismiss(props.onMarkSectionForReview)
|
|
676
|
-
: undefined
|
|
677
|
-
}
|
|
678
|
-
onReviewPrev={
|
|
679
|
-
props.onGoToPreviousReviewItem
|
|
680
|
-
? runWithSelectionToolbarDismiss(props.onGoToPreviousReviewItem)
|
|
681
|
-
: undefined
|
|
682
|
-
}
|
|
683
|
-
onReviewNext={
|
|
684
|
-
props.onGoToNextReviewItem
|
|
685
|
-
? runWithSelectionToolbarDismiss(props.onGoToNextReviewItem)
|
|
686
|
-
: undefined
|
|
687
|
-
}
|
|
688
|
-
onReviewAccept={(() => {
|
|
689
|
-
const active = props.reviewQueue?.items[props.reviewQueue.activeIndex];
|
|
690
|
-
if (active?.kind !== "change" || !props.onAcceptRevision) {
|
|
691
|
-
return undefined;
|
|
692
|
-
}
|
|
693
|
-
const revisionId = active.itemId;
|
|
694
|
-
return () => {
|
|
695
|
-
dismissSelectionToolbar();
|
|
696
|
-
props.onAcceptRevision?.(revisionId);
|
|
697
|
-
};
|
|
698
|
-
})()}
|
|
699
|
-
onReviewReject={(() => {
|
|
700
|
-
const active = props.reviewQueue?.items[props.reviewQueue.activeIndex];
|
|
701
|
-
if (active?.kind !== "change" || !props.onRejectRevision) {
|
|
702
|
-
return undefined;
|
|
703
|
-
}
|
|
704
|
-
const revisionId = active.itemId;
|
|
705
|
-
return () => {
|
|
706
|
-
dismissSelectionToolbar();
|
|
707
|
-
props.onRejectRevision?.(revisionId);
|
|
708
|
-
};
|
|
709
|
-
})()}
|
|
710
|
-
onReviewAcceptAll={
|
|
711
|
-
props.onAcceptAllChanges
|
|
712
|
-
? runWithSelectionToolbarDismiss(props.onAcceptAllChanges)
|
|
713
|
-
: undefined
|
|
714
|
-
}
|
|
715
|
-
onReviewRejectAll={
|
|
716
|
-
props.onRejectAllChanges
|
|
717
|
-
? runWithSelectionToolbarDismiss(props.onRejectAllChanges)
|
|
718
|
-
: undefined
|
|
719
|
-
}
|
|
720
|
-
/>
|
|
721
|
-
) : null}
|
|
722
|
-
</TwContextBand>
|
|
723
|
-
) : null}
|
|
724
572
|
{/*
|
|
725
573
|
* Phase C.γ.3 — mount the workspace chrome host when the
|
|
726
574
|
* integrator has wired an editor-action bag. Omitting the
|
|
@@ -746,9 +594,12 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
746
594
|
/>
|
|
747
595
|
) : null}
|
|
748
596
|
{chromeVisibility.toolbar ? (
|
|
749
|
-
<div
|
|
597
|
+
<div
|
|
598
|
+
className="sticky top-0 z-30 shrink-0 bg-[var(--color-bg-canvas)]/95 px-3 pt-3 backdrop-blur-sm"
|
|
599
|
+
data-testid="tw-review-workspace__sticky-toolbar"
|
|
600
|
+
>
|
|
750
601
|
<ChromePresetToolbar
|
|
751
|
-
chromePreset={
|
|
602
|
+
chromePreset={productChromePreset}
|
|
752
603
|
{...(props.collabSession ? { collabSession: props.collabSession } : {})}
|
|
753
604
|
{...(props.collabTransportStatus
|
|
754
605
|
? { collabTransportStatus: props.collabTransportStatus }
|
|
@@ -763,10 +614,10 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
763
614
|
? { collabSendBaseline: props.collabSendBaseline }
|
|
764
615
|
: {})}
|
|
765
616
|
chromeOptionsResolved={chromeOptions}
|
|
766
|
-
capabilities={
|
|
767
|
-
compatibility={
|
|
768
|
-
warnings={
|
|
769
|
-
blockedReasons={
|
|
617
|
+
capabilities={chromeCapabilities}
|
|
618
|
+
compatibility={diagnosticsCompatibility}
|
|
619
|
+
warnings={diagnosticsWarnings}
|
|
620
|
+
blockedReasons={diagnosticsBlockedReasons}
|
|
770
621
|
showDiagnosticsChrome={chromeVisibility.alerts}
|
|
771
622
|
interactionPolicy={toolbarInteractionPolicy}
|
|
772
623
|
scopedChromePolicy={scopedChromePolicy}
|
|
@@ -894,6 +745,12 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
894
745
|
props.onReviewMarkupModeChange?.(mode);
|
|
895
746
|
}}
|
|
896
747
|
role={viewState.editorRole}
|
|
748
|
+
onEditorRoleChange={(role) => {
|
|
749
|
+
dismissSelectionToolbar();
|
|
750
|
+
if (role !== viewState.editorRole) {
|
|
751
|
+
props.onEditorRoleChange?.(role);
|
|
752
|
+
}
|
|
753
|
+
}}
|
|
897
754
|
reviewQueue={props.reviewQueue}
|
|
898
755
|
markupDisplay={markupDisplay}
|
|
899
756
|
onReviewSidebarTrackedChanges={props.onReviewSidebarTrackedChanges
|
|
@@ -943,8 +800,9 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
943
800
|
|
|
944
801
|
{chromeVisibility.alerts ? <TwAlertBanner
|
|
945
802
|
snapshot={snapshot}
|
|
946
|
-
preserveOnlyCount={preserveOnlyCount}
|
|
947
|
-
workflowBlockedReasons={
|
|
803
|
+
preserveOnlyCount={showDebugDiagnostics ? preserveOnlyCount : 0}
|
|
804
|
+
workflowBlockedReasons={diagnosticsBlockedReasons}
|
|
805
|
+
showPreservationDiagnostics={showDebugDiagnostics}
|
|
948
806
|
onShowDetail={() => {
|
|
949
807
|
setReviewRailOpen(true);
|
|
950
808
|
props.onActiveRailTabChange?.("health");
|
|
@@ -964,7 +822,10 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
964
822
|
/>
|
|
965
823
|
|
|
966
824
|
{/* Document column */}
|
|
967
|
-
<div
|
|
825
|
+
<div
|
|
826
|
+
className="flex min-h-0 flex-1 flex-col min-w-0"
|
|
827
|
+
data-testid="tw-review-workspace__document-scroll-column"
|
|
828
|
+
>
|
|
968
829
|
<div
|
|
969
830
|
ref={scrollRootRef}
|
|
970
831
|
onMouseOver={handleDocumentMouseOver}
|
|
@@ -989,11 +850,10 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
989
850
|
* section-properties controls move to the on-demand
|
|
990
851
|
* band-activation ribbon (Slice B).
|
|
991
852
|
*/}
|
|
992
|
-
{
|
|
993
|
-
gatedSelectionTool &&
|
|
994
|
-
shouldRenderSelectionToolKind(scopedChromePolicy, gatedSelectionTool.kind) ? (
|
|
853
|
+
{shouldRenderFloatingSelectionTool ? (
|
|
995
854
|
<TwSelectionToolHost
|
|
996
855
|
tool={gatedSelectionTool}
|
|
856
|
+
selectionKey={`${viewState.selection.anchor}:${viewState.selection.head}:${viewState.selection.storyTarget?.kind ?? "main"}`}
|
|
997
857
|
contextAnalytics={
|
|
998
858
|
chromeVisibility.contextAnalytics
|
|
999
859
|
? props.selectionContextAnalytics
|
|
@@ -1037,6 +897,7 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1037
897
|
onSetTableAlignment={props.onSetTableAlignment}
|
|
1038
898
|
onSetCellVerticalAlign={props.onSetCellVerticalAlign}
|
|
1039
899
|
onOpenTableMore={openTableMoreMenu}
|
|
900
|
+
showPreservationDiagnostics={showDebugDiagnostics}
|
|
1040
901
|
chromePins={viewState.chromePins}
|
|
1041
902
|
onChromePinChange={props.onChromePinChange}
|
|
1042
903
|
/>
|
|
@@ -1135,10 +996,11 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1135
996
|
style={isPageWorkspace ? pageShellMetrics.contentInsetStyle : undefined}
|
|
1136
997
|
>
|
|
1137
998
|
<div
|
|
1138
|
-
className={isPageWorkspace ? "relative" :
|
|
999
|
+
className={isPageWorkspace ? "relative" : "relative mx-auto w-full max-w-[80rem]"}
|
|
1000
|
+
data-testid="tw-review-workspace__document-column"
|
|
1139
1001
|
data-document-grid={pageChromeModel.documentGridType}
|
|
1140
1002
|
data-page-border-display={pageChromeModel.pageBorderDisplay}
|
|
1141
|
-
style={
|
|
1003
|
+
style={documentColumnStyle}
|
|
1142
1004
|
>
|
|
1143
1005
|
{isPageWorkspace && chromeVisibility.pageChrome && pageChromeModel.showPageBorder && !hidePageBorderForActiveEditing ? (
|
|
1144
1006
|
<div
|
|
@@ -1188,6 +1050,7 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1188
1050
|
grabbedObjectFromOffset={grabbedSegmentOffsets?.from ?? null}
|
|
1189
1051
|
grabbedObjectToOffset={grabbedSegmentOffsets?.to ?? null}
|
|
1190
1052
|
onDeselectObject={props.onDeselectObject}
|
|
1053
|
+
onBeginObjectDrag={props.onBeginObjectDrag}
|
|
1191
1054
|
tableContext={props.tableContext}
|
|
1192
1055
|
onSetColumnWidth={props.onSetColumnWidth}
|
|
1193
1056
|
onSetRowHeight={props.onSetRowHeight}
|
|
@@ -1243,7 +1106,7 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1243
1106
|
<TwStatusBar
|
|
1244
1107
|
isDirty={snapshot.isDirty}
|
|
1245
1108
|
isExportBlocked={snapshot.compatibility.blockExport}
|
|
1246
|
-
preserveOnlyCount={preserveOnlyCount}
|
|
1109
|
+
preserveOnlyCount={showDebugDiagnostics ? preserveOnlyCount : 0}
|
|
1247
1110
|
commentCount={snapshot.comments.totalCount}
|
|
1248
1111
|
changeCount={snapshot.trackedChanges.totalCount}
|
|
1249
1112
|
sessionId={snapshot.sessionId}
|
|
@@ -1255,15 +1118,16 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1255
1118
|
displayPageNumber={statusBarPageFacts.displayPageNumber}
|
|
1256
1119
|
pageCount={statusBarPageFacts.pageCount}
|
|
1257
1120
|
measurementFidelity={statusBarPageFacts.measurementFidelity}
|
|
1121
|
+
debugMode={showDebugDiagnostics}
|
|
1258
1122
|
/>
|
|
1259
1123
|
) : null}
|
|
1260
1124
|
</div>
|
|
1261
1125
|
|
|
1262
|
-
{/* Review rail —
|
|
1126
|
+
{/* Review rail — overlay on desktop, drawer-backed on narrow layouts. */}
|
|
1263
1127
|
<TwReviewWorkspaceRail
|
|
1264
1128
|
mode={
|
|
1265
1129
|
(responsiveChrome.showDockedReviewRail
|
|
1266
|
-
? "
|
|
1130
|
+
? "overlay"
|
|
1267
1131
|
: responsiveChrome.showDrawerReviewRail
|
|
1268
1132
|
? "drawer"
|
|
1269
1133
|
: "hidden") satisfies TwReviewWorkspaceRailMode
|
|
@@ -1274,8 +1138,8 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1274
1138
|
currentUserId: props.currentUserId,
|
|
1275
1139
|
comments: snapshot.comments,
|
|
1276
1140
|
trackedChanges: snapshot.trackedChanges,
|
|
1277
|
-
compatibility:
|
|
1278
|
-
warnings:
|
|
1141
|
+
compatibility: diagnosticsCompatibility,
|
|
1142
|
+
warnings: diagnosticsWarnings,
|
|
1279
1143
|
markupDisplay,
|
|
1280
1144
|
contextAnalytics: chromeVisibility.contextAnalytics
|
|
1281
1145
|
? props.currentScopeContextAnalytics
|
|
@@ -1295,7 +1159,8 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1295
1159
|
onAcceptAllChanges: props.onAcceptAllChanges,
|
|
1296
1160
|
onRejectAllChanges: props.onRejectAllChanges,
|
|
1297
1161
|
// Layer 11 closeout: mounted workspace chrome reads scope
|
|
1298
|
-
// rail data through `api.ui.scope.rail()
|
|
1162
|
+
// rail data through `api.ui.scope.rail()` and scope identity
|
|
1163
|
+
// counts through `api.ui.scope.list()`, with the workflow
|
|
1299
1164
|
// facet retained as the no-provider fallback.
|
|
1300
1165
|
scopeRailSegments,
|
|
1301
1166
|
activeScopeId,
|
|
@@ -1303,7 +1168,7 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1303
1168
|
handleScopeStripeClick({ scopeId: segment.scopeId });
|
|
1304
1169
|
},
|
|
1305
1170
|
workflowTab: props.reviewRailWorkflowTab,
|
|
1306
|
-
workflowCount: props.reviewRailWorkflowCount,
|
|
1171
|
+
workflowCount: props.reviewRailWorkflowCount ?? mountedSemanticScopeCount,
|
|
1307
1172
|
workflowScopesTitle: props.reviewRailWorkflowScopesTitle,
|
|
1308
1173
|
intelligenceEyebrow: props.reviewRailIntelligenceEyebrow,
|
|
1309
1174
|
intelligenceHeader: props.reviewRailIntelligenceHeader,
|
|
@@ -1313,7 +1178,8 @@ export function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {
|
|
|
1313
1178
|
...(diagnosticsSignal.severity !== "none"
|
|
1314
1179
|
? { healthSeverity: diagnosticsSignal.severity }
|
|
1315
1180
|
: {}),
|
|
1316
|
-
workflowBlockedReasons:
|
|
1181
|
+
workflowBlockedReasons: diagnosticsBlockedReasons,
|
|
1182
|
+
showPreservationDiagnostics: showDebugDiagnostics,
|
|
1317
1183
|
}}
|
|
1318
1184
|
/>
|
|
1319
1185
|
</div>
|