refactor: extract common dialog component

Signed-off-by: Jamie Klassen <jamie.klassen@broadcom.com>
This commit is contained in:
Jamie Klassen
2024-01-26 19:09:50 -05:00
parent f6c0fc32dc
commit 3c184afa91
6 changed files with 157 additions and 135 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes-react': patch
---
Extracted common dialog component.
+1 -1
View File
@@ -685,7 +685,7 @@ export const PodExecTerminal: (
// @public
export const PodExecTerminalDialog: (
props: PodExecTerminalProps,
) => React_2.JSX.Element;
) => false | React_2.JSX.Element | undefined;
// @public
export interface PodExecTerminalProps {
@@ -0,0 +1,110 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
Button,
Dialog,
DialogContent,
DialogTitle,
IconButton,
Theme,
createStyles,
makeStyles,
} from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';
import React, { useState } from 'react';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
dialogPaper: { minHeight: 'calc(100% - 64px)' },
dialogContent: { flexBasis: 0 },
closeButton: {
position: 'absolute',
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500],
},
}),
);
export interface KubernetesDialogProps {
buttonAriaLabel: string;
buttonIcon: React.ReactNode;
buttonText: string;
children?: React.ReactNode;
disabled?: boolean;
title: string;
}
/**
* Dialog component for use in the Kubernetes plugin
*
* @public
*/
export const KubernetesDialog = ({
buttonAriaLabel,
buttonIcon,
buttonText,
children,
disabled,
title,
}: KubernetesDialogProps) => {
const classes = useStyles();
const [open, setOpen] = useState(false);
const openDialog = () => {
setOpen(true);
};
const closeDialog = () => {
setOpen(false);
};
return (
<>
<Dialog
maxWidth="xl"
fullWidth
open={open}
onClose={closeDialog}
PaperProps={{ className: classes.dialogPaper }}
>
<DialogTitle id="dialog-title">
{title}
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={closeDialog}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent className={classes.dialogContent}>
{children}
</DialogContent>
</Dialog>
<Button
variant="outlined"
aria-label={buttonAriaLabel}
component="label"
disabled={disabled}
onClick={openDialog}
startIcon={buttonIcon}
>
{buttonText}
</Button>
</>
);
};
@@ -0,0 +1,16 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './KubernetesDialog';
@@ -13,98 +13,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
Button,
createStyles,
Dialog,
DialogContent,
DialogTitle,
IconButton,
makeStyles,
Theme,
} from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';
import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser';
import React, { useState } from 'react';
import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser';
import React from 'react';
import { KubernetesDialog } from '../KubernetesDialog';
import { useIsPodExecTerminalSupported } from '../../hooks';
import { PodExecTerminal, PodExecTerminalProps } from './PodExecTerminal';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
dialogPaper: { minHeight: 'calc(100% - 64px)' },
dialogContent: { flexBasis: 0 },
closeButton: {
position: 'absolute',
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500],
},
}),
);
/**
* Opens a terminal connected to the given pod's container in a dialog
*
* @public
*/
export const PodExecTerminalDialog = (props: PodExecTerminalProps) => {
const classes = useStyles();
const { clusterName, containerName, podName } = props;
const [open, setOpen] = useState(false);
const isPodExecTerminalSupported = useIsPodExecTerminalSupported();
const openDialog = () => {
setOpen(true);
};
const closeDialog = () => {
setOpen(false);
};
return (
<>
{!isPodExecTerminalSupported.loading &&
isPodExecTerminalSupported.value && (
<Dialog
maxWidth={false}
fullWidth
open={open}
onClose={closeDialog}
PaperProps={{ className: classes.dialogPaper }}
>
<DialogTitle id="dialog-title">
{podName} - {containerName} terminal shell on cluster{' '}
{clusterName}
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={closeDialog}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent className={classes.dialogContent}>
<PodExecTerminal {...props} />
</DialogContent>
</Dialog>
)}
<Button
variant="outlined"
aria-label="open terminal"
component="label"
!isPodExecTerminalSupported.loading &&
isPodExecTerminalSupported.value && (
<KubernetesDialog
buttonAriaLabel="open terminal"
buttonIcon={<OpenInBrowserIcon />}
buttonText="Terminal"
disabled={
isPodExecTerminalSupported.loading ||
!isPodExecTerminalSupported.value
}
onClick={openDialog}
startIcon={<OpenInBrowserIcon />}
title={`${podName} - ${containerName} terminal shell on cluster ${clusterName}`}
>
Terminal
</Button>
</>
<PodExecTerminal {...props} />
</KubernetesDialog>
)
);
};
@@ -13,36 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useState } from 'react';
import React from 'react';
import {
Button,
createStyles,
Dialog,
DialogContent,
DialogTitle,
IconButton,
makeStyles,
Theme,
} from '@material-ui/core';
import SubjectIcon from '@material-ui/icons/Subject';
import CloseIcon from '@material-ui/icons/Close';
import { KubernetesDialog } from '../../KubernetesDialog';
import { PodLogs } from './PodLogs';
import { ContainerScope } from './types';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
closeButton: {
position: 'absolute',
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500],
},
}),
);
/**
* Props for PodLogsDialog
*
@@ -58,43 +36,15 @@ export interface PodLogsDialogProps {
* @public
*/
export const PodLogsDialog = ({ containerScope }: PodLogsDialogProps) => {
const classes = useStyles();
const [open, setOpen] = useState(false);
const openDialog = () => {
setOpen(true);
};
const closeDialog = () => {
setOpen(false);
};
return (
<>
<Dialog maxWidth="xl" fullWidth open={open} onClose={closeDialog}>
<DialogTitle id="dialog-title">
{containerScope.podName} - {containerScope.containerName} logs on
cluster {containerScope.clusterName}
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={closeDialog}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent>
<PodLogs containerScope={containerScope} />
</DialogContent>
</Dialog>
<Button
variant="outlined"
aria-label="get logs"
component="label"
onClick={openDialog}
startIcon={<SubjectIcon />}
>
Logs
</Button>
</>
<KubernetesDialog
buttonAriaLabel="get logs"
buttonIcon={<SubjectIcon />}
buttonText="Logs"
disabled={false}
title={`${containerScope.podName} - ${containerScope.containerName} logs on cluster ${containerScope.clusterName}`}
>
<PodLogs containerScope={containerScope} />
</KubernetesDialog>
);
};