-
Notifications
You must be signed in to change notification settings - Fork 401
upcoming: [UIE-9327] - Add service URIs to Database summary tab #13261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6a0678c
235285b
b1d41f5
f585dc9
57db07e
00c147d
74a00c3
0a9c583
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@linode/manager": Upcoming Features | ||
| --- | ||
|
|
||
| Add service URIs to Database summary tab ([#13261](https://github.com/linode/manager/pull/13261)) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| import { getSSLFields } from '@linode/api-v4/lib/databases/databases'; | ||
| import { TooltipIcon } from '@linode/ui'; | ||
| import { downloadFile } from '@linode/utilities'; | ||
| import { styled } from '@mui/material/styles'; | ||
| import { Button } from 'akamai-cds-react-components'; | ||
| import { useSnackbar } from 'notistack'; | ||
| import * as React from 'react'; | ||
|
|
||
| import DownloadIcon from 'src/assets/icons/lke-download.svg'; | ||
| import { getErrorStringOrDefault } from 'src/utilities/errorUtils'; | ||
|
|
||
| import { sxTooltipIcon } from './DatabaseSummaryConnectionDetails'; | ||
|
|
||
| import type { Database, SSLFields } from '@linode/api-v4'; | ||
|
|
||
| interface Props { | ||
| database: Database; | ||
| } | ||
|
|
||
| export const DatabaseCaCert = (props: Props) => { | ||
| const { database } = props; | ||
| const { enqueueSnackbar } = useSnackbar(); | ||
| const [isCACertDownloading, setIsCACertDownloading] = | ||
| React.useState<boolean>(false); | ||
|
|
||
| const handleDownloadCACertificate = () => { | ||
| setIsCACertDownloading(true); | ||
| getSSLFields(database.engine, database.id) | ||
| .then((response: SSLFields) => { | ||
| // Convert to utf-8 from base64 | ||
| try { | ||
| const decodedFile = window.atob(response.ca_certificate); | ||
| downloadFile(`${database.label}-ca-certificate.crt`, decodedFile); | ||
| setIsCACertDownloading(false); | ||
| } catch { | ||
| enqueueSnackbar('Error parsing your CA Certificate file', { | ||
| variant: 'error', | ||
| }); | ||
| setIsCACertDownloading(false); | ||
| return; | ||
| } | ||
| }) | ||
| .catch((errorResponse: any) => { | ||
|
Check warning on line 43 in packages/manager/src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseCaCert.tsx
|
||
| const error = getErrorStringOrDefault( | ||
| errorResponse, | ||
| 'Unable to download your CA Certificate' | ||
| ); | ||
| setIsCACertDownloading(false); | ||
| enqueueSnackbar(error, { variant: 'error' }); | ||
| }); | ||
| }; | ||
|
|
||
| const disableDownloadCACertificateBtn = database.status === 'provisioning'; | ||
|
|
||
| return ( | ||
| <> | ||
| <StyledCaCertButton | ||
| data-testid="download-ca-certificate" | ||
| disabled={disableDownloadCACertificateBtn} | ||
| onClick={handleDownloadCACertificate} | ||
| processing={isCACertDownloading} | ||
| variant="link" | ||
| > | ||
| <DownloadIcon /> | ||
| Download CA Certificate | ||
| </StyledCaCertButton> | ||
| {disableDownloadCACertificateBtn && ( | ||
| <span style={{ alignContent: 'center' }}> | ||
| <TooltipIcon | ||
| status="info" | ||
| sxTooltipIcon={sxTooltipIcon} | ||
| text="Your Database Cluster is currently provisioning." | ||
| /> | ||
| </span> | ||
| )} | ||
| </> | ||
| ); | ||
| }; | ||
|
|
||
| export const StyledCaCertButton = styled(Button, { | ||
| label: 'StyledCaCertButton', | ||
| })(({ theme }) => ({ | ||
| '&:hover': { | ||
| backgroundColor: 'transparent', | ||
| opacity: 0.7, | ||
| }, | ||
| '&[disabled]': { | ||
| '& g': { | ||
| stroke: theme.tokens.color.Neutrals[30], | ||
| }, | ||
| '&:hover': { | ||
| backgroundColor: 'inherit', | ||
| textDecoration: 'none', | ||
| }, | ||
| // Override disabled background color defined for dark mode | ||
| backgroundColor: 'transparent', | ||
| color: theme.tokens.color.Neutrals[30], | ||
| cursor: 'default', | ||
| }, | ||
| color: theme.palette.primary.main, | ||
| font: theme.font.bold, | ||
| fontSize: '0.875rem', | ||
| lineHeight: '1.125rem', | ||
| minHeight: 'auto', | ||
| minWidth: 'auto', | ||
| padding: 0, | ||
| })); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,32 @@ | ||
| import { Paper } from '@linode/ui'; | ||
| import { useDatabaseConnectionPoolsQuery } from '@linode/queries'; | ||
| import { Paper, Typography } from '@linode/ui'; | ||
| import Grid from '@mui/material/Grid'; | ||
| import { styled } from '@mui/material/styles'; | ||
| import * as React from 'react'; | ||
|
|
||
| import ClusterConfiguration from 'src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryClusterConfiguration'; | ||
| import ConnectionDetails from 'src/features/Databases/DatabaseDetail/DatabaseSummary/DatabaseSummaryConnectionDetails'; | ||
| import { useFlags } from 'src/hooks/useFlags'; | ||
|
|
||
| import { useDatabaseDetailContext } from '../DatabaseDetailContext'; | ||
| import { ServiceURI } from '../ServiceURI'; | ||
| import { DatabaseCaCert } from './DatabaseCaCert'; | ||
|
|
||
| export const DatabaseSummary = () => { | ||
| const { database } = useDatabaseDetailContext(); | ||
| const flags = useFlags(); | ||
|
|
||
| const { data: connectionPools } = useDatabaseConnectionPoolsQuery( | ||
| database.id, | ||
| flags.databasePgBouncer, | ||
| {} | ||
| ); | ||
|
|
||
| const showPgBouncerConnectionDetails = | ||
| flags.databasePgBouncer && | ||
| database.engine === 'postgresql' && | ||
| connectionPools && | ||
| connectionPools.data.length > 0; | ||
|
|
||
| return ( | ||
| <Paper> | ||
|
|
@@ -29,7 +47,34 @@ export const DatabaseSummary = () => { | |
| > | ||
| <ConnectionDetails database={database} /> | ||
| </Grid> | ||
| {showPgBouncerConnectionDetails && ( | ||
| <Grid | ||
| size={{ | ||
| md: 12, | ||
| sm: 12, | ||
| }} | ||
| > | ||
| <Typography mb={2} variant="h3"> | ||
| PgBouncer Connection Details | ||
| </Typography> | ||
| <ServiceURI database={database} /> | ||
| </Grid> | ||
| )} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It may not be necessary, but I'm wondering if it would make sense to add some kind of error state for this field in the event that the connection-pools GET call fails. Currently it just hides the PgBouncer Connection Details field as a whole, but they won't actually see any error messaging until they navigate to the Networking tab. |
||
| </Grid> | ||
| {database.ssl_connection && ( | ||
| <StyledButtonCtn> | ||
| <DatabaseCaCert database={database} /> | ||
| </StyledButtonCtn> | ||
| )} | ||
| </Paper> | ||
| ); | ||
| }; | ||
|
|
||
| export const StyledButtonCtn = styled('div', { | ||
| label: 'StyledButtonCtn', | ||
| })(({ theme }) => ({ | ||
| display: 'flex', | ||
| justifyContent: 'flex-end', | ||
| marginTop: '10px', | ||
| padding: `${theme.spacingFunction(8)} 0`, | ||
| })); | ||
Uh oh!
There was an error while loading. Please reload this page.