fix(striker-ui): allow open VNC connection in new tab from dashboard

main
Tsu-ba-me 1 year ago
parent f56cf55f04
commit 1d606ea20d
  1. 70
      striker-ui/components/Display/Preview.tsx
  2. 17
      striker-ui/pages/index.tsx

@ -27,6 +27,7 @@ type PreviewOptionalProps = {
externalPreview?: string; externalPreview?: string;
externalTimestamp?: number; externalTimestamp?: number;
headerEndAdornment?: ReactNode; headerEndAdornment?: ReactNode;
hrefPreview?: string;
isExternalLoading?: boolean; isExternalLoading?: boolean;
isExternalPreviewStale?: boolean; isExternalPreviewStale?: boolean;
isFetchPreview?: boolean; isFetchPreview?: boolean;
@ -43,12 +44,19 @@ type PreviewProps = PreviewOptionalProps & {
}; };
const PREVIEW_DEFAULT_PROPS: Required< const PREVIEW_DEFAULT_PROPS: Required<
Omit<PreviewOptionalProps, 'onClickConnectButton' | 'onClickPreview'> Omit<
PreviewOptionalProps,
'hrefPreview' | 'onClickConnectButton' | 'onClickPreview'
>
> & > &
Pick<PreviewOptionalProps, 'onClickConnectButton' | 'onClickPreview'> = { Pick<
PreviewOptionalProps,
'hrefPreview' | 'onClickConnectButton' | 'onClickPreview'
> = {
externalPreview: '', externalPreview: '',
externalTimestamp: 0, externalTimestamp: 0,
headerEndAdornment: null, headerEndAdornment: null,
hrefPreview: undefined,
isExternalLoading: false, isExternalLoading: false,
isExternalPreviewStale: false, isExternalPreviewStale: false,
isFetchPreview: true, isFetchPreview: true,
@ -90,6 +98,7 @@ const Preview: FC<PreviewProps> = ({
externalPreview = PREVIEW_DEFAULT_PROPS.externalPreview, externalPreview = PREVIEW_DEFAULT_PROPS.externalPreview,
externalTimestamp = PREVIEW_DEFAULT_PROPS.externalTimestamp, externalTimestamp = PREVIEW_DEFAULT_PROPS.externalTimestamp,
headerEndAdornment, headerEndAdornment,
hrefPreview,
isExternalLoading = PREVIEW_DEFAULT_PROPS.isExternalLoading, isExternalLoading = PREVIEW_DEFAULT_PROPS.isExternalLoading,
isExternalPreviewStale = PREVIEW_DEFAULT_PROPS.isExternalPreviewStale, isExternalPreviewStale = PREVIEW_DEFAULT_PROPS.isExternalPreviewStale,
isFetchPreview = PREVIEW_DEFAULT_PROPS.isFetchPreview, isFetchPreview = PREVIEW_DEFAULT_PROPS.isFetchPreview,
@ -153,6 +162,44 @@ const Preview: FC<PreviewProps> = ({
], ],
); );
const iconButton = useMemo(() => {
if (isPreviewLoading) {
return <Spinner mb="1em" mt="1em" />;
}
const disabled = !preview;
const sx: MUIIconButtonProps['sx'] = {
borderRadius: BORDER_RADIUS,
color: GREY,
padding: 0,
};
if (hrefPreview) {
return (
<MUIIconButton disabled={disabled} href={hrefPreview} sx={sx}>
{previewButtonContent}
</MUIIconButton>
);
}
return (
<MUIIconButton
component="span"
disabled={disabled}
onClick={previewClickHandler}
sx={sx}
>
{previewButtonContent}
</MUIIconButton>
);
}, [
hrefPreview,
isPreviewLoading,
preview,
previewButtonContent,
previewClickHandler,
]);
useEffect(() => { useEffect(() => {
if (isFetchPreview) { if (isFetchPreview) {
(async () => { (async () => {
@ -195,24 +242,7 @@ const Preview: FC<PreviewProps> = ({
</PreviewPanelHeader> </PreviewPanelHeader>
<FlexBox row sx={{ '& > :first-child': { flexGrow: 1 } }}> <FlexBox row sx={{ '& > :first-child': { flexGrow: 1 } }}>
{/* Box wrapper below is required to keep external preview size sane. */} {/* Box wrapper below is required to keep external preview size sane. */}
<Box textAlign="center"> <Box textAlign="center">{iconButton}</Box>
{isPreviewLoading ? (
<Spinner mt="1em" mb="1em" />
) : (
<MUIIconButton
component="span"
disabled={!preview}
onClick={previewClickHandler}
sx={{
borderRadius: BORDER_RADIUS,
color: GREY,
padding: 0,
}}
>
{previewButtonContent}
</MUIIconButton>
)}
</Box>
{isShowControls && preview && ( {isShowControls && preview && (
<FlexBox> <FlexBox>
<IconButton onClick={connectButtonClickHandle}> <IconButton onClick={connectButtonClickHandle}>

@ -1,7 +1,6 @@
import { Add as AddIcon } from '@mui/icons-material'; import { Add as AddIcon } from '@mui/icons-material';
import { Box, Divider, Grid } from '@mui/material'; import { Box, Divider, Grid } from '@mui/material';
import Head from 'next/head'; import Head from 'next/head';
import { NextRouter, useRouter } from 'next/router';
import { FC, useEffect, useRef, useState } from 'react'; import { FC, useEffect, useRef, useState } from 'react';
import API_BASE_URL from '../lib/consts/API_BASE_URL'; import API_BASE_URL from '../lib/consts/API_BASE_URL';
@ -28,10 +27,7 @@ type ServerListItem = ServerOverviewMetadata & {
timestamp: number; timestamp: number;
}; };
const createServerPreviewContainer = ( const createServerPreviewContainer = (servers: ServerListItem[]) => (
servers: ServerListItem[],
router: NextRouter,
) => (
<Grid <Grid
alignContent="stretch" alignContent="stretch"
columns={{ xs: 1, sm: 2, md: 3, xl: 4 }} columns={{ xs: 1, sm: 2, md: 3, xl: 4 }}
@ -84,16 +80,12 @@ const createServerPreviewContainer = (
{anvilName} {anvilName}
</Link>, </Link>,
]} ]}
hrefPreview={`/server?uuid=${serverUUID}&server_name=${serverName}&server_state=${serverState}&vnc=1`}
isExternalLoading={loading} isExternalLoading={loading}
isExternalPreviewStale={isScreenshotStale} isExternalPreviewStale={isScreenshotStale}
isFetchPreview={false} isFetchPreview={false}
isShowControls={false} isShowControls={false}
isUseInnerPanel isUseInnerPanel
onClickPreview={() => {
router.push(
`/server?uuid=${serverUUID}&server_name=${serverName}&server_state=${serverState}&vnc=1`,
);
}}
serverState={serverState} serverState={serverState}
serverUUID={serverUUID} serverUUID={serverUUID}
/> />
@ -129,7 +121,6 @@ const filterServers = (allServers: ServerListItem[], searchTerm: string) =>
const Dashboard: FC = () => { const Dashboard: FC = () => {
const componentMountedRef = useRef(true); const componentMountedRef = useRef(true);
const router = useRouter();
const [allServers, setAllServers] = useState<ServerListItem[]>([]); const [allServers, setAllServers] = useState<ServerListItem[]>([]);
const [excludeServers, setExcludeServers] = useState<ServerListItem[]>([]); const [excludeServers, setExcludeServers] = useState<ServerListItem[]>([]);
@ -244,11 +235,11 @@ const Dashboard: FC = () => {
value={inputSearchTerm} value={inputSearchTerm}
/> />
</PanelHeader> </PanelHeader>
{createServerPreviewContainer(includeServers, router)} {createServerPreviewContainer(includeServers)}
{includeServers.length > 0 && ( {includeServers.length > 0 && (
<Divider sx={{ backgroundColor: DIVIDER }} /> <Divider sx={{ backgroundColor: DIVIDER }} />
)} )}
{createServerPreviewContainer(excludeServers, router)} {createServerPreviewContainer(excludeServers)}
</> </>
)} )}
</Panel> </Panel>

Loading…
Cancel
Save