import React, { useState } from 'react'; import { DismissibleAlert } from '../../components/ui/dismissible-alert'; import { Text } from '../../components/ui/text'; import { Spinner } from '../../components/ui/spinner'; import { detachInstallationCode } from '../../utils/wpAdminApi'; /** * LETTING GO OF A PRACTICE, AND IT HAS TO EXIST FOR THE REFUSAL BESIDE IT TO BE HONEST. * * `adopt_handover_code` refuses to re-point a site that already holds a code, because silently moving a * working install onto another organization's record is the disclosure that whole mechanism is arranged * to avoid. That refusal only stands up if there is a separate door out - otherwise a practice that * pasted the wrong code once is stuck with it and the only way back is editing the database. * * A DELIBERATE, SEPARATE ACT - NEVER A SIDE EFFECT OF ADOPTING. The server takes a distinct action name * for exactly that reason, so re-pointing a site can never happen inside a request somebody thought was * an adopt. * * IT ONLY APPEARS FOR A SITE RUNNING AN ADOPTED CODE, which is why the caller checks the shape rather * than this component doing it. A site running its own generated id has nothing to let go of, and * offering the control anyway would invite somebody to disconnect a practice that was never connected. */ const DetachInstallationCode: React.FC<{ code: string }> = ({ code }) => { const [confirming, setConfirming] = useState(false); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const detach = async () => { if (busy) return; setBusy(true); setError(null); const outcome = await detachInstallationCode(); if (outcome.ok) { /* * A FULL RELOAD, for the same reason adopting does one: the organization is resolved ONCE at * boot from this option. Anything short of starting again leaves a disconnected site still * rendering the practice it just let go of. */ window.location.reload(); return; } setBusy(false); setError( outcome.reason === 'not-adopted' ? 'This site is running its own installation id, so there is nothing to disconnect.' : 'That could not be sent to WordPress. Nothing on this site was changed - check your ' + 'connection and try again.', ); }; return (
{/* The code connects any site to the practice, so only its tail is shown to tell codes apart. */} This site is connected to a practice that was set up elsewhere, using the code ending in{' '} {code.slice(-4)}. {!confirming ? ( /* * TWO STEPS, because this is the destructive direction. Adopting a code is recoverable - * detach and adopt the right one - while detaching costs the code itself: it was shown * once on a console the contractor has long since navigated away from. */ ) : ( <> The practice and everything in it is untouched - this only stops THIS website pointing at it. To connect it again you will need the same code, and it is not re-issued, so make sure you still have it. )} {error && ( {error} )}
); }; export default DetachInstallationCode;