diff --git a/apps/client/src/common/components/copy-tag/CopyTag.tsx b/apps/client/src/common/components/copy-tag/CopyTag.tsx index 1464d1aec..0a556904d 100644 --- a/apps/client/src/common/components/copy-tag/CopyTag.tsx +++ b/apps/client/src/common/components/copy-tag/CopyTag.tsx @@ -1,5 +1,6 @@ -import { PropsWithChildren } from 'react'; +import { PropsWithChildren, useState } from 'react'; import { Button, ButtonGroup, IconButton, Tooltip } from '@chakra-ui/react'; +import { IoCheckmark } from '@react-icons/all-files/io5/IoCheckmark'; import { IoCopy } from '@react-icons/all-files/io5/IoCopy'; import { tooltipDelayFast } from '../../../ontimeConfig'; @@ -7,26 +8,34 @@ import { Size } from '../../models/Util.type'; import copyToClipboard from '../../utils/copyToClipboard'; interface CopyTagProps { + copyValue: string; label: string; - className?: string; size?: Size; disabled?: boolean; + onClick?: () => void; } export default function CopyTag(props: PropsWithChildren) { - const { label, className, size = 'xs', disabled, children } = props; + const { copyValue, label, size = 'xs', disabled, children, onClick } = props; + const [copied, setCopied] = useState(false); - const handleClick = () => copyToClipboard(children as string); + const handleClick = () => { + copyToClipboard(copyValue); + setCopied(true); + + // reset copied state + setTimeout(() => setCopied(false), 1000); + }; return ( - - } + icon={copied ? : } variant='ontime-filled' tabIndex={-1} onClick={handleClick} diff --git a/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.module.scss b/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.module.scss index ad787e0b9..cc8a7a1c4 100644 --- a/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.module.scss +++ b/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.module.scss @@ -4,3 +4,8 @@ gap: $section-spacing; row-gap: $element-inner-spacing; } + +.goIcon { + transform: rotate(45deg); + margin-left: 0.25rem; +} diff --git a/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx b/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx index c1915c7b8..3c3178f47 100644 --- a/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx +++ b/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx @@ -1,19 +1,33 @@ +import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp'; + import { serverPort } from '../../../../common/api/constants'; -import AppLink from '../../../../common/components/app-link/AppLink'; +import CopyTag from '../../../../common/components/copy-tag/CopyTag'; import useInfo from '../../../../common/hooks-query/useInfo'; +import { openLink } from '../../../../common/utils/linkUtils'; import style from './NetworkInterfaces.module.scss'; export default function InfoNif() { const { data } = useInfo(); + const handleClick = (address: string) => openLink(address); + return (
- {data?.networkInterfaces?.map((nif) => ( - - {`${nif.name} - ${nif.address}`} - - ))} + {data?.networkInterfaces?.map((nif) => { + const address = `http://${nif.address}:${serverPort}`; + + return ( + handleClick(address)} + label='Copy IP or navigate to address' + > + {`${nif.name} - ${nif.address}`} + + ); + })}
); } diff --git a/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx b/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx index c32dcce66..192663cea 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx +++ b/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx @@ -193,7 +193,7 @@ export default function GSheetSetup(props: GSheetSetupProps) {
{isAuthenticating && } - + {authKey ? authKey : 'Upload files to generate Auth Key'}
-
- {`/ontime/load/id "${event.id}"`} - {`/ontime/load/cue "${event.cue}"`} -
+ + + ); +} + +interface EventEditorFooterProps { + id: string; + cue: string; +} + +const EventEditorFooter = memo(_EventEditorFooter); + +function _EventEditorFooter(props: EventEditorFooterProps) { + const { id, cue } = props; + + const loadById = `/ontime/load/id "${id}"`; + const loadByCue = `/ontime/load/cue "${cue}"`; + + return ( +
+ + {loadById} + + + {loadByCue} +
); }