Skip to content

Commit 12f5363

Browse files
JuliRossiclaudeFBanfijoaquincasal
authored
feat: drive-integration v1.1 — UI redesigns, keyboard accessibility, pre-flight doc scope [] (#11075)
* chore(drive-integration): remove dev fixtures, debug logs, and mock singletons [INTEG-3806] (#10991) * chore(drive-integration): remove dev fixtures, debug logs, and mock singletons [INTEG-3806] - Delete src/fixtures/googleDocsReview/ and all references in Page.tsx, vite-env.d.ts, .env.example - Remove console.log calls from index.tsx (OAuth callback) and useWorkflowAgent.ts (polling) - Replace shared mock singletons (mockCma, mockSdk) with per-test factory calls in all spec files - Fix pre-existing broken mock in Page.spec.tsx where onAiAccessDenied received a click event instead of a string Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): resolve TypeScript build errors in spec files [INTEG-3806] - Cast createMockSDK() to any in ConfigScreen.spec.tsx so vi mock methods are accessible - Fix onAiAccessDenied mock prop type to accept a string argument - Cast minimal mock objects to any in ModalOrchestrator.spec.tsx to satisfy SDK's BasicMetaSysProps Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(drive-integration): remove unused VITE_ENABLE_MOCK_EDIT_MODAL env var [INTEG-3806] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(drive-integration): move ConfigScreen spec to test/locations folder [INTEG-3806] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): select first root entry when entering edit mode [INTEG-3881] (#10994) * fix: changing default selected index * fix: formatting with prettier * fix(drive-integration): multiselect popover misalignment when list is not scrollable [INTEG-4038] (#10996) * fix(drive-integration): dispatch resize event when multiselect list is not scrollable When a search query filters the list short enough that maxScroll is 0, the scroll-nudge trick produces no scroll event, so Floating UI never repositions the popover and the portal appears misaligned. Fall back to dispatching a window resize event, which autoUpdate listens to by default. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * wip: simplify multiselect reflow to always dispatch window resize --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): fix field dropdowns closing on selection [INTEG-4040] (#11003) * fix(drive-integration): dispatch resize event when multiselect list is not scrollable When a search query filters the list short enough that maxScroll is 0, the scroll-nudge trick produces no scroll event, so Floating UI never repositions the popover and the portal appears misaligned. Fall back to dispatching a window resize event, which autoUpdate listens to by default. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): adjusting height so focusList() doesnt trigger --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * Add eslint script (#11005) * feat(drive-integration): keyboard accessibility for edit action buttons in review view [INTEG-3889] (#11006) * feat(drive-integration): keyboard accessibility for review view [INTEG-3889] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): add Enter key support for multiselect dropdowns [INTEG-3889] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): creating keyboard utils and refactoring styles [INTEG-3889] * refactor(drive-integration): adding timeout to change focus + adding enter handler [INTEG-3889] * refactor(drive-integration): defensive preventDefault [INTEG-3889] * refactor(drive-integration): addressing PR comments [INTEG-3889] --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(drive-integration): adding remove button redesign [INTEG-4135] (#11021) * feat(drive-integration): adding remove button redesign [INTEG-4135] * refactor(drive-integration): image removal through three dots button * refactor(drive-integration): adding ability to remove images through selection [INTEG-4135] * Revert "feat(drive-integration): adding remove button redesign [INTEG-4135] (#11021)" This reverts commit 6a654fa. * refactor(drive-integration): Move modal redesign [INTEG-4116] (#11019) * feat(drive-integration): redesign Edit content mapping modal with two-column layout [INTEG-4116] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): align columns, wrap in shared border, scrollable entry list [INTEG-4116] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): grey backgrounds, fixed left column width, tighter card padding [INTEG-4116] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): xs padding and borders on all grey background boxes [INTEG-4116] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): PlusIcon, simplify CSS to f36 props, fix tests [INTEG-4116] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor: removing comments and margin * fix(drive-integration): update MappingView tests for new EditModal layout [INTEG-4116] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): truncating edit modal labels + refactoring utils file * refactor(drive-integration): using grid component [INTEG-4116] * refactor(drive-integration): changing edit modal field type color [INTEG-4116] --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(drive-integration): adding remove button redesign [INTEG-4135] (#11023) * feat(drive-integration): adding remove button redesign [INTEG-4135] (#11021) * feat(drive-integration): adding remove button redesign [INTEG-4135] * refactor(drive-integration): image removal through three dots button * refactor(drive-integration): adding ability to remove images through selection [INTEG-4135] * refactor(drive-integration): avoid double DOM query for selection locations [INTEG-4135] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * prettier: fixing validation * refactor(drive-integration): addressing comments [INTEG-4135] * refactor(drive-integration): isViewMode prop refactor [INTEG-4135] --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): flaky modal tests caused by react-modal timer leak [INTEG-4036] (#11029) * test(drive-integration): fix flaky modal tests caused by react-modal timer leak Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): extend flaky timer fix to all remaining modal test files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): move react-modal timer fix to global setupTests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): guard runAllTimers in afterEach against inline useRealTimers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): revert to per-file timer fix for modal tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): explicitly cleanup before flushing timers in modal tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): fix cleanup ordering in SelectTabsModal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: review page UI adjustments [INTEG-4179] (#11028) * fix(drive-integration): review page UI adjustments [INTEG-4179] - Add empty state message in Edit Modal when no current location exists - Show affected mappings list in removal confirmation modal - Verified image removal via text selection is working correctly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): update RemoveContentModal tests for locations prop [INTEG-4179] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: prettier formatting on RemoveContentModal spec Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): fix react-modal teardown error in IncludeImagesModal spec [INTEG-4179] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): fix react-modal portal teardown error in test environment [INTEG-4179] Set ReactModal.setAppElement globally in setupTests so the portal always has a valid DOM parent to detach from, preventing document-is-not-defined errors when the 200ms close timeout fires after jsdom teardown. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): flush react-modal close timer in IncludeImagesModal spec [INTEG-4179] Use vi.useFakeTimers({ shouldAdvanceTime: true }) + vi.runAllTimers() in afterEach to flush the 200ms portal close timeout before jsdom tears down, preventing the "document is not defined" unhandled error in CI. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): deduplicate beforeEach/afterEach in IncludeImagesModal spec [INTEG-4179] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): use ArrowRightIcon in removal confirmation modal [INTEG-4179] Replace text arrow with Forma 36 ArrowRightIcon in the mappings list. Also reverts IncludeImagesModal spec to base branch version (fix already merged by Franco in #11029). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(drive-integration): add entry wizard for new entry design updates [INTEG-4136] (#11027) * feat(drive-integration): add entry wizard in edit content modal [INTEG-4136] Wires up the "Add entry" button in the EditModal with a 4-step semi-wizard: select content type → is-reference → select reference entry → select fields. On save, appends a new EntryBlockGraphEntry and applies field assignments. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): wizard navigation through modal controls [INTEG-4136] Remove wizard-internal buttons. Wizard step state is lifted into EditModal so Modal.Controls drives Back/Next/Save, and the X button cancels as usual. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): stretch left column border to full row height [INTEG-4136] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(drive-integration): lift referenceGraph into state for full edge fidelity [INTEG-4136] referenceGraph now lives in useState in ReviewPage (same pattern as entryBlockGraph). handleAddEntry appends a reference edge when the wizard's isReference + referenceEntryId are set, so the graph reflects the new relationship immediately without a full workflow re-run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): wizard step as enum, switch for navigation [INTEG-4136] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): extract buildFieldOptionsForContentType to fieldFormatting [INTEG-4136] Removes duplicated field-option mapping logic shared between getNewLocationForEntry and buildNewLocationForContentType. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): write reference field into new entry fields on add [INTEG-4136] Auto-picks the first Link/Entry or Array/Entry field on the content type and writes { __ref: referenceEntryId } into newEntry.fields so entryService pass 2 resolves it to a real Contentful link on create. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): flip reference direction — new entry is child, selected entry is parent Parent entry now holds { __ref: newTempId } in its first Link/Entry field. Reference graph edge is from parent → new child, matching Contentful's data model. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Revert "fix(drive-integration): flip reference direction — new entry is child, selected entry is parent" This reverts commit baf8b1f. * feat(drive-integration): add reference field selection step to add-entry wizard New step 4 (SelectReferenceField) appears between SelectReference and SelectFields when the chosen content type has more than one Link/Entry or Array/Entry field. Auto-skipped for content types with a single reference field — falls back to auto-picking the first one. User-selected field id is passed through to handleAddEntry. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): extract isEntryReferenceField predicate to fieldFormatting Replaces inline Link/Entry + Array/Entry checks in MappingView and EditModal with a named predicate, consistent with the existing isAssetFieldForImageAssign pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): simplify refField lookup in handleAddEntry Resolve the field object once instead of storing the id and re-scanning fields to check its type. Removes the redundant inner refFieldId check. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(drive-integration): prettier format touched files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): add AddEntryWizard step-by-step tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(drive-integration): formating with prettier * fix(drive-integration): fix stale referenceGraph read and duplicate image targets in handleAddEntry - Pass live `referenceGraph` state as a prop to MappingView so appended edges are read from current state rather than the original payload snapshot, preventing edge loss when adding multiple reference entries in one session - Remove duplicate assetTargets/rtTargets variables in the image content branch — reuse the already-computed richTextTargets/nonRichTextTargets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): update SelectReferenceField label copy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): use switch for wizard step rendering in AddEntryWizard * refactor(drive-integration): rename WizardState interface to Wizard * refactor(drive-integration): rename isWorkflowContentTypeFieldWithId to hasFieldId * refactor(drive-integration): use crypto.randomUUID() for new entry tempId * refactor(drive-integration): use hasFieldId helper instead of 'id' in f inline check * refactor(drive-integration): use reduce to partition richText and nonRichText targets * Revert "refactor(drive-integration): use reduce to partition richText and nonRichText targets" This reverts commit 5ca0fd9. * refactor(drive-integration): extract isLinkedReference condition in handleAddEntry * fix(drive-integration): non-null assert referenceEntryId after isLinkedReference guard * fix(drive-integration): use resolved refField.id for reference graph edge fieldId * fix(drive-integration): skip fields with no type instead of defaulting to Text Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): add hasFieldType guard and reuse across field resolution Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): replace wizard switch blocks with WIZARD_STEPS descriptor map Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): move buildNewLocationForContentType into EditModal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(drive-integration): moving thigs from wizardSteps.ts to AddEntryWizard.tsx --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * test(drive-integration): fix react-modal timer leak in RemoveContentModal spec (#11032) PR #11028 added new open-modal tests to RemoveContentModal.spec.tsx but didn't carry over the fake-timer guard from #11029. react-modal's 200ms portal close setTimeout fires after jsdom teardown, causing "document is not defined" in CI. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(drive-integration): resolve ESLint errors from v1.1 lint pass - Drop unused activeRunId state (value was set but never read) - Drop unused resumeWorkflow destructure from useWorkflowAgent - Wrap resetDocumentSelection, resetProgress, and handleWorkflowError in useCallback to fix exhaustive-deps warnings on their callers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Franco Banfi <62450599+FBanfi@users.noreply.github.com> Co-authored-by: francobanfi <franco.banfi@external.contentful.com> Co-authored-by: Joaquin <joaquin.casal@external.contentful.com> Co-authored-by: joaquin <joaquin.casal@10pines.com>
1 parent b174f2d commit 12f5363

54 files changed

Lines changed: 4759 additions & 630 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/drive-integration/.env.example

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@ CONTENTFUL_ACCESS_TOKEN=
44
PROD_STATIC_S3_BASE=
55
GOOGLE_DOCS_PROD_CLOUDFRONT_DIST_ID=
66

7-
# Frontend (Vite): dev-only UI to view a review payload from a fixture.
8-
VITE_ENABLE_MOCK_REVIEW_PAYLOAD=
9-
10-
# Frontend (Vite): dev-only UI to preview the exclude/edit modal inside the mapping view.
11-
VITE_ENABLE_MOCK_EDIT_MODAL=
12-
137
# Frontend (Vite): opt in to a local Agents API during development.
148
VITE_LOCAL_AGENTS_API_BASE_URL=
159

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import eslint from '@eslint/js';
2+
import tseslint from 'typescript-eslint';
3+
import reactPlugin from 'eslint-plugin-react';
4+
import reactHooksPlugin from 'eslint-plugin-react-hooks';
5+
6+
export default tseslint.config(
7+
eslint.configs.recommended,
8+
...tseslint.configs.recommended,
9+
reactPlugin.configs.flat.recommended,
10+
{
11+
plugins: { 'react-hooks': reactHooksPlugin },
12+
settings: { react: { version: 'detect' } },
13+
rules: {
14+
'react/react-in-jsx-scope': 'off',
15+
'react/prop-types': 'off',
16+
'react-hooks/rules-of-hooks': 'error',
17+
'react-hooks/exhaustive-deps': 'warn',
18+
'@typescript-eslint/no-explicit-any': 'warn',
19+
},
20+
},
21+
{
22+
ignores: ['build/', 'dist/', 'node_modules/'],
23+
}
24+
);

apps/drive-integration/functions/oauth/oauth.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface AppEventHandlerRequest {
1616
state?: string;
1717
}
1818

19+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
1920
export interface AppEventHandlerResponse {
2021
// Empty response for event handlers
2122
}

0 commit comments

Comments
 (0)