Feat/dce 212 - #23035
Conversation
Replace the legacy express-order page (PriceCards + Order component) with the
react-order Anycast MFE, selected at runtime:
- add AnycastOrder/{anycastOrderModule,anycastOrderComponent}: load
`react-order/anycast` (subscribe) when the domain has no DNS zone, or
`react-order/anycast_upgrade` (upgrade) when it already has one; pass
subsidiary/language/hostAppName and zoneName/dnssecSupported
- route the anycast order path to the configo as a child of DomainDetailPage
so the dashboard stays mounted (no focus-driven remount loop, fluid return)
- navigate with push (not replace) so the configo's history.back() returns to
the originating tab without a hard reload
- drop the now-unused DnsOrder page, DnsZoneOrder and DnsOrderCard (+ specs)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rder The Anycast order route matches no domain tab, so no tab stayed highlighted. Highlight the tab it was launched from — DNS servers or general information — from the navigation state, and skip rendering the DNS tab's own content panel on that route (the configo already renders in the Outlet). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The configo Return/Finish buttons fall back to window.history.back() (SPA, no dashboard reload) for in-app navigation. But on a direct entry (email link, bookmark, refresh) there is no in-app history, so history.back() goes nowhere / out of the app. Detect direct entry via react-router's location.key and, in that case only, pass an explicit navbar.backUrl to the DNS servers tab so the buttons always land on a real page. In-app navigation stays fluid (no backUrl). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Disable refetchOnWindowFocus on the domain zone query. On the subscribe flow the zone query is errored (no zone yet), and staleTime never guards errored queries — so returning from the express tab refetched it, flipped domainZone undefined -> defined, and made the host swap the subscribe MFE for the upgrade one, remounting the federated tunnel and dropping its post-submit confirmation recap. The zone's existence does not change on tab focus, so the refetch is unnecessary. ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CI (pnpm) resolved @types/react@19 for web-domains — which has no explicit pin — while manager-react-shell-client and react are on v18, causing TS2786 'RouterProvider cannot be used as a JSX component' and a ShellContext type mismatch in App.tsx. Pin @types/react and @types/react-dom to v18 like the other apps do. ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- keep the legacy zone activation route + DnsOrderPage on this branch (the Anycast PR only replaces the Anycast order path; the zone-subscription branch rewires zoneActivate to the zone configo), so "Activate zone" no longer 404s - make useGetDomainZone's refetchOnWindowFocus opt-out an explicit option (defaults to the React Query default) and disable it only from the Anycast tunnel, instead of globally - harden the direct-entry backUrl with an end-anchored replace that works with the hash router and preserves any query string - add anycastOrderComponent tests (subscribe vs upgrade, loading, navbar) ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These components remain in production on this branch (they back the legacy zone activation route), so keep their unit tests instead of dropping coverage. ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Integrate the react-order `zone` configo (Module Federation MFE) as the
DNS zone activation funnel:
- add ZoneOrder/{zoneOrderComponent,zoneOrderModule} loading `react-order/zone`,
passing subsidiary/language/hostAppName and zoneName/dnssecSupported
- add ZoneActivatePage (dedicated route) rendering the configo, with a back
link to the domain general information tab
- redirect the zone tab to the activation route when the domain has no DNS
zone (replaces the previous "no zone" banner + activate button); the MFE
stays on an isolated route so its post-submit confirmation recap survives
- point the zoneActivate route to ZoneActivatePage
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…l-info return - mount the react-order `zone` configo on a route nested under DomainDetailPage (sibling of ZoneLayout), so the dashboard chrome stays mounted (fluid, no full reload) while the MFE escapes ZoneLayout's focus-driven remount - redirect the zone tab to that route when the domain has no DNS zone - forward `navbar.backUrl` (domain general information tab) so the configo's Return and post-submit Finish buttons land on the general information tab - drop the now-unused standalone ZoneActivatePage and its spec Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-aligned validation) Rebuild the legacy "new DNS zone" tunnel to build the express order directly and validate the domain like the react-order `zone` configo: - service: build the `dns` express order (zone + template + optional DNSSEC and Anycast addon) via the jsurl `?products=` express URL; getAnycastPrice from the public catalog; validateZone = local regex + IAM ownership probe (v2/iam/resource) + cart `/checkout` probe (zone_exists / invalid_zone) that also reports DNSSEC support. Soft-pass on hard failures. - controller: debounced domain check with a stale-response guard, surfaces the validation reason (zone_exists vs invalid) and pre-selects DNSSEC when available - template (oui UI): options as oui-tile cards with oui-checkbox (Anycast + catalog price, conditional DNSSEC showing "Inclus"), fixed 12-month commitment as a disabled radio tile, Anycast renewal note using the catalog price, validation errors as oui-message panels (dedicated "zone already registered" message), centered inline loader - drop the isZoneValid stub (routing resolve + component binding) - add i18n keys across the 8 locales Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes the CI lint failure (prettier) on dns-zone-new.html. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Turn the Anycast and DNSSEC option tiles into selectable oui-checkbox thumbnails (blue card when checked), moving label, description and the price/included indicator into the checkbox label/description/footer slots. Show the Anycast price as "HT / an" via the catalog-price interval unit, drop "Activer"/"Enable" from the tile titles, and size the footer price/included text with oui-heading_6. Remove the dead data-user attribute from the catalog-price usages (currency comes from coreConfig). ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The zone order tunnel only ever sends the 'basic' template (aligned with the react-order zone configo), so the TEMPLATES enum and its unused 'minimized' entry are dead — replace them with a single DEFAULT_TEMPLATE constant. Also fix a pre-existing no-multi-assign lint error in the zone-name check. ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The other locales are regenerated by the i18n pipeline, so the PR only carries the fr_FR source translations for the DNS zone order tunnel. ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: CDS Translator Agent <opensource@ovh.net>
… spec Use an end-anchored regex for the navbar backUrl (hash-router safe, preserves query, no wrong-occurrence replace), matching the Anycast component, and add a unit spec covering the loading state, dnssecSupported and backUrl derivation. ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the DNS zone activation/order flows by replacing the legacy in-app order UI with “react-order” (module-federated) configo tunnels, and refreshes the legacy Angular DNS zone creation screen to support option selection (Anycast/DNSSEC) and improved zone validation.
Changes:
- Reworked the legacy Angular “new DNS zone” page to validate zone names via IAM + cart probes, surface “zone exists” errors, and allow ordering Anycast/DNSSEC.
- Replaced the previous React
DnsOrderPageflow with two dedicated module-federation tunnels: Zone order configo and Anycast order configo (subscribe/upgrade). - Updated routing/navigation to support the new configo routes and improve back-navigation behavior, plus added tests for the new configo host components.
Reviewed changes
Copilot reviewed 34 out of 34 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/manager/apps/web/client/app/dns-zone/new/translations/Messages_pt_PT.json | Adds new i18n keys for options/duration/submit and “zone exists”. |
| packages/manager/apps/web/client/app/dns-zone/new/translations/Messages_pl_PL.json | Adds new i18n keys for options/duration/submit and “zone exists”. |
| packages/manager/apps/web/client/app/dns-zone/new/translations/Messages_it_IT.json | Adds new i18n keys for options/duration/submit and “zone exists”. |
| packages/manager/apps/web/client/app/dns-zone/new/translations/Messages_fr_FR.json | Adds new i18n keys for options/duration/submit and “zone exists”. |
| packages/manager/apps/web/client/app/dns-zone/new/translations/Messages_fr_CA.json | Adds new i18n keys for options/duration/submit and “zone exists”. |
| packages/manager/apps/web/client/app/dns-zone/new/translations/Messages_es_ES.json | Adds new i18n keys for options/duration/submit and “zone exists”. |
| packages/manager/apps/web/client/app/dns-zone/new/translations/Messages_en_GB.json | Adds new i18n keys for options/duration/submit and “zone exists”. |
| packages/manager/apps/web/client/app/dns-zone/new/translations/Messages_de_DE.json | Adds new i18n keys for options/duration/submit and “zone exists”. |
| packages/manager/apps/web/client/app/dns-zone/new/new.component.js | Removes the obsolete isZoneValid binding. |
| packages/manager/apps/web/client/app/dns-zone/new/index.js | Replaces manager-product-offers wiring with Angular + translate + new service registration. |
| packages/manager/apps/web/client/app/dns-zone/new/dns-zone-new.service.js | New Angular service for zone validation (IAM + cart probes) and Anycast price extraction. |
| packages/manager/apps/web/client/app/dns-zone/new/dns-zone-new.routing.js | Removes the placeholder isZoneValid resolve. |
| packages/manager/apps/web/client/app/dns-zone/new/dns-zone-new.html | Replaces the old stepper/product-offers UI with direct validation + option selection + submit. |
| packages/manager/apps/web/client/app/dns-zone/new/dns-zone-new.controller.js | Updates controller to use the new service and build an express-order payload with options. |
| packages/manager/apps/web/client/app/dns-zone/new/dns-zone-new.constants.js | Adds constants for regex validation, plan codes, durations, config labels, and tracking. |
| packages/manager/apps/web-domains/src/zone/pages/zone/Zone.page.tsx | Redirects to zone activation configo route when no zone exists; removes activate button/banner logic. |
| packages/manager/apps/web-domains/src/domain/routes/routes.tsx | Replaces DnsOrderPage routes with Zone/Anycast configo routes and adjusts nesting. |
| packages/manager/apps/web-domains/src/domain/hooks/data/query.ts | Adds optional refetchOnWindowFocus control to useGetDomainZone. |
| packages/manager/apps/web-domains/src/domain/components/ZoneOrder/zoneOrderModule.tsx | New MF runtime loader/mounter for the react-order/zone remote. |
| packages/manager/apps/web-domains/src/domain/components/ZoneOrder/zoneOrderComponent.tsx | New host component that derives options/backUrl and renders the zone configo. |
| packages/manager/apps/web-domains/src/domain/components/ZoneOrder/zoneOrderComponent.spec.tsx | Adds unit tests for ZoneOrderComponent prop forwarding and backUrl derivation. |
| packages/manager/apps/web-domains/src/domain/components/ServiceDetail/ServiceDetailTabs.tsx | Keeps originating tab highlighted when Anycast order configo is shown; hides DNS tab content while on configo. |
| packages/manager/apps/web-domains/src/domain/components/ConfigurationCards/DnsState.tsx | Switches to push navigation for Anycast order route (better history.back behavior). |
| packages/manager/apps/web-domains/src/domain/components/AnycastOrder/DnsZoneOrder.tsx | Deletes legacy in-app DNS zone order UI (replaced by configo). |
| packages/manager/apps/web-domains/src/domain/components/AnycastOrder/DnsZoneOrder.spec.tsx | Deletes tests for the removed legacy DNS zone order component. |
| packages/manager/apps/web-domains/src/domain/components/AnycastOrder/anycastOrderModule.tsx | New MF runtime loader/mounter for react-order/anycast and react-order/anycast_upgrade. |
| packages/manager/apps/web-domains/src/domain/components/AnycastOrder/anycastOrderComponent.tsx | New host component selecting subscribe vs upgrade tunnel and handling direct-entry navbar behavior. |
| packages/manager/apps/web-domains/src/domain/components/AnycastOrder/anycastOrderComponent.spec.tsx | Adds unit tests for subscribe/upgrade selection and navbar direct-entry behavior. |
| packages/manager/apps/web-domains/src/domain/components/AnycastOrder/AnycastOrderButton.tsx | Switches to push navigation for Anycast order route and forwards “from tab” state. |
| packages/manager/apps/web-domains/src/common/pages/DnsOrder/DnsOrder.page.tsx | Deletes the legacy combined DNS/zone order page (replaced by configo hosts). |
| packages/manager/apps/web-domains/src/common/pages/DnsOrder/DnsOrder.page.spec.tsx | Deletes tests for the removed legacy order page. |
| packages/manager/apps/web-domains/src/common/components/DnsOrderCard/DnsOrderCard.tsx | Deletes the legacy Anycast order card (replaced by configo). |
| packages/manager/apps/web-domains/src/common/components/DnsOrderCard/DnsOrderCard.spec.tsx | Deletes tests for the removed legacy order card. |
| packages/manager/apps/web-domains/package.json | Adds React type dependencies. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| </ovh-manager-product-offers> | ||
| </div> | ||
|
|
||
| <p class="mt-2" data-ng-if="$ctrl.options.anycast"> |
| container.innerHTML = ''; | ||
| } | ||
| }; | ||
| }, [subsidiary, language, zoneName, dnssecSupported]); |
| container.innerHTML = ''; | ||
| } | ||
| }; | ||
| }, [subsidiary, language, zoneName, dnssecSupported]); |
| import get from 'lodash/get'; | ||
| import map from 'lodash/map'; | ||
|
|
||
| import { | ||
| pricingConstants, | ||
| workflowConstants, | ||
| } from '@ovh-ux/manager-product-offers'; | ||
|
|
||
| import { WORKFLOW_OPTIONS } from './dns-zone-new.constants'; | ||
| import { TEMPLATES } from '../../domain/zone/activate/activate.constants'; | ||
| ANYCAST_PLAN_CODE, | ||
| CONFIGURATION_LABELS, | ||
| DEFAULT_DURATION, | ||
| DEFAULT_PRICING_MODE, | ||
| DEFAULT_TEMPLATE, | ||
| DNS_PRODUCT_ID, | ||
| TRACKING, | ||
| ZONE_PLAN_CODE, | ||
| } from './dns-zone-new.constants'; |
| order() { | ||
| this.atInternet.trackClick(TRACKING.ORDER); | ||
| const products = this.buildExpressOrderProducts(); | ||
| return this.$window.open( | ||
| `${this.expressOrderUrl}?products=${JSURL.stringify(products)}`, | ||
| '_blank', | ||
| 'noopener', | ||
| ); | ||
| } |
| * @param {Object} catalog Public `dns` catalog | ||
| * @return {Object|null} Catalog price object ({ value, text, currencyCode }) | ||
| * or null when not found. |
| .finally(() => { | ||
| if (cartId) { | ||
| this.WucOrderCartService.deleteCart(cartId); | ||
| } | ||
| }); |
- guard Anycast renewal price on anycastPrice to avoid a null price component - add hostAppName/navbar.backUrl to zone and anycast effect deps for fresh config - unescape pl_PL Anycast label to a plain space Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…hind feature flags Replace the hardcoded region === EU checks for the DynHost tab and free hosting activation with feature-availability flags, and gate the associated email card behind its own flag: - web-domains:domains:dynhost - web-domains:domains:freehosting - web-domains:domains:associated-email Refs: INC0236492 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| * | ||
| * @param {string} ovhSubsidiary | ||
| * @param {string} zoneName | ||
| * @return {Promise<{ valid: boolean, dnssecAvailable: boolean }>} |
| // The Anycast order tunnel has its own URL that matches no tab. Keep the | ||
| // tab it was launched from highlighted: DNS servers vs general information. | ||
| if (matchPath(`${urls.domainTabOrderAnycast}/*`, location.pathname)) { | ||
| tab = | ||
| location.state?.from === AnycastPreviousPages.DNS_SERVERS | ||
| ? 'dns' | ||
| : 'information'; | ||
| } |
| tab.id !== 'dynhost' || availability?.['web-domains:domains:dynhost'], | ||
| ); | ||
|
|
||
| const handleValueChange = async (event: TabsValueChangeEvent) => { |
…for contact admin check
On CA/US, getUser().nichandle returns the login email whereas the domain
contactAdmin.id is an account handle, so the equality check always failed and
hid the owner-edit link ("Contact your administrator"). Use getUser().auth.account
(the handle) which matches contactAdmin.id on all subsidiaries.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 40 out of 40 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (2)
packages/manager/apps/web-domains/src/domain/components/ServiceDetail/ServiceDetailTabs.tsx:67
legacyTabsis mutated on every tab click when the zone feature is disabled, which can append duplicate entries over time. This is unnecessary global state mutation and can grow the array indefinitely.
const handleValueChange = async (event: TabsValueChangeEvent) => {
if (!availability?.['web-domains:zone']) {
legacyTabs.push('zone');
}
packages/manager/apps/web/client/app/dns-zone/new/dns-zone-new.service.js:62
- The JSDoc return type for
validateZonedoesn’t match what the function actually resolves (it also returns areason). Keeping the doc accurate helps callers use the API correctly.
* @param {string} ovhSubsidiary
* @param {string} zoneName
* @return {Promise<{ valid: boolean, dnssecAvailable: boolean }>}
*/
| if (!isFetchingDomainZone && !domainZone) { | ||
| return <Navigate to={buildUrl(domainUrls.zoneActivate)} replace />; | ||
| } |
| if (domainZoneError) { | ||
| addInfo(t('zone_page_message_no_zone'), false); | ||
| } | ||
| }, [isFetchingDomainZone, domainZoneError]); |
ref: #DCE-218 Signed-off-by: Louis BENSI <louis.bensi@corp.ovh.com>
Fresh pnpm installs resolved the transitive @types/react to 19.2.17 while the app runs React 18.2.0, producing 94 TS2786/TS2345 errors (React 18/19 type mismatch). Pinning @types/react and @types/react-dom in devDependencies lets manager-pm's critical-deps normalization keep them on v18, like every other pnpm-managed app. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: CDS Translator Agent <opensource@ovh.net>
Redirect the domain listing "cancel terminate" action to billing/autorenew/services/cancel-resiliation using serviceId (domain name) and serviceType=DOMAIN, matching the billing route query params. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 53 out of 53 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.Me.Contact.component.tsx:86
- Lowercasing this dynamic i18n key will miss existing camelCase keys in most locales (e.g.
domain_operations_update_nicowner_click_whoisContactBilling). Consider using a fallback list so both old and new key casings resolve.
| // Use the account handle (auth.account), not nichandle: on CA/US | ||
| // getUser().nichandle is the login email, whereas contactAdmin.id is a handle. | ||
| setNichandle(user.auth.account); | ||
| }; |
| <FormFieldLabel> | ||
| {t(`domain_operations_update_key_${argumentKey}`)} | ||
| {t(`domain_operations_update_${argumentKey}`.toLowerCase())} | ||
| </FormFieldLabel> |
| <li key={item} className="font-bold text-[var(--ods-color-text)]"> | ||
| {t(`domain_operations_update_${item}`)} | ||
| {t(`domain_operations_update_${item}`.toLowerCase())} | ||
| </li> |
| }} | ||
| > | ||
| {t(`domain_operations_update_${argumentKey}_click`)} | ||
| {t(`domain_operations_update_${argumentKey}_click`.toLowerCase())} |
| "domain_operations_update_companynationalidentificationnumber": "Tax code ", | ||
| "domain_operations_update_nationalidentificationnumber": "Tax code ", |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 53 out of 53 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (7)
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.String.component.tsx:56
argumentKeyis lowercased before lookup, but many locale files (e.g. en_GB/pt_PT) still define camelCase keys likedomain_operations_update_firstName. This will make labels fall back to the key / show missing translations depending on i18next config. Consider passing an array of keys so both the new lowercase and the legacy camelCase keys resolve.
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.Me.component.tsx:55- The translation key is forced to lowercase, but several locales still use camelCase keys (e.g.
domain_operations_update_firstName_click). This can produce missing translations. Use i18next's array fallback to support both key casings during the migration.
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.Me.Contact.component.tsx:67 - This lowercases the dynamically-built translation key. Since several locales still contain camelCase variants (e.g.
domain_operations_update_spareEmail), the labels can go missing. Use an i18next key array to support both legacy and new key casing.
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.Me.Contact.component.tsx:86 - The click-label key is lowercased, but not all locale JSON files have been migrated to lowercase key names. This can cause missing translations for some subsidiaries/locales. Use an i18next key array so both lowercase and legacy keys resolve.
packages/manager/apps/web-ongoing-operations/src/hooks/nichandle/useNichandle.tsx:16 user.authis accessed without optional chaining; ifauthis absent in some environments, this will throw at runtime. Other parts of the repo guard this (e.g.user.auth?.account).
packages/manager/apps/web-ongoing-operations/public/translations/dashboard/Messages_en_GB.json:182- Trailing whitespace in these labels will be user-visible and can also cause inconsistent snapshot expectations in tests/translations tooling. Remove the extra space.
"domain_operations_update_companynationalidentificationnumber": "Tax code ",
"domain_operations_update_nationalidentificationnumber": "Tax code ",
packages/manager/apps/web/client/app/dns-zone/new/dns-zone-new.service.js:62
- The JSDoc return type for
validateZonedoesn't match the actual resolved object (it also includesreason). This can mislead callers and tooling.
Replace the "Activer mon hébergement gratuit" drawer with the react-order/freehosting configo, wired as an in-dashboard route (sibling of the zone/anycast configos) so the dashboard stays mounted. The domain is forwarded via selection.serviceName per the configo USAGE contract. Remove the now-dead manual order flow (initial/order free-hosting hooks, their API calls, the dns_zone config helper and types) and the orphaned translation keys across all locales. ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Hosting: drop useGenerateUrl (a hook) from the onClick handlers and build the path with a plain :serviceName substitution, for both the free-hosting and paid-hosting actions (Rules of Hooks) - freeHostingOrderComponent: anchor the direct-entry backUrl replace to the end of the URL (hash-router safe, preserves query) instead of a loose replace - freeHostingOrderModule: include hostAppName and the stable navbar?.backUrl in the mount effect deps (not the navbar object, which would remount every render) ref: #DCE-212 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 77 out of 77 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (5)
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.String.component.tsx:55
- Lowercasing the i18n key will break non-FR locales where the translation keys are still camelCase (e.g. Messages_pt_PT.json contains "domain_operations_update_firstName" but not "domain_operations_update_firstname"). Use a key fallback list (lowercase + original + legacy "key" variant) so existing translations keep working.
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.Me.Contact.component.tsx:67 - Lowercasing the translation key here will cause missing labels in locales that still use camelCase keys (e.g. "domain_operations_update_birthCity" vs requested "..._birthcity"). Consider providing a fallback to the original key instead of forcing lowercase.
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.Me.Contact.component.tsx:86 - Lowercasing this CTA i18n key will break locales that still expose camelCase variants (e.g. "..._whoisContactBilling"), leading to the raw key being displayed. Use a fallback list (lowercase + original) to keep backwards compatibility across locales.
packages/manager/apps/web-ongoing-operations/src/components/Update/Content/Update.Me.component.tsx:54 - Lowercasing the i18n key here will cause missing translations in locales that still use camelCase keys (e.g. "..._firstName_click"). Use a fallback (lowercase + original) so both key styles resolve.
packages/manager/apps/web-ongoing-operations/src/hooks/nichandle/useNichandle.tsx:16 user.authis accessed without a null-check. In other parts of the repo the code uses optional chaining for this field (e.g. container/.../UserDetails.tsx), so this can throw at runtime ifauthis missing. Consider falling back touser.nichandle(or empty string) whenauth.accountis unavailable.
| onClick: () => | ||
| navigateTo('billing', '/autorenew/services/cancel-resiliation', { | ||
| selectedType: DOMAIN, | ||
| serviceId: serviceName, | ||
| serviceType: DOMAIN, | ||
| searchText: serviceName, | ||
| serviceId: serviceInfo?.serviceId, | ||
| }), |
Description
Ticket Reference: #DCE-212