Skip to content

feat(web-ongoing-operations): add designated agent foa validation - #23154

Open
louisbensiovh wants to merge 1 commit into
masterfrom
feat/designated-agent
Open

feat(web-ongoing-operations): add designated agent foa validation#23154
louisbensiovh wants to merge 1 commit into
masterfrom
feat/designated-agent

Conversation

@louisbensiovh

Copy link
Copy Markdown
Contributor

Ticket Reference: #D2I-6259

Copilot AI lite review requested due to automatic review settings August 21, 2026 14:59
@louisbensiovh
louisbensiovh requested a review from a team as a code owner August 21, 2026 14:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a “Designated Agent” FOA (Form of Authorization) validation flow for DomainTrade ongoing operations in web-ongoing-operations, including APIv2 integration, UI entry points from the datagrid actions, and a dedicated validation page.

Changes:

  • Added APIv2 FOA/task fetching + validation client, with React Query hooks and utility helpers.
  • Added a new FOA validation page and a new datagrid actions component to expose the FOA CTA when applicable.
  • Updated tests, mocks, routes, and dashboard translations to support the new flow.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/manager/apps/web-ongoing-operations/src/utils/foa.utils.ts Adds FOA “pending” predicate and “most recent task” selection helper.
packages/manager/apps/web-ongoing-operations/src/utils/foa.utils.spec.ts Unit tests for FOA utils.
packages/manager/apps/web-ongoing-operations/src/types/index.ts Introduces APIv2 task + FOA types and an actions props type.
packages/manager/apps/web-ongoing-operations/src/setupTests.tsx Extends test mocks (core-api v2 + stable navigate spy + params).
packages/manager/apps/web-ongoing-operations/src/routes/routes.tsx Registers the new FOA validation route/page.
packages/manager/apps/web-ongoing-operations/src/routes/routes.constant.ts Adds FOA route pattern.
packages/manager/apps/web-ongoing-operations/src/pages/foa/FoaValidation.tsx New FOA validation page composition and gating logic.
packages/manager/apps/web-ongoing-operations/src/pages/foa/FoaValidation.spec.tsx Page-level tests for validation behavior, navigation, and errors.
packages/manager/apps/web-ongoing-operations/src/pages/dashboard/domain/Domain.spec.tsx Adjusts mocks to account for new FOA-related hook usage.
packages/manager/apps/web-ongoing-operations/src/pages/dashboard/dns/Dns.spec.tsx Adjusts mocks to account for new FOA-related hook usage.
packages/manager/apps/web-ongoing-operations/src/pages/dashboard/allDom/AllDom.spec.tsx Adjusts mocks to account for new FOA-related hook usage.
packages/manager/apps/web-ongoing-operations/src/hooks/useOngoingOperationDatagridColumns.tsx Swaps inline menu for a dedicated actions component.
packages/manager/apps/web-ongoing-operations/src/hooks/data/query.tsx Adds FOA/task queries and the usePendingFoas hook.
packages/manager/apps/web-ongoing-operations/src/enum/foa.enum.ts Adds FOA choice enum for validate calls.
packages/manager/apps/web-ongoing-operations/src/data/api/foa.ts Implements APIv2 FOA/task endpoints and validate action.
packages/manager/apps/web-ongoing-operations/src/data/api/foa.spec.ts Unit tests for FOA API client functions.
packages/manager/apps/web-ongoing-operations/src/constants.ts Adds the scheduled-task status constant used for FOA filtering.
packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx New actions menu component including FOA CTA and navigation.
packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.spec.tsx Tests ensuring FOA CTA visibility and navigation behavior.
packages/manager/apps/web-ongoing-operations/src/components/Foa/FoaActions.component.tsx Implements accept/reject flow (multi-FOA, 409-idempotency, notifications).
packages/manager/apps/web-ongoing-operations/src/components/Dashboard/DashboardPage.spec.tsx Adjusts mocks to account for new FOA-related hook usage.
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_pt_PT.json Adds FOA CTA/page/action strings (pt-PT).
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_pl_PL.json Adds FOA CTA/page/action strings (pl-PL).
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_it_IT.json Adds FOA CTA/page/action strings (it-IT).
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_fr_FR.json Adds FOA CTA/page/action strings (fr-FR).
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_fr_CA.json Adds FOA CTA/page/action strings (fr-CA).
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_es_ES.json Adds FOA CTA/page/action strings (es-ES).
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_en_GB.json Adds FOA CTA/page/action strings (en-GB).
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_de_DE.json Adds FOA CTA/page/action strings (de-DE).
Suppressed comments (2)

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:50

  • This className expression can evaluate to "false menu-item-button" when the condition is not met, because template literals stringify false. Prefer a ternary (or clsx) so the "not hidden" case produces an empty string rather than the literal "false" class.
          label: t('domain_operations_tab_popover_progress'),
          className: `${props.function !==
            DomainOperationsEnum.DomainIncomingTransfer &&
            'hidden'} menu-item-button`,

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:61

  • Same issue here: ${!canValidateFoa && 'hidden'} becomes the literal string "false" in the rendered class list when canValidateFoa is true. Use a ternary (or clsx) to avoid emitting a bogus false class.
          id: 3,
          label: t('domain_operations_foa_cta'),
          className: `${!canValidateFoa && 'hidden'} menu-item-button`,
          onClick: () => {

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +35 to +38
id: 1,
label: t('domain_operations_tab_popover_update'),
className: `${!canUpdate && 'hidden'} menu-item-button`,
onClick: () => {
Comment on lines 120 to 122
cell: (props: TOngoingOperations) => (
<ActionMenu
id={`${props.id}`}
isCompact
isDisabled={
!props.canAccelerate && !props.canRelaunch && !props.canCancel
}
variant={ODS_BUTTON_VARIANT.ghost}
items={[
{
id: 1,
label: t('domain_operations_tab_popover_update'),
className: `${!props.canAccelerate &&
!props.canRelaunch &&
!props.canCancel &&
'hidden'} menu-item-button`,
onClick: () => {
const url = `${location.pathname}/update/${props.id}`;
trackPageNavivationTile(url);
navigate(url);
clearNotifications();
},
},
{
id: 2,
label: t('domain_operations_tab_popover_progress'),
className: `${props.function !==
DomainOperationsEnum.DomainIncomingTransfer &&
'hidden'} menu-item-button`,
onClick: () => {
const url = `/tracking/${props.id}`;
trackPageNavivationTile(url);
navigate(url);
},
},
]}
/>
<OngoingOperationDatagridActions props={props} />
),
Copilot AI review requested due to automatic review settings August 24, 2026 14:26
@louisbensiovh
louisbensiovh force-pushed the feat/designated-agent branch from d3f2cf5 to ed6376b Compare August 24, 2026 14:26
ref: #D2I-6259
Signed-off-by: Louis BENSI <louis.bensi@corp.ovh.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@louisbensiovh
louisbensiovh force-pushed the feat/designated-agent branch from ed6376b to 6f0a409 Compare August 24, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.

Suppressed comments (3)

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:37

  • Using a template literal with && here will inject the string "false" into the class list when the condition is falsy (e.g., "false menu-item-button"). Use a ternary (or a classnames helper) to avoid unintended classes.
          className: `${!canUpdate && 'hidden'} menu-item-button`,

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:50

  • This multi-line && 'hidden' expression in a template literal will also produce a literal "false" class when the condition is false. Prefer a ternary so the class list is either "hidden menu-item-button" or just "menu-item-button".
          className: `${props.function !==
            DomainOperationsEnum.DomainIncomingTransfer &&
            'hidden'} menu-item-button`,

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:60

  • Same issue as above: interpolating !canValidateFoa && 'hidden' into a template literal yields an extra "false" class when the item is visible. Use a ternary (or classnames helper) instead.
          className: `${!canValidateFoa && 'hidden'} menu-item-button`,

Comment on lines +20 to +22
const isTrade = props.function === DomainOperationsEnum.DomainTrade;
// Only a change of registrant carries FOAs, so no other row fetches them
const { taskId, pendingFoas } = usePendingFoas(props.domain ?? '', isTrade);
Comment on lines +21 to +26
export const getMostRecentTask = (
tasks: TDomainTaskV2[],
): TDomainTaskV2 | null =>
[...(tasks ?? [])].sort(
(a, b) => getTaskTimestamp(b) - getTaskTimestamp(a),
)[0] ?? null;
Copilot AI review requested due to automatic review settings August 24, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.

Suppressed comments (4)

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:37

  • Using a boolean expression inside a template string can produce an unwanted "false" CSS class when canUpdate is true, because ${!canUpdate && 'hidden'} evaluates to false and gets stringified. Use a ternary (or a classnames helper) so the className is either "hidden" or "".
          className: `${!canUpdate && 'hidden'} menu-item-button`,

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:50

  • This template-string pattern can also stringify to "false" when the condition is not met, adding an unintended class name. Prefer a ternary so the className is stable and only adds "hidden" when needed.
          className: `${props.function !==
            DomainOperationsEnum.DomainIncomingTransfer &&
            'hidden'} menu-item-button`,

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:60

  • Same issue here: ${!canValidateFoa && 'hidden'} becomes the literal "false" class when canValidateFoa is true. Use a ternary to avoid emitting "false" into className.
          className: `${!canValidateFoa && 'hidden'} menu-item-button`,

packages/manager/apps/web-ongoing-operations/src/components/OngoingOperationDatagrid/OngoingOperationDatagridActions.tsx:22

  • usePendingFoas triggers at least one (and potentially two) APIv2 queries per trade row to decide whether to show the FOA entry point. In a datagrid with many trade operations, this becomes an N+1 client-side fetch pattern and can noticeably slow down the listing / increase API load. Consider deferring the FOA lookup until the user interacts (e.g., when opening the menu / clicking the CTA), or aggregating the FOA availability into the main listing payload so the grid can decide without per-row queries.
  const isTrade = props.function === DomainOperationsEnum.DomainTrade;
  // Only a change of registrant carries FOAs, so no other row fetches them
  const { taskId, pendingFoas } = usePendingFoas(props.domain ?? '', isTrade);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants