Add data layer for merge request AI overview tab

This is the data layer half of a split for the merge request AI overview replacement tab, behind the mr_ai_overview flag (default off). It wires up the mount point, an Apollo provider, a GraphQL query and a merge-status subscription, and adds loading, error and retry states to app.vue. It renders an empty container by design: the readiness panel that fills it in lands in the MR above this one.

Detailed context for AI agents

This is part of a chain splitting a single 1085 line change into reviewable pieces. Foundational work already merged as !252481 (merged). The remaining chain, each part building on the one above:

  1. This MR: data layer (mount point, Apollo provider, GraphQL query and subscription, app.vue wiring and states).
  2. !252997: merge readiness panel.
  3. !252998: reviewers panel.
  4. !252999: description and labels.

GraphQL

The query and the merge-status subscription both read existing MergeRequest fields only. No new GraphQL type, field, resolver or service was added, and there is no REST call anywhere in this change.

Mount point

The mount point gains project_path and iid data attributes, which the Vue app reads to build the GraphQL variables. index.js provides the Apollo client that app.vue's query and subscription run through.

Spec fix

Adding the ~/lib/graphql import to this area made spec/frontend/merge_request_tabs_spec.js fail to load. That spec used a bare jest.mock('ee_else_ce/merge_requests/ai_overview') automock, and jest's automock loads the real module once to read its export shape before replacing it with mocks. Once lib/graphql was reachable from that import graph, the automock load ran its top-level code a second time, including Object.defineProperty(window, 'pendingApolloRequests', ...). That property is not configurable, so the second call threw Cannot redefine property. The fix gives the mock an explicit factory so the real module is never loaded.

Verification

Ran the jest suites for ee/spec/frontend/merge_requests/ai_overview and spec/frontend/merge_request_tabs_spec.js: 112 tests passing, no failures. Prettier and eslint clean.

Not dead code

The empty container app.vue renders is intentional. The merge readiness panel that fills it is added directly above this MR in the stack (!252997), so this half has nothing visible to show on its own by design.

Merge request reports

Loading
Loading