From 92a87cbda5f6a80345f72fa4c074bc569a107c0e Mon Sep 17 00:00:00 2001 From: anshengxu Date: Tue, 5 Mar 2024 11:14:12 +0800 Subject: [PATCH 1/7] ARC-2922 update copy button logic --- .../components/JenkinsSetup/JenkinsSetup.tsx | 114 ++++++++++++++---- 1 file changed, 91 insertions(+), 23 deletions(-) diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx index e94ffc2e..dca6c754 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx @@ -11,6 +11,7 @@ import Button, { ButtonGroup } from '@atlaskit/button'; import InfoIcon from '@atlaskit/icon/glyph/info'; import CopyIcon from '@atlaskit/icon/glyph/copy'; import OpenIcon from '@atlaskit/icon/glyph/open'; +import CheckIcon from '@atlaskit/icon/glyph/check'; import Tooltip from '@atlaskit/tooltip'; import { useHistory, useParams } from 'react-router'; import Spinner from '@atlaskit/spinner'; @@ -34,7 +35,6 @@ import { } from './JenkinsSetup.styles'; import { getJenkinsServerWithSecret } from '../../api/getJenkinsServerWithSecret'; import { serverNameFormOuterContainer } from '../ServerNameForm/ServerNameForm.styles'; -import { CopiedToClipboard } from '../CopiedToClipboard/CopiedToClipboard'; import { ConnectionFlowHeader } from '../ConnectionWizard/ConnectionFlowHeader'; import { SecretTokenContent, WebhookGuideContent } from '../CopiedToClipboard/CopyToClipboardContent'; import { getWebhookUrl } from '../../common/util/jenkinsConnectionsUtils'; @@ -52,60 +52,57 @@ const analyticsClient = new AnalyticsClient(); type CopyProps = { handleCopyToClipboard: (copyRef: React.RefObject, elementName?: string) => Promise | void; + setCopyButtonStateToTrue: (copyButton: CopyButtonNameEnum) => void; + copyButtonName: CopyButtonNameEnum; testId?: string }; const CopyButton = ({ handleCopyToClipboard, copyRef, + setCopyButtonStateToTrue, + copyButtonName, testId }: CopyProps & { copyRef: React.RefObject }): JSX.Element => { const [isCopied, setIsCopied] = useState(false); - useEffect(() => { - let timeoutId: NodeJS.Timeout; - if (isCopied) { - timeoutId = setTimeout(() => { - setIsCopied(false); - }, 2000); - } - return () => { - if (timeoutId) { - clearTimeout(timeoutId); - } - }; - }, [isCopied]); + const handleCopyFlow = () => { + setIsCopied(true); + setCopyButtonStateToTrue(copyButtonName); + }; return (
- - {isCopied && }
); }; type MyJenkinsAdminProps = { + handleCopyToClipboard: (copyRef: React.RefObject, elementName?: string) => Promise | void; + setCopyButtonStateToTrue: (copyButton: CopyButtonNameEnum) => void, webhookGuideRef: RefObject, secretTokenRef: RefObject }; const MyJenkinsAdmin = ({ handleCopyToClipboard, + setCopyButtonStateToTrue, webhookGuideRef, secretTokenRef -}: CopyProps & MyJenkinsAdminProps): JSX.Element => { +}: MyJenkinsAdminProps): JSX.Element => { const tooltipContent = 'Send this token separately to the webhook URL and step-by-step guide. It\'s best practice to use a secure channel like a password management tool.'; @@ -118,6 +115,8 @@ const MyJenkinsAdmin = ({ Webhook URL and step-by-step guide @@ -126,7 +125,11 @@ const MyJenkinsAdmin = ({ - + @@ -134,6 +137,8 @@ const MyJenkinsAdmin = ({ }; type IAmTheJenkinsAdminProps = { + handleCopyToClipboard: (copyRef: React.RefObject, elementName?: string) => Promise | void; + setCopyButtonStateToTrue: (copyButton: CopyButtonNameEnum) => void, siteNameRef: RefObject, webhookUrlRef: RefObject, secretRef: RefObject, @@ -141,10 +146,11 @@ type IAmTheJenkinsAdminProps = { const IAmTheJenkinsAdmin = ({ handleCopyToClipboard, + setCopyButtonStateToTrue, siteNameRef, webhookUrlRef, secretRef -}: CopyProps & IAmTheJenkinsAdminProps): JSX.Element => { +}: IAmTheJenkinsAdminProps): JSX.Element => { const handleFollowLink = async (e: React.MouseEvent): Promise => { e.preventDefault(); @@ -183,17 +189,25 @@ const IAmTheJenkinsAdmin = ({ Site name
  • Webhook URL
  • Secret - +
  • @@ -202,6 +216,14 @@ const IAmTheJenkinsAdmin = ({ ); }; +const enum CopyButtonNameEnum { + AdminSiteName = 'adminSiteName', + AdminWebhook = 'adminWebhook', + AdminSecret = 'adminSecret', + NonAdminWebhook = 'nonAdminWebhook', + NonAdminSecret = 'nonAdminSecret' +} + const JenkinsSetup = (): JSX.Element => { const history = useHistory(); const { path } = useParams(); @@ -214,6 +236,11 @@ const JenkinsSetup = (): JSX.Element => { const [serverName, setServerName] = useState(''); const [showMyJenkinsAdmin, setShowMyJenkinsAdmin] = useState(false); const [showIAmTheJenkinsAdmin, setShowIAmTheJenkinsAdmin] = useState(false); + const [isCopyAdminSiteName, setIsCopyAdminSiteName] = useState(false); + const [isCopyAdminWebhook, setIsCopyAdminWebhook] = useState(false); + const [isCopyAdminSecret, setIsCopyAdminSecret] = useState(false); + const [isCopyWebhook, setIsCopyWebhook] = useState(false); + const [isCopySecret, setIsCopySecret] = useState(false); const [webhookUrl, setWebhookUrl] = useState(''); const [secret, setSecret] = useState(''); const [siteName, setSiteName] = useState(''); @@ -252,6 +279,36 @@ const JenkinsSetup = (): JSX.Element => { fetchData(); }, [uuid, getServer]); + const setCopiedButtonStateToTrue = (copyButtonName: CopyButtonNameEnum) => { + switch (copyButtonName) { + case CopyButtonNameEnum.AdminSiteName: + setIsCopyAdminSiteName(true); + break; + case CopyButtonNameEnum.AdminWebhook: + setIsCopyAdminWebhook(true); + break; + case CopyButtonNameEnum.AdminSecret: + setIsCopyAdminSecret(true); + break; + case CopyButtonNameEnum.NonAdminWebhook: + setIsCopyWebhook(true); + break; + case CopyButtonNameEnum.NonAdminSecret: + setIsCopySecret(true); + break; + default: + break; + } + }; + + const clearCopiedButtonStates = () => { + setIsCopyAdminSiteName(false); + setIsCopyAdminWebhook(false); + setIsCopyAdminSecret(false); + setIsCopyWebhook(false); + setIsCopySecret(false); + }; + const handleCopyToClipboard = async (copyRef: React.RefObject, elementName?: string) => { if (copyRef.current) { @@ -290,6 +347,9 @@ const JenkinsSetup = (): JSX.Element => { const handleMyJenkinsAdminClick = async (e: React.MouseEvent) => { e.preventDefault(); + if (!showMyJenkinsAdmin) { + clearCopiedButtonStates(); + } setShowMyJenkinsAdmin(true); setShowIAmTheJenkinsAdmin(false); @@ -306,6 +366,9 @@ const JenkinsSetup = (): JSX.Element => { const handleIAmTheJenkinsAdminClick = async (e: React.MouseEvent) => { e.preventDefault(); + if (!showIAmTheJenkinsAdmin) { + clearCopiedButtonStates(); + } setShowIAmTheJenkinsAdmin(true); setShowMyJenkinsAdmin(false); @@ -343,6 +406,8 @@ const JenkinsSetup = (): JSX.Element => { const isFetchingData = !serverName || !webhookUrl || !secret; + const enableFinishButton = (isCopyAdminSecret && isCopyAdminSiteName && isCopyAdminWebhook) || + (isCopySecret && isCopyWebhook); return (
    @@ -391,6 +456,7 @@ const JenkinsSetup = (): JSX.Element => { {showMyJenkinsAdmin ? ( @@ -399,6 +465,7 @@ const JenkinsSetup = (): JSX.Element => { {showIAmTheJenkinsAdmin ? ( { + {showIsCopiedClipBoard && }
    ); }; @@ -90,14 +110,16 @@ type MyJenkinsAdminProps = { handleCopyToClipboard: (copyRef: React.RefObject, elementName?: string) => Promise | void; setCopyButtonStateToTrue: (copyButton: CopyButtonNameEnum) => void, webhookGuideRef: RefObject, - secretTokenRef: RefObject + secretTokenRef: RefObject, + primaryButtonName: CopyButtonNameEnum, }; const MyJenkinsAdmin = ({ handleCopyToClipboard, setCopyButtonStateToTrue, webhookGuideRef, - secretTokenRef + secretTokenRef, + primaryButtonName }: MyJenkinsAdminProps): JSX.Element => { const tooltipContent = 'Send this token separately to the webhook URL and step-by-step guide. It\'s best practice to use a secure channel like a password management tool.'; @@ -112,6 +134,7 @@ const MyJenkinsAdmin = ({ @@ -124,6 +147,7 @@ const MyJenkinsAdmin = ({ @@ -138,6 +162,7 @@ type IAmTheJenkinsAdminProps = { siteNameRef: RefObject, webhookUrlRef: RefObject, secretRef: RefObject, + primaryButtonName: CopyButtonNameEnum, }; const IAmTheJenkinsAdmin = ({ @@ -145,7 +170,8 @@ const IAmTheJenkinsAdmin = ({ setCopyButtonStateToTrue, siteNameRef, webhookUrlRef, - secretRef + secretRef, + primaryButtonName }: IAmTheJenkinsAdminProps): JSX.Element => { const handleFollowLink = async (e: React.MouseEvent): Promise => { e.preventDefault(); @@ -186,6 +212,7 @@ const IAmTheJenkinsAdmin = ({ @@ -194,6 +221,7 @@ const IAmTheJenkinsAdmin = ({ @@ -202,6 +230,7 @@ const IAmTheJenkinsAdmin = ({ @@ -241,6 +270,8 @@ const JenkinsSetup = (): JSX.Element => { const [secret, setSecret] = useState(''); const [siteName, setSiteName] = useState(''); const [globalPageUrl, setGlobalPageUrl] = useState(''); + const [primaryCopyButtonName, setPrimaryCopyButtonName] = + useState(CopyButtonNameEnum.NonAdminWebhook); const connectionSettings = settings === 'connection-settings'; const getServer = useCallback(async () => { @@ -279,15 +310,28 @@ const JenkinsSetup = (): JSX.Element => { switch (copyButtonName) { case CopyButtonNameEnum.AdminSiteName: setIsCopyAdminSiteName(true); + if (!isCopyAdminWebhook) { + setPrimaryCopyButtonName(CopyButtonNameEnum.AdminWebhook); + } else if (!isCopyAdminSecret) { + setPrimaryCopyButtonName(CopyButtonNameEnum.AdminSecret); + } break; case CopyButtonNameEnum.AdminWebhook: setIsCopyAdminWebhook(true); + if (!isCopyAdminSiteName) { + setPrimaryCopyButtonName(CopyButtonNameEnum.AdminSiteName); + } else if (!isCopyAdminSecret) { + setPrimaryCopyButtonName(CopyButtonNameEnum.AdminSecret); + } break; case CopyButtonNameEnum.AdminSecret: setIsCopyAdminSecret(true); break; case CopyButtonNameEnum.NonAdminWebhook: setIsCopyNonAdminWebhook(true); + if (!isCopyNonAdminSecret) { + setPrimaryCopyButtonName(CopyButtonNameEnum.NonAdminSecret); + } break; case CopyButtonNameEnum.NonAdminSecret: setIsCopyNonAdminSecret(true); @@ -345,6 +389,7 @@ const JenkinsSetup = (): JSX.Element => { if (!showMyJenkinsAdmin) { clearCopiedButtonStates(); + setPrimaryCopyButtonName(CopyButtonNameEnum.NonAdminWebhook); } setShowMyJenkinsAdmin(true); setShowIAmTheJenkinsAdmin(false); @@ -364,6 +409,7 @@ const JenkinsSetup = (): JSX.Element => { if (!showIAmTheJenkinsAdmin) { clearCopiedButtonStates(); + setPrimaryCopyButtonName(CopyButtonNameEnum.AdminSiteName); } setShowIAmTheJenkinsAdmin(true); setShowMyJenkinsAdmin(false); @@ -453,6 +499,7 @@ const JenkinsSetup = (): JSX.Element => { @@ -462,6 +509,7 @@ const JenkinsSetup = (): JSX.Element => { Date: Wed, 6 Mar 2024 09:56:59 +0800 Subject: [PATCH 4/7] address PR review --- .../components/JenkinsSetup/JenkinsSetup.tsx | 100 ++++++++++-------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx index c74d3e12..17af3bbd 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx @@ -135,7 +135,7 @@ const MyJenkinsAdmin = ({ handleCopyToClipboard={handleCopyToClipboard} setCopyButtonStateToTrue={setCopyButtonStateToTrue} primaryButtonName={primaryButtonName} - copyButtonName={CopyButtonNameEnum.NonAdminWebhook} + copyButtonName="nonAdminWebhook" copyRef={webhookGuideRef} testId="copy-webhook-url-guide" /> @@ -148,7 +148,7 @@ const MyJenkinsAdmin = ({ handleCopyToClipboard={handleCopyToClipboard} setCopyButtonStateToTrue={setCopyButtonStateToTrue} primaryButtonName={primaryButtonName} - copyButtonName={CopyButtonNameEnum.NonAdminSecret} + copyButtonName="nonAdminSecret" copyRef={secretTokenRef} testId="copy-secret-token-guide" /> @@ -213,7 +213,7 @@ const IAmTheJenkinsAdmin = ({ handleCopyToClipboard={handleCopyToClipboard} setCopyButtonStateToTrue={setCopyButtonStateToTrue} primaryButtonName={primaryButtonName} - copyButtonName={CopyButtonNameEnum.AdminSiteName} + copyButtonName="adminSiteName" copyRef={siteNameRef} testId="site-name-copy-button" />
  • @@ -222,7 +222,7 @@ const IAmTheJenkinsAdmin = ({ handleCopyToClipboard={handleCopyToClipboard} setCopyButtonStateToTrue={setCopyButtonStateToTrue} primaryButtonName={primaryButtonName} - copyButtonName={CopyButtonNameEnum.AdminWebhook} + copyButtonName="adminWebhook" copyRef={webhookUrlRef} testId="copy-webhook-url" />
  • @@ -231,7 +231,7 @@ const IAmTheJenkinsAdmin = ({ handleCopyToClipboard={handleCopyToClipboard} setCopyButtonStateToTrue={setCopyButtonStateToTrue} primaryButtonName={primaryButtonName} - copyButtonName={CopyButtonNameEnum.AdminSecret} + copyButtonName="adminSecret" copyRef={secretRef} testId="copy-secret-token" />
  • @@ -241,13 +241,7 @@ const IAmTheJenkinsAdmin = ({ ); }; -const enum CopyButtonNameEnum { - AdminSiteName = 'adminSiteName', - AdminWebhook = 'adminWebhook', - AdminSecret = 'adminSecret', - NonAdminWebhook = 'nonAdminWebhook', - NonAdminSecret = 'nonAdminSecret' -} +type CopyButtonNameEnum = 'adminSiteName' | 'adminWebhook' | 'adminSecret' | 'nonAdminWebhook' | 'nonAdminSecret'; const JenkinsSetup = (): JSX.Element => { const history = useHistory(); @@ -261,19 +255,28 @@ const JenkinsSetup = (): JSX.Element => { const [serverName, setServerName] = useState(''); const [showMyJenkinsAdmin, setShowMyJenkinsAdmin] = useState(false); const [showIAmTheJenkinsAdmin, setShowIAmTheJenkinsAdmin] = useState(false); - const [isCopyAdminSiteName, setIsCopyAdminSiteName] = useState(false); - const [isCopyAdminWebhook, setIsCopyAdminWebhook] = useState(false); - const [isCopyAdminSecret, setIsCopyAdminSecret] = useState(false); - const [isCopyNonAdminWebhook, setIsCopyNonAdminWebhook] = useState(false); - const [isCopyNonAdminSecret, setIsCopyNonAdminSecret] = useState(false); + const [copyButtonStates, setCopyButtonStates] = useState({ + isCopyAdminSiteName: false, + isCopyAdminWebhook: false, + isCopyAdminSecret: false, + isCopyNonAdminWebhook: false, + isCopyNonAdminSecret: false + }); const [webhookUrl, setWebhookUrl] = useState(''); const [secret, setSecret] = useState(''); const [siteName, setSiteName] = useState(''); const [globalPageUrl, setGlobalPageUrl] = useState(''); const [primaryCopyButtonName, setPrimaryCopyButtonName] = - useState(CopyButtonNameEnum.NonAdminWebhook); + useState('nonAdminWebhook'); const connectionSettings = settings === 'connection-settings'; + const updateCopyButtonState = (key: string, newValue: boolean) => { + setCopyButtonStates((prevState) => ({ + ...prevState, + [key]: newValue + })); + }; + const getServer = useCallback(async () => { try { const { name, secret: retrievedSecret } = await getJenkinsServerWithSecret(uuid); @@ -308,33 +311,33 @@ const JenkinsSetup = (): JSX.Element => { const setCopiedButtonStateToTrue = (copyButtonName: CopyButtonNameEnum) => { switch (copyButtonName) { - case CopyButtonNameEnum.AdminSiteName: - setIsCopyAdminSiteName(true); - if (!isCopyAdminWebhook) { - setPrimaryCopyButtonName(CopyButtonNameEnum.AdminWebhook); - } else if (!isCopyAdminSecret) { - setPrimaryCopyButtonName(CopyButtonNameEnum.AdminSecret); + case 'adminSiteName': + updateCopyButtonState('isCopyAdminSiteName', true); + if (!copyButtonStates.isCopyAdminWebhook) { + setPrimaryCopyButtonName('adminWebhook'); + } else if (!copyButtonStates.isCopyAdminSecret) { + setPrimaryCopyButtonName('adminSecret'); } break; - case CopyButtonNameEnum.AdminWebhook: - setIsCopyAdminWebhook(true); - if (!isCopyAdminSiteName) { - setPrimaryCopyButtonName(CopyButtonNameEnum.AdminSiteName); - } else if (!isCopyAdminSecret) { - setPrimaryCopyButtonName(CopyButtonNameEnum.AdminSecret); + case 'adminWebhook': + updateCopyButtonState('isCopyAdminWebhook', true); + if (!copyButtonStates.isCopyAdminSiteName) { + setPrimaryCopyButtonName('adminSiteName'); + } else if (!copyButtonStates.isCopyAdminSecret) { + setPrimaryCopyButtonName('adminSecret'); } break; - case CopyButtonNameEnum.AdminSecret: - setIsCopyAdminSecret(true); + case 'adminSecret': + updateCopyButtonState('isCopyAdminSecret', true); break; - case CopyButtonNameEnum.NonAdminWebhook: - setIsCopyNonAdminWebhook(true); - if (!isCopyNonAdminSecret) { - setPrimaryCopyButtonName(CopyButtonNameEnum.NonAdminSecret); + case 'nonAdminWebhook': + updateCopyButtonState('isCopyNonAdminWebhook', true); + if (!copyButtonStates.isCopyNonAdminSecret) { + setPrimaryCopyButtonName('nonAdminSecret'); } break; - case CopyButtonNameEnum.NonAdminSecret: - setIsCopyNonAdminSecret(true); + case 'nonAdminSecret': + updateCopyButtonState('isCopyNonAdminSecret', true); break; default: break; @@ -342,11 +345,13 @@ const JenkinsSetup = (): JSX.Element => { }; const clearCopiedButtonStates = () => { - setIsCopyAdminSiteName(false); - setIsCopyAdminWebhook(false); - setIsCopyAdminSecret(false); - setIsCopyNonAdminWebhook(false); - setIsCopyNonAdminSecret(false); + setCopyButtonStates({ + isCopyAdminSiteName: false, + isCopyAdminWebhook: false, + isCopyAdminSecret: false, + isCopyNonAdminWebhook: false, + isCopyNonAdminSecret: false + }); }; const handleCopyToClipboard = @@ -389,7 +394,7 @@ const JenkinsSetup = (): JSX.Element => { if (!showMyJenkinsAdmin) { clearCopiedButtonStates(); - setPrimaryCopyButtonName(CopyButtonNameEnum.NonAdminWebhook); + setPrimaryCopyButtonName('nonAdminWebhook'); } setShowMyJenkinsAdmin(true); setShowIAmTheJenkinsAdmin(false); @@ -409,7 +414,7 @@ const JenkinsSetup = (): JSX.Element => { if (!showIAmTheJenkinsAdmin) { clearCopiedButtonStates(); - setPrimaryCopyButtonName(CopyButtonNameEnum.AdminSiteName); + setPrimaryCopyButtonName('adminSiteName'); } setShowIAmTheJenkinsAdmin(true); setShowMyJenkinsAdmin(false); @@ -448,8 +453,9 @@ const JenkinsSetup = (): JSX.Element => { const isFetchingData = !serverName || !webhookUrl || !secret; - const enableFinishButton = (isCopyAdminSecret && isCopyAdminSiteName && isCopyAdminWebhook) || - (isCopyNonAdminSecret && isCopyNonAdminWebhook); + const enableFinishButton = (copyButtonStates.isCopyAdminSecret && copyButtonStates.isCopyAdminSiteName && + copyButtonStates.isCopyAdminWebhook) || (copyButtonStates.isCopyNonAdminSecret && + copyButtonStates.isCopyNonAdminWebhook); return (
    From 9940ce2c781ddbbf072ca9ddeb35549a86f2d617 Mon Sep 17 00:00:00 2001 From: anshengxu Date: Wed, 6 Mar 2024 12:14:48 +0800 Subject: [PATCH 5/7] address pr review again --- .../components/JenkinsSetup/JenkinsSetup.tsx | 119 +++++++++--------- 1 file changed, 62 insertions(+), 57 deletions(-) diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx index 17af3bbd..56811839 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsSetup/JenkinsSetup.tsx @@ -243,7 +243,23 @@ const IAmTheJenkinsAdmin = ({ type CopyButtonNameEnum = 'adminSiteName' | 'adminWebhook' | 'adminSecret' | 'nonAdminWebhook' | 'nonAdminSecret'; +interface CopyButtonMetadata { + name: CopyButtonNameEnum; + isClicked: boolean; +} + const JenkinsSetup = (): JSX.Element => { + const initialAdminButtonStates: CopyButtonMetadata[] = [ + { name: 'adminSiteName', isClicked: false }, + { name: 'adminWebhook', isClicked: false }, + { name: 'adminSecret', isClicked: false } + ]; + + const initialNonAdminButtonStates: CopyButtonMetadata[] = [ + { name: 'nonAdminWebhook', isClicked: false }, + { name: 'nonAdminSecret', isClicked: false } + ]; + const history = useHistory(); const { path } = useParams(); const webhookGuideRef = useRef(null); @@ -255,13 +271,9 @@ const JenkinsSetup = (): JSX.Element => { const [serverName, setServerName] = useState(''); const [showMyJenkinsAdmin, setShowMyJenkinsAdmin] = useState(false); const [showIAmTheJenkinsAdmin, setShowIAmTheJenkinsAdmin] = useState(false); - const [copyButtonStates, setCopyButtonStates] = useState({ - isCopyAdminSiteName: false, - isCopyAdminWebhook: false, - isCopyAdminSecret: false, - isCopyNonAdminWebhook: false, - isCopyNonAdminSecret: false - }); + const [copyAdminButtonStates, setCopyAdminButtonStates] = useState(initialAdminButtonStates); + const [copyNonAdminButtonStates, setCopyNonAdminButtonStates] = + useState(initialNonAdminButtonStates); const [webhookUrl, setWebhookUrl] = useState(''); const [secret, setSecret] = useState(''); const [siteName, setSiteName] = useState(''); @@ -270,11 +282,24 @@ const JenkinsSetup = (): JSX.Element => { useState('nonAdminWebhook'); const connectionSettings = settings === 'connection-settings'; - const updateCopyButtonState = (key: string, newValue: boolean) => { - setCopyButtonStates((prevState) => ({ - ...prevState, - [key]: newValue - })); + const updateAdminCopyButtonState = (key: CopyButtonNameEnum, isClicked: boolean) => { + const existingItemIndex = copyAdminButtonStates.findIndex((item) => item.name === key); + + if (existingItemIndex !== -1) { + const updatedButtons = [...copyAdminButtonStates]; + updatedButtons[existingItemIndex].isClicked = isClicked; + setCopyAdminButtonStates(updatedButtons); + } + }; + + const updateNonAdminCopyButtonState = (key: CopyButtonNameEnum, isClicked: boolean) => { + const existingItemIndex = copyNonAdminButtonStates.findIndex((item) => item.name === key); + + if (existingItemIndex !== -1) { + const updatedButtons = [...copyNonAdminButtonStates]; + updatedButtons[existingItemIndex].isClicked = isClicked; + setCopyNonAdminButtonStates(updatedButtons); + } }; const getServer = useCallback(async () => { @@ -309,49 +334,29 @@ const JenkinsSetup = (): JSX.Element => { fetchData(); }, [uuid, getServer]); - const setCopiedButtonStateToTrue = (copyButtonName: CopyButtonNameEnum) => { - switch (copyButtonName) { - case 'adminSiteName': - updateCopyButtonState('isCopyAdminSiteName', true); - if (!copyButtonStates.isCopyAdminWebhook) { - setPrimaryCopyButtonName('adminWebhook'); - } else if (!copyButtonStates.isCopyAdminSecret) { - setPrimaryCopyButtonName('adminSecret'); - } - break; - case 'adminWebhook': - updateCopyButtonState('isCopyAdminWebhook', true); - if (!copyButtonStates.isCopyAdminSiteName) { - setPrimaryCopyButtonName('adminSiteName'); - } else if (!copyButtonStates.isCopyAdminSecret) { - setPrimaryCopyButtonName('adminSecret'); - } - break; - case 'adminSecret': - updateCopyButtonState('isCopyAdminSecret', true); - break; - case 'nonAdminWebhook': - updateCopyButtonState('isCopyNonAdminWebhook', true); - if (!copyButtonStates.isCopyNonAdminSecret) { - setPrimaryCopyButtonName('nonAdminSecret'); - } - break; - case 'nonAdminSecret': - updateCopyButtonState('isCopyNonAdminSecret', true); - break; - default: - break; + const findNextPrimaryButtonIndex = (buttonStates: CopyButtonMetadata[]) => { + return buttonStates.findIndex((item) => item.isClicked === false); + }; + + const setAdminCopiedButtonStateToTrue = (copyButtonName: CopyButtonNameEnum) => { + updateAdminCopyButtonState(copyButtonName, true); + const nextPrimaryButtonIndex = findNextPrimaryButtonIndex(copyAdminButtonStates); + if (nextPrimaryButtonIndex !== -1) { + setPrimaryCopyButtonName(copyAdminButtonStates[nextPrimaryButtonIndex].name); + } + }; + + const setNonAdminCopiedButtonStateToTrue = (copyButtonName: CopyButtonNameEnum) => { + updateNonAdminCopyButtonState(copyButtonName, true); + const nextPrimaryButtonIndex = findNextPrimaryButtonIndex(copyNonAdminButtonStates); + if (nextPrimaryButtonIndex !== -1) { + setPrimaryCopyButtonName(copyNonAdminButtonStates[nextPrimaryButtonIndex].name); } }; const clearCopiedButtonStates = () => { - setCopyButtonStates({ - isCopyAdminSiteName: false, - isCopyAdminWebhook: false, - isCopyAdminSecret: false, - isCopyNonAdminWebhook: false, - isCopyNonAdminSecret: false - }); + setCopyAdminButtonStates(initialAdminButtonStates); + setCopyNonAdminButtonStates(initialNonAdminButtonStates); }; const handleCopyToClipboard = @@ -453,9 +458,9 @@ const JenkinsSetup = (): JSX.Element => { const isFetchingData = !serverName || !webhookUrl || !secret; - const enableFinishButton = (copyButtonStates.isCopyAdminSecret && copyButtonStates.isCopyAdminSiteName && - copyButtonStates.isCopyAdminWebhook) || (copyButtonStates.isCopyNonAdminSecret && - copyButtonStates.isCopyNonAdminWebhook); + const isAllRequiredButtonsClicked = copyAdminButtonStates.every((button) => button.isClicked) || + (copyNonAdminButtonStates.every((button) => button.isClicked)); + return (
    @@ -504,7 +509,7 @@ const JenkinsSetup = (): JSX.Element => { {showMyJenkinsAdmin ? ( { {showIAmTheJenkinsAdmin ? ( { - {showIsCopiedClipBoard && } + {showIsCopiedToClipboardTooltip && }
    ); };