Skip to content

Commit

Permalink
feat: [UIE-8007] - DBaaS enhancements summary and settings (#10939)
Browse files Browse the repository at this point in the history
  • Loading branch information
corya-akamai authored Sep 18, 2024
1 parent 1a3b0f2 commit 9734976
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Upcoming Features
---

DBaaS V2 readonly hosts ([#10939](https://github.com/linode/manager/pull/10939))
1 change: 0 additions & 1 deletion packages/api-v4/src/regions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export type Capabilities =
| 'Kubernetes'
| 'Linodes'
| 'Managed Databases'
| 'Managed Databases Beta'
| 'Metadata'
| 'NodeBalancers'
| 'Object Storage'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

DBaaS V2 enhancements to the Summary and Settings tabs ([#10939](https://github.com/linode/manager/pull/10939))
5 changes: 3 additions & 2 deletions packages/manager/src/factories/databases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ export const databaseInstanceFactory = Factory.Sync.makeFactory<DatabaseInstance
created: '2021-12-09T17:15:12',
engine: Factory.each((i) => ['mysql', 'postgresql'][i % 2] as Engine),
hosts: {
primary: 'db-primary-0.b.linodeb.net',
secondary: 'db-secondary-0.b.linodeb.net',
primary: 'db-mysql-primary-0.b.linodeb.net',
secondary: 'db-mysql-secondary-0.b.linodeb.net',
},
id: Factory.each((i) => i),
instance_uri: '',
Expand Down Expand Up @@ -222,6 +222,7 @@ export const databaseFactory = Factory.Sync.makeFactory<Database>({
members: {
'2.2.2.2': 'primary',
},
platform: pickRandom(['rdbms-legacy', 'rdbms-default']),
port: 3306,
region: 'us-east',
ssl_connection: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,30 @@ describe('DatabaseSettings Component', () => {
expect(button).toBeEnabled();
}
});

it('Should render Maintenance Window with radio buttons', () => {
const database = databaseFactory.build({
platform: 'rdbms-legacy',
});
const { getByRole, queryByText } = renderWithTheme(
<DatabaseSettings database={database} />
);
const radioInput = getByRole('radiogroup');
expect(radioInput).toHaveTextContent('Monthly');
expect(radioInput).toHaveTextContent('Weekly');
expect(queryByText('Maintenance Window')).toBeTruthy();
});

it('Should render Weekly Maintenance Window', () => {
const database = databaseFactory.build({
platform: 'rdbms-default',
});
const { queryByText } = renderWithTheme(
<DatabaseSettings database={database} />
);

expect(queryByText('Monthly')).toBeNull();
expect(queryByText('Weekly')).toBeNull();
expect(queryByText('Set a Weekly Maintenance Window')).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@ export const DatabaseSettings: React.FC<Props> = (props) => {
</Typography>
);

const resetRootPasswordCopy =
'Resetting your root password will automatically generate a new password. You can view the updated password on your database cluster summary page. ';
const isLegacy = database.platform === 'rdbms-legacy';

const deleteClusterCopy =
'Deleting a database cluster is permanent and cannot be undone.';
const resetRootPasswordCopy = isLegacy
? 'Resetting your root password will automatically generate a new password. You can view the updated password on your database cluster summary page. '
: 'Reset your root password if someone should no longer have access to the root user or if you believe your password may have been compromised. This will automatically generate a new password that you’ll be able to see on your database cluster summary page.';

const deleteClusterCopy = isLegacy
? 'Deleting a database cluster is permanent and cannot be undone.'
: 'Permanently remove an unused database cluster.';

const [isDeleteDialogOpen, setIsDeleteDialogOpen] = React.useState(false);
const [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import { FormControlLabel } from 'src/components/FormControlLabel';
import { RadioGroup } from 'src/components/RadioGroup';
import { useDatabaseMutation } from 'src/queries/databases/databases';

// import { updateDatabaseSchema } from '@linode/validation/src/databases.schema';

const useStyles = makeStyles()((theme: Theme) => ({
formControlDropdown: {
'& label': {
Expand Down Expand Up @@ -173,22 +171,30 @@ export const MaintenanceWindow = (props: Props) => {
onSubmit: handleSaveMaintenanceWindow,
});

const isLegacy = database.platform === 'rdbms-legacy';

const typographyDatabase =
'Select when you want the required OS and DB engine updates to take place. The maintenance may cause downtime on clusters with less than 3 nodes (non high-availability clusters).';

const typographyLegacyDatabase =
"OS and DB engine updates will be performed on the schedule below. Select the frequency, day, and time you'd prefer maintenance to occur.";

return (
<form onSubmit={handleSubmit}>
<div className={classes.topSection}>
<div className={classes.sectionTitleAndText}>
<Typography className={classes.sectionTitle} variant="h3">
Maintenance Window
{isLegacy
? 'Maintenance Window'
: 'Set a Weekly Maintenance Window'}
</Typography>
{maintenanceUpdateError ? (
<Notice spacingTop={8} variant="error">
{maintenanceUpdateError[0].reason}
</Notice>
) : null}
<Typography className={classes.sectionText}>
OS and DB engine updates will be performed on the schedule below.
Select the frequency, day, and time you&rsquo;d prefer maintenance
to occur.{' '}
{isLegacy ? typographyLegacyDatabase : typographyDatabase}
{database.cluster_size !== 3
? 'For non-HA plans, expect downtime during this window.'
: null}
Expand Down Expand Up @@ -261,7 +267,7 @@ export const MaintenanceWindow = (props: Props) => {
/>
<TooltipIcon
sxTooltipIcon={{
marginTop: '1.25rem',
marginTop: '1.75rem',
padding: '0px 8px',
}}
text={
Expand All @@ -277,44 +283,46 @@ export const MaintenanceWindow = (props: Props) => {
</div>
</FormControl>
</div>
<FormControl
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setFormTouched(true);
setFieldValue('frequency', e.target.value);
if (e.target.value === 'weekly') {
// If the frequency is weekly, set the 'week_of_month' field to null since that should only be specified for a monthly frequency.
setFieldValue('week_of_month', null);
}
{isLegacy && (
<FormControl
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setFormTouched(true);
setFieldValue('frequency', e.target.value);
if (e.target.value === 'weekly') {
// If the frequency is weekly, set the 'week_of_month' field to null since that should only be specified for a monthly frequency.
setFieldValue('week_of_month', null);
}

if (e.target.value === 'monthly') {
const dayOfWeek =
daySelectionMap.find(
(option) => option.value === values.day_of_week
) ?? daySelectionMap[0];
if (e.target.value === 'monthly') {
const dayOfWeek =
daySelectionMap.find(
(option) => option.value === values.day_of_week
) ?? daySelectionMap[0];

weekSelectionModifier(dayOfWeek.label, weekSelectionMap);
setFieldValue(
'week_of_month',
modifiedWeekSelectionMap[0].value
);
}
}}
disabled={disabled}
>
<RadioGroup
style={{ marginBottom: 0, marginTop: 0 }}
value={values.frequency}
weekSelectionModifier(dayOfWeek.label, weekSelectionMap);
setFieldValue(
'week_of_month',
modifiedWeekSelectionMap[0].value
);
}
}}
disabled={disabled}
>
{maintenanceFrequencyMap.map((option) => (
<FormControlLabel
control={<Radio />}
key={option.value}
label={option.key}
value={option.value}
/>
))}
</RadioGroup>
</FormControl>
<RadioGroup
style={{ marginBottom: 0, marginTop: 0 }}
value={values.frequency}
>
{maintenanceFrequencyMap.map((option) => (
<FormControlLabel
control={<Radio />}
key={option.value}
label={option.key}
value={option.value}
/>
))}
</RadioGroup>
</FormControl>
)}
<div>
{values.frequency === 'monthly' ? (
<FormControl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,12 @@ export const DatabaseSummaryConnectionDetails = (props: Props) => {
{database.hosts.secondary ? (
<Box alignItems="center" display="flex" flexDirection="row">
<Typography>
<span>private network host</span> = {database.hosts.secondary}
{database.platform === 'rdbms-default' ? (
<span>read-only host</span>
) : (
<span>private network host</span>
)}
= {database.hosts.secondary}
</Typography>
<CopyTooltip
className={classes.inlineCopyToolTip}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { SafeTabPanel } from 'src/components/Tabs/SafeTabPanel';
import { TabLinkList } from 'src/components/Tabs/TabLinkList';
import { TabPanels } from 'src/components/Tabs/TabPanels';
import { Tabs } from 'src/components/Tabs/Tabs';
import DatabaseLogo from 'src/features/Databases/DatabaseLanding/DatabaseLogo';
import { useEditableLabelState } from 'src/hooks/useEditableLabelState';
import { useFlags } from 'src/hooks/useFlags';
import { useIsResourceRestricted } from 'src/hooks/useIsResourceRestricted';
Expand Down Expand Up @@ -199,6 +200,7 @@ export const DatabaseDetail = () => {
</SafeTabPanel>
</TabPanels>
</Tabs>
{database.platform === 'rdbms-default' && <DatabaseLogo />}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { TableCell } from '@mui/material';
import React from 'react';

import { Hidden } from 'src/components/Hidden';
Expand Down Expand Up @@ -60,8 +59,14 @@ const DatabaseLandingTable = ({
Status
</TableSortCell>
{isNewDatabase && (
/* TODO add back TableSortCell once API is updated to support sort by Plan */
<TableCell>Plan</TableCell>
<TableSortCell
active={orderBy === 'plan'}
direction={order}
handleClick={handleOrderChange}
label="plan"
>
Plan
</TableSortCell>
)}
<Hidden smDown>
<TableSortCell
Expand Down
6 changes: 6 additions & 0 deletions packages/manager/src/mocks/serverHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ const databases = [
label: `Nanode 1 GB`,
memory: 1024,
}),
databaseTypeFactory.build({
class: 'nanode',
id: 'g6-standard-1',
label: `Linode 2 GB`,
memory: 2048,
}),
...databaseTypeFactory.buildList(7, { class: 'standard' }),
];
const dedicatedTypes = databaseTypeFactory.buildList(7, {
Expand Down
2 changes: 1 addition & 1 deletion packages/validation/src/databases.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const createDatabaseSchema = object({
region: string().required('Region is required'),
type: string().required('Type is required'),
cluster_size: number()
.oneOf([1, 3], 'Nodes are required')
.oneOf([1, 2, 3], 'Nodes are required')
.required('Nodes are required'),
replication_type: string().when('engine', {
is: (engine: string) => Boolean(engine.match(/mysql|postgres/g)),
Expand Down

0 comments on commit 9734976

Please sign in to comment.