Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ export const StyledRootContainer = styled(Paper, {
padding: theme.spacing(3),
}));

export const StyledHelperText = styled(Typography, {
label: 'StyledHelperText',
})(({ theme }) => ({
lineHeight: 1.5,
paddingBottom: theme.spacing(),
paddingTop: theme.spacing(),
}));

export const StyledActionsPanel = styled(ActionsPanel, {
label: 'StyledActionsPanel',
})(() => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import * as React from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useHistory, useLocation } from 'react-router-dom';

import { Link } from 'src/components/Link';
import { Notice } from 'src/components/Notice/Notice';
import { SupportLink } from 'src/components/SupportLink';
import { Typography } from 'src/components/Typography';
import { getQueryParamFromQueryString } from 'src/utilities/queryParams';

import { BucketRateLimitTable } from '../BucketLanding/BucketRateLimitTable';
import { BucketBreadcrumb } from './BucketBreadcrumb';
import {
StyledActionsPanel,
StyledHelperText,
StyledRootContainer,
StyledText,
} from './BucketProperties.styles';
Expand All @@ -23,69 +17,36 @@ interface Props {
bucket: ObjectStorageBucket;
}

export interface UpdateBucketRateLimitPayload {
rateLimit: string;
}

export const BucketProperties = React.memo((props: Props) => {
const { bucket } = props;
const { endpoint_type, hostname, label } = bucket;

const form = useForm<UpdateBucketRateLimitPayload>({
defaultValues: {
rateLimit: '1',
},
});

const {
formState: { errors, isDirty, isSubmitting },
handleSubmit,
} = form;

const location = useLocation();
const history = useHistory();
const prefix = getQueryParamFromQueryString(location.search, 'prefix');

const onSubmit = () => {
// TODO: OBJGen2 - Handle Bucket Rate Limit update logic once the endpoint for updating is available.
// The 'data' argument is expected -> data: UpdateBucketRateLimitPayload
};

return (
<FormProvider {...form}>
<>
<BucketBreadcrumb bucketName={label} history={history} prefix={prefix} />
<StyledText>{hostname || 'Loading...'}</StyledText>
<StyledText>{hostname}</StyledText>

<StyledRootContainer>
<Typography variant="h2">Bucket Rate Limits</Typography>

{errors.root?.message ? (
<Notice text={errors.root?.message} variant="error" />
) : null}

{/* TODO: OBJGen2 - We need to handle link in upcoming PR */}
<StyledHelperText>
Specifies the maximum Requests Per Second (RPS) for an Endpoint. To
increase it to High,{' '}
<SupportLink
text="open a support ticket"
title="Request to Increase Bucket Rate Limits"
/>
. Understand <Link to="#">bucket rate limits</Link>.
</StyledHelperText>

<form onSubmit={handleSubmit(onSubmit)}>
<BucketRateLimitTable endpointType={endpoint_type} />
<StyledActionsPanel
primaryButtonProps={{
disabled: !isDirty,
label: 'Save',
loading: isSubmitting,
type: 'submit',
}}
/>
</form>
<BucketRateLimitTable
typographyProps={{
component: 'h3',
variant: 'h3',
}}
endpointType={endpoint_type}
/>
{/* TODO: OBJGen2 - This will be handled once we receive API for bucket rates */}
<StyledActionsPanel
primaryButtonProps={{
disabled: true,
label: 'Save',
type: 'submit',
}}
/>
</StyledRootContainer>
</FormProvider>
</>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ export const BucketDetailsDrawer = React.memo(
account?.capabilities ?? []
);

const isObjectStorageGen2Enabled = isFeatureEnabledV2(
'Object Storage Endpoint Types',
Boolean(flags.objectStorageGen2?.enabled),
account?.capabilities ?? []
);

// @TODO OBJGen2 - We could clean this up when OBJ Gen2 is in GA.
const { data: clusters } = useObjectStorageClusters(
!isObjMultiClusterEnabled
Expand All @@ -74,8 +80,6 @@ export const BucketDetailsDrawer = React.memo(
);

let formattedCreated;
const showBucketRateLimitTable =
endpoint_type === 'E2' || endpoint_type === 'E3';

try {
if (created) {
Expand Down Expand Up @@ -141,21 +145,15 @@ export const BucketDetailsDrawer = React.memo(
)}
{/* @TODO OBJ Multicluster: use region instead of cluster if isObjMultiClusterEnabled
to getBucketAccess and updateBucketAccess. */}
{
<>
<Typography data-testid="bucketRateLimit" variant="h3">
Bucket Rate Limits
</Typography>
{showBucketRateLimitTable ? (
<BucketRateLimitTable endpointType={endpoint_type} />
) : (
<Typography>
This endpoint type supports up to 750 Requests Per Second(RPS).{' '}
<Link to="#">Understand bucket rate limits</Link>.
</Typography>
)}
</>
}
{isObjectStorageGen2Enabled && (
<BucketRateLimitTable
typographyProps={{
marginTop: 1,
variant: 'inherit',
}}
endpointType={endpoint_type}
/>
)}
{<Divider spacingBottom={16} spacingTop={16} />}
{cluster && label && (
<AccessSelect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { BucketRateLimitTable } from './BucketRateLimitTable';

// recent bucket rate limit changes cause these tests to fail + bug when opening up Create Bucket drawer.
// commenting out these tests for now + will investigate in a separate PR (need to investigate further)
describe.skip('BucketRateLimitTable', () => {
describe('BucketRateLimitTable', () => {
it('should render a BucketRateLimitTable', () => {
const { getAllByRole, getByText, queryByText } = renderWithTheme(
<BucketRateLimitTable endpointType="E2" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
import React from 'react';
import { useController, useFormContext } from 'react-hook-form';

import { Box } from 'src/components/Box';
import { FormControlLabel } from 'src/components/FormControlLabel';
import { FormLabel } from 'src/components/FormLabel';
import { Link } from 'src/components/Link';
import { Radio } from 'src/components/Radio/Radio';
import { SupportLink } from 'src/components/SupportLink';
import { Table } from 'src/components/Table';
import { TableBody } from 'src/components/TableBody';
import { TableCell } from 'src/components/TableCell';
import { TableHead } from 'src/components/TableHead';
import { TableRow } from 'src/components/TableRow';
import { Typography } from 'src/components/Typography';

import type { UpdateBucketRateLimitPayload } from '../BucketDetail/BucketProperties';
import type { ObjectStorageEndpointTypes } from '@linode/api-v4';
import type { TypographyProps } from 'src/components/Typography';

/**
* TODO: This component is currently using static data until
* TODO: [IMPORTANT NOTE]: This component is currently using static data until
* and API endpoint is available to return rate limits for
* each endpoint type.
*/

interface BucketRateLimitTableProps {
endpointType: ObjectStorageEndpointTypes | undefined;
endpointType?: ObjectStorageEndpointTypes;
typographyProps?: TypographyProps;
}

const tableHeaders = ['Limits', 'GET', 'PUT', 'LIST', 'DELETE', 'OTHER'];
Expand Down Expand Up @@ -50,66 +55,93 @@ const tableData = ({ endpointType }: BucketRateLimitTableProps) => {

export const BucketRateLimitTable = ({
endpointType,
typographyProps,
}: BucketRateLimitTableProps) => {
const { control } = useFormContext<UpdateBucketRateLimitPayload>();
const { field } = useController({
control,
name: 'rateLimit',
});
const isGen2EndpointType = endpointType === 'E2' || endpointType === 'E3';

return (
<Table data-testid="bucket-rate-limit-table" sx={{ marginBottom: 3 }}>
<TableHead>
<TableRow>
{tableHeaders.map((header, index) => {
return (
<TableCell
sx={{
'&&:last-child': {
paddingRight: 2,
},
}}
key={`${index}-${header}`}
>
{header}
</TableCell>
);
})}
</TableRow>
</TableHead>
<TableBody>
{tableData({ endpointType }).map((row, rowIndex) => (
<TableRow key={rowIndex}>
<TableCell>
<FormControlLabel
control={
<Radio
checked={field.value === row.id}
disabled
onChange={() => field.onChange(row.id)}
value={row.id}
<Box>
<FormLabel>
<Typography
data-testid="bucketRateLimit"
marginBottom={1}
{...typographyProps}
>
Bucket Rate Limits
</Typography>
</FormLabel>
<Typography marginBottom={isGen2EndpointType ? 2 : 3}>
{isGen2EndpointType ? (
<>
Specifies the maximum Requests Per Second (RPS) for a bucket. To
increase it to High,{' '}
<SupportLink
text="open a support ticket"
title="Request to Increase Bucket Rate Limits"
/>
.{' '}
</>
) : (
'This endpoint type supports up to 750 Requests Per Second (RPS). '
)}
Understand <Link to="#">bucket rate limits</Link>.

@mjac0bs mjac0bs Aug 30, 2024 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions for my own knowledge, not directly related to these PR's changes:

  1. Have we moved away from using "Learn more about [topic]." in our copy? This is the first time I remember seeing "Understand [topic]." and it's used multiple times. I was wondering whether that's intentional or due to some inconsistency in tech writing.

Screenshot 2024-08-30 at 7 44 50β€―AM

  1. Why is E1 listed twice in this dropdown?
    Screenshot 2024-08-30 at 7 44 59β€―AM

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I'll confirm with TW
  2. In rare cases, the dropdown must display a specific endpoint hostname (s3_endpoint) along with the endpoint type to distinguish between two assigned endpoints of the same type. This is necessary for multiple Gen1 (E1) assignments in the same region. Essentially, this mock demonstrates that if an s3_endpoint is provided, we want to display it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TW wants to keep it as is even though we use it in one other place

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for confirming and for the dropdown explanation. Any verdict on the Save button?

</Typography>

{isGen2EndpointType && (
<Table data-testid="bucket-rate-limit-table" sx={{ marginBottom: 3 }}>
<TableHead>
<TableRow>
{tableHeaders.map((header, index) => {
return (
<TableCell
sx={{
'&&:last-child': {
paddingRight: 2,
},
}}
key={`${index}-${header}`}
>
{header}
</TableCell>
);
})}
</TableRow>
</TableHead>
<TableBody>
{tableData({ endpointType }).map((row, rowIndex) => (
<TableRow key={rowIndex}>
<TableCell>
<FormControlLabel
control={
<Radio
checked={rowIndex === 0}
disabled
onChange={() => null}
value={row.id}
/>
}
label={row.label}
/>
}
label={row.label}
/>
</TableCell>
{row.values.map((value, index) => {
return (
<TableCell
sx={{
'&&:last-child': {
paddingRight: 2,
},
}}
key={`${index}-${value}`}
>
{value}
</TableCell>
);
})}
</TableRow>
))}
</TableBody>
</Table>
{row.values.map((value, index) => {
return (
<TableCell
sx={{
'&&:last-child': {
paddingRight: 2,
},
}}
key={`${index}-${value}`}
>
{value}
</TableCell>
);
})}
</TableRow>
))}
</TableBody>
</Table>
)}
</Box>
);
};
Loading