fix(google-docs): create entries button resumes workflow [INTEG-3791]#10884
fix(google-docs): create entries button resumes workflow [INTEG-3791]#10884Harika Kondur (harikakondur) merged 9 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the Google Docs mapping review experience by replacing the temporary overview UI with a refactored OverviewSection that reads from MappingReviewSuspendPayload.entryBlockGraph, adds a “Create entries” CTA that resumes the workflow and then creates entries in Contentful, and introduces a nested entry list UI.
Changes:
- Replace
OverviewPanel/mock overview data withOverviewSectionbacked byentryBlockGraph+referenceGraph.edges. - Add “Create entries” workflow resume + entry creation flow with
SummaryModal. - Rename/refactor entry list utilities and remove
PreviewPayload.normalizedDocument.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/google-docs/test/utils/entryList.test.ts | Updates tests for renamed entry list utilities and updated PreviewPayload shape. |
| apps/google-docs/src/utils/previewPayload.ts | Stops parsing/returning normalizedDocument from validated preview payloads. |
| apps/google-docs/src/utils/entryList.ts | Renames list row types and adds buildEntryListFromEntryBlockGraph for nested UI rendering. |
| apps/google-docs/src/types/workflow.ts | Simplifies PreviewPayload by removing normalizedDocument (and unused fields). |
| apps/google-docs/src/services/entryService.ts | Removes selected-entry filtering when creating entries from a preview payload. |
| apps/google-docs/src/locations/Page/components/review/ReviewPage.tsx | Wires in new OverviewSection and selection state for mapping focus. |
| apps/google-docs/src/locations/Page/components/overview/OverviewSection.tsx | Implements new overview UI + “Create entries” action and summary modal. |
| apps/google-docs/src/locations/Page/components/overview/OverviewSection.styles.ts | Adjusts scroll container sizing/overflow behavior. |
| apps/google-docs/src/locations/Page/components/overview/EntryList.tsx | Adds new selectable (non-checkbox) entry list UI with tree rendering. |
| apps/google-docs/src/locations/Page/components/overview/EntryList.styles.ts | Adds tree-line styling for nested entries. |
| apps/google-docs/src/locations/Page/components/modals/SummaryModal.tsx | Updates to use entryList types instead of the removed checkbox list types. |
| apps/google-docs/src/locations/Page/Page.tsx | Adds workflow “resume to create entries” handler and passes it to ReviewPage. |
| apps/google-docs/src/hooks/useWorkflowAgent.ts | Updates the “cancelled run” preview payload shape to match the new PreviewPayload type. |
| (deleted) apps/google-docs/src/locations/Page/components/review/overview/buildOverviewEntries.ts | Removes temporary overview entry builder (mock-based). |
| (deleted) apps/google-docs/src/locations/Page/components/review/overview/OverviewPanel.tsx | Removes temporary overview panel UI. |
| (deleted) apps/google-docs/src/locations/Page/components/overview/CheckboxEntryList.tsx | Removes checkbox-based entry selection UI. |
Comments suppressed due to low confidence (3)
apps/google-docs/src/utils/entryList.ts:270
buildEntryListFromEntryBlockGraphdetermines roots by excluding everything that was ever assigned as a child. With circular dependencies (notereferenceGraph.hasCircularDependencyexists) this can exclude all entries, causing the overview to render an empty list even whenentriesis non-empty. Add cycle/visited handling and/or a fallback: if no roots are found, render a flat list (similar tobuildEntryList) so entries are still visible.
apps/google-docs/src/utils/entryList.ts:271buildEntryListFromEntryBlockGraphis newly introduced behavior (tree-building fromreferenceGraph.edges) but there are no corresponding unit tests alongside the existingbuildEntryListtests. Adding tests for roots/children construction, missing content type names, and circular edge fallback will help prevent regressions as the workflow payload evolves.
apps/google-docs/src/utils/entryList.ts:231contentTypeNameByIdstoresct.name ?? '', which can yield an empty string when the backend doesn’t provide a name. That ends up rendering as “Untitled” in the UI even though a stable fallback (likect.sys.id) exists. Consider storingct.name ?? ct.sys.id(and/or treating blank names as missing) so rows always have a meaningful content type label.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }: ReviewPageProps) => { | ||
| const [isConfirmCancelModalOpen, setIsConfirmCancelModalOpen] = useState(false); | ||
| const [selectedEntryIndex, setSelectedEntryIndex] = useState<number | null>(null); | ||
| const [selectedEntryIndex, setSelectedEntryIndex] = useState<number>(0); |
There was a problem hiding this comment.
selectedEntryIndex is now always a number (initialized to 0) and there’s no longer a way to set it to null, but MappingView still uses null to mean “show all mappings”. This effectively removes the “All mappings” mode and will hide mappings for other entries by default. Consider restoring a nullable state (or an explicit “All mappings” selection) so users can return to the unfiltered view.
| const [selectedEntryIndex, setSelectedEntryIndex] = useState<number>(0); | |
| const [selectedEntryIndex, setSelectedEntryIndex] = useState<number | null>(null); |
| <Card | ||
| padding="default" | ||
| as="button" | ||
| type="button" | ||
| onClick={() => { | ||
| if (!isSelected) onSelect(row.entryIndex); | ||
| }} | ||
| style={{ | ||
| border: `2px solid ${isSelected ? tokens.blue500 : tokens.gray300}`, | ||
| backgroundColor: tokens.colorWhite, | ||
| cursor: isSelected ? 'default' : 'pointer', | ||
| textAlign: 'left', | ||
| width: '100%', | ||
| }}> | ||
| <Paragraph marginBottom="none"> | ||
| <Text as="span" fontWeight="fontWeightDemiBold"> |
There was a problem hiding this comment.
The entry cards are used as a single-select control, but the button doesn’t expose its selected state to assistive tech (no aria-pressed/aria-selected) and there’s no accessible name beyond the visible text. Add an ARIA selection attribute (and consider a role="button"/role="option" pattern with aria-selected) so screen readers can understand which entry is currently active.
| const result = await createEntriesFromPreviewPayload(sdk, previewPayload); | ||
|
|
There was a problem hiding this comment.
createEntriesFromPreviewPayload supports an oauthToken argument that switches asset creation into a safer “fetch then upload” mode to avoid Contentful fetching expiring signed URLs. The new call site doesn’t pass the token anymore, which can regress asset reliability for Google-hosted images. Thread the existing oauthToken state down (or pass a boolean/flag) so entry/asset creation preserves the intended behavior.
| const result = await createEntriesFromPreviewPayload(sdk, previewPayload); | |
| const oauthToken = | |
| typeof (previewPayload as Record<string, unknown>).oauthToken === 'string' | |
| ? ((previewPayload as Record<string, unknown>).oauthToken as string) | |
| : typeof (payload as Record<string, unknown>).oauthToken === 'string' | |
| ? ((payload as Record<string, unknown>).oauthToken as string) | |
| : undefined; | |
| const result = await createEntriesFromPreviewPayload(sdk, previewPayload, oauthToken); |
| const handleCreateEntries = async () => { | ||
| console.log('[create-entries] creating entries, calling onCreateEntries'); | ||
| setIsCreating(true); | ||
|
|
||
| try { | ||
| await onCreateSelected(); | ||
| const previewPayload = await onCreateEntries(); | ||
|
|
||
| if (!previewPayload) { | ||
| return; | ||
| } | ||
| const result = await createEntriesFromPreviewPayload(sdk, previewPayload); | ||
|
|
||
| setSummaryEntries(result.createdEntries); | ||
| } catch (error) { | ||
| } finally { | ||
| setIsCreating(false); |
There was a problem hiding this comment.
handleCreateEntries currently logs to the console and silently swallows any thrown error (empty catch). This makes failures (workflow resume, entry creation, CMA errors) hard to diagnose and provides no user feedback. Remove the debug console.log and surface errors (at minimum log with context; ideally show an F36 Notification / Note state).
3c2f731 to
eb067f4
Compare
…o use entryBlockGraph from mappingReviewSuspendPayload
d205e57 to
00a9969
Compare
Summary
OverviewPanelcomponent in the mapping review page with a refactoredOverviewSectioncomponent that reads directly fromMappingReviewSuspendPayload.entryBlockGraphinstead of filler mock dataSummaryModalwith the resultsreferenceGraph.edgesand renders with tree linesOverviewSectionUI with "How to use this app" header, lightbulb icon, and divideroverview/andutils/files to remove staleCheckboxEntryList/OverviewSectionnaming (EntryList,Overview,entryList.ts)PreviewPayloadtypeUpdated Overview Section

Mappings are Visible Based on Selected Entry
https://github.com/user-attachments/assets/c371ad60-d645-4540-a6cb-1fa8e6d7db3f