Skip to content

Commit debff9e

Browse files
change: [DPS-35759] - Fix UI/Copy issues after UX review (#13140)
* change: [DPS-35759] - Fix UI/Copy issues after UX review * revert spacing change - point 2
1 parent 02e82e6 commit debff9e

File tree

12 files changed

+167
-74
lines changed

12 files changed

+167
-74
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Changed
3+
---
4+
5+
Logs Delivery UI changes after review ([#13140](https://github.com/linode/manager/pull/13140))

packages/manager/src/features/Delivery/Destinations/DestinationTableRow.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ export const DestinationTableRow = React.memo(
4242
<TableCell>
4343
<DateTimeDisplay value={destination.updated} />
4444
</TableCell>
45+
<Hidden lgDown>
46+
<TableCell>{destination.updated_by}</TableCell>
47+
</Hidden>
4548
<TableCell actionCell>
4649
<DestinationActionMenu
4750
destination={destination}

packages/manager/src/features/Delivery/Destinations/DestinationsLanding.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useDestinationsQuery } from '@linode/queries';
2-
import { CircleProgress, ErrorState, Hidden } from '@linode/ui';
2+
import { CircleProgress, ErrorState, Hidden, Paper } from '@linode/ui';
33
import { TableBody, TableHead, TableRow } from '@mui/material';
44
import Table from '@mui/material/Table';
55
import { useNavigate, useSearch } from '@tanstack/react-router';
@@ -119,7 +119,7 @@ export const DestinationsLanding = () => {
119119
};
120120

121121
return (
122-
<>
122+
<Paper>
123123
<DeliveryTabHeader
124124
entity="Destination"
125125
isSearching={isFetching}
@@ -177,6 +177,16 @@ export const DestinationsLanding = () => {
177177
>
178178
Last Modified
179179
</TableSortCell>
180+
<Hidden lgDown>
181+
<TableSortCell
182+
active={orderBy === 'updated_by'}
183+
direction={order}
184+
handleClick={handleOrderChange}
185+
label="updated_by"
186+
>
187+
Last Modified By
188+
</TableSortCell>
189+
</Hidden>
180190
<TableCell sx={{ width: '5%' }} />
181191
</TableRow>
182192
</TableHead>
@@ -188,7 +198,7 @@ export const DestinationsLanding = () => {
188198
{...handlers}
189199
/>
190200
))}
191-
{destinations?.results === 0 && <TableRowEmpty colSpan={6} />}
201+
{destinations?.results === 0 && <TableRowEmpty colSpan={7} />}
192202
</TableBody>
193203
</Table>
194204
<PaginationFooter
@@ -206,6 +216,6 @@ export const DestinationsLanding = () => {
206216
/>
207217
</>
208218
)}
209-
</>
219+
</Paper>
210220
);
211221
};

packages/manager/src/features/Delivery/Shared/LabelValue.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import { Box, Typography } from '@linode/ui';
1+
import { Box, Tooltip, Typography } from '@linode/ui';
22
import { styled, useTheme } from '@mui/material/styles';
3+
import useMediaQuery from '@mui/material/useMediaQuery';
34
import * as React from 'react';
45

56
interface LabelValueProps {
67
children?: React.ReactNode;
78
compact?: boolean;
89
'data-testid'?: string;
910
label: string;
11+
smHideTooltip?: boolean;
1012
value: string;
1113
}
1214

@@ -17,8 +19,10 @@ export const LabelValue = (props: LabelValueProps) => {
1719
value,
1820
'data-testid': dataTestId,
1921
children,
22+
smHideTooltip,
2023
} = props;
2124
const theme = useTheme();
25+
const matchesSmDown = useMediaQuery(theme.breakpoints.down('sm'));
2226

2327
return (
2428
<Box
@@ -35,13 +39,18 @@ export const LabelValue = (props: LabelValueProps) => {
3539
>
3640
{label}:
3741
</Typography>
38-
<StyledValue data-testid={dataTestId}>{value}</StyledValue>
42+
<StyledValue
43+
data-testid={dataTestId}
44+
title={!smHideTooltip && matchesSmDown ? value : undefined}
45+
>
46+
<Typography>{value}</Typography>
47+
</StyledValue>
3948
{children}
4049
</Box>
4150
);
4251
};
4352

44-
const StyledValue = styled(Box, {
53+
const StyledValue = styled(Tooltip, {
4554
label: 'StyledValue',
4655
})(({ theme }) => ({
4756
alignItems: 'center',
@@ -51,4 +60,12 @@ const StyledValue = styled(Box, {
5160
display: 'flex',
5261
height: theme.spacingFunction(24),
5362
padding: theme.spacingFunction(4, 8),
63+
[theme.breakpoints.down('sm')]: {
64+
display: 'block',
65+
maxWidth: '174px',
66+
textOverflow: 'ellipsis',
67+
overflow: 'hidden',
68+
whiteSpace: 'nowrap',
69+
padding: theme.spacingFunction(1, 8),
70+
},
5471
}));

packages/manager/src/features/Delivery/Streams/StreamForm/Clusters/StreamFormClusters.tsx

Lines changed: 93 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { useRegionsQuery } from '@linode/queries';
2+
import { useIsGeckoEnabled } from '@linode/shared';
13
import {
24
Box,
35
Checkbox,
@@ -8,6 +10,10 @@ import {
810
Typography,
911
} from '@linode/ui';
1012
import { capitalize } from '@linode/utilities';
13+
import Grid from '@mui/material/Grid';
14+
import { styled, type Theme } from '@mui/material/styles';
15+
import useMediaQuery from '@mui/material/useMediaQuery';
16+
import { useFlags } from 'launchdarkly-react-client-sdk';
1117
import { enqueueSnackbar } from 'notistack';
1218
import React, { useEffect, useMemo, useState } from 'react';
1319
import { useWatch } from 'react-hook-form';
@@ -17,6 +23,7 @@ import { DebouncedSearchTextField } from 'src/components/DebouncedSearchTextFiel
1723
import { sortData } from 'src/components/OrderBy';
1824
import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter';
1925
import { MIN_PAGE_SIZE } from 'src/components/PaginationFooter/PaginationFooter.constants';
26+
import { RegionSelect } from 'src/components/RegionSelect/RegionSelect';
2027
import { Table } from 'src/components/Table';
2128
import { StreamFormClusterTableContent } from 'src/features/Delivery/Streams/StreamForm/Clusters/StreamFormClustersTableContent';
2229
import { useAllKubernetesClustersQuery } from 'src/queries/kubernetes';
@@ -41,11 +48,17 @@ export const StreamFormClusters = (props: StreamFormClustersProps) => {
4148
const { control, setValue, formState, trigger } =
4249
useFormContext<StreamAndDestinationFormType>();
4350

51+
const xsDown = useMediaQuery((theme: Theme) => theme.breakpoints.down('sm'));
52+
const { gecko2 } = useFlags();
53+
const { isGeckoLAEnabled } = useIsGeckoEnabled(gecko2?.enabled, gecko2?.la);
54+
const { data: regions } = useRegionsQuery();
55+
4456
const [order, setOrder] = useState<'asc' | 'desc'>('asc');
4557
const [orderBy, setOrderBy] = useState<OrderByKeys>('label');
4658
const [page, setPage] = useState<number>(1);
4759
const [pageSize, setPageSize] = useState<number>(MIN_PAGE_SIZE);
4860
const [searchText, setSearchText] = useState<string>('');
61+
const [regionFilter, setRegionFilter] = useState<string>('');
4962

5063
const {
5164
data: clusters = [],
@@ -119,20 +132,30 @@ export const StreamFormClusters = (props: StreamFormClustersProps) => {
119132
}
120133
};
121134

122-
const filteredClusters = !searchText
123-
? clusters
124-
: clusters.filter((cluster) => {
125-
const lowerSearch = searchText.toLowerCase();
135+
const filteredClusters =
136+
!searchText && !regionFilter
137+
? clusters
138+
: clusters.filter((cluster) => {
139+
const lowerSearch = searchText.toLowerCase();
126140

127-
return (
128-
cluster.label.toLowerCase().includes(lowerSearch) ||
129-
cluster.region.toLowerCase().includes(lowerSearch) ||
130-
(cluster.control_plane.audit_logs_enabled
131-
? 'enabled'
132-
: 'disabled'
133-
).includes(lowerSearch)
134-
);
135-
});
141+
let result = true;
142+
143+
if (searchText) {
144+
result =
145+
cluster.label.toLowerCase().includes(lowerSearch) ||
146+
cluster.region.toLowerCase().includes(lowerSearch) ||
147+
(cluster.control_plane.audit_logs_enabled
148+
? 'enabled'
149+
: 'disabled'
150+
).includes(lowerSearch);
151+
}
152+
153+
if (result && regionFilter) {
154+
return cluster.region === regionFilter;
155+
}
156+
157+
return result;
158+
});
136159

137160
const sortedAndFilteredClusters = sortData<KubernetesCluster>(
138161
orderBy,
@@ -201,24 +224,49 @@ export const StreamFormClusters = (props: StreamFormClustersProps) => {
201224
)}
202225
/>
203226
</div>
204-
<DebouncedSearchTextField
205-
clearable
206-
containerProps={{
207-
sx: {
208-
width: '40%',
209-
mt: 2,
210-
},
211-
}}
212-
debounceTime={250}
213-
hideLabel
214-
inputProps={{
215-
'data-pendo-id': `Logs Delivery Streams ${capitalize(mode)}-Clusters-Search`,
227+
<StyledGrid
228+
sx={{
229+
alignItems: 'center',
230+
display: 'flex',
231+
flexWrap: xsDown ? 'wrap' : 'nowrap',
232+
gap: 3,
233+
justifyContent: 'space-between',
234+
flex: '1 1 auto',
235+
mt: 2,
216236
}}
217-
label="Search"
218-
onSearch={(value) => setSearchText(value)}
219-
placeholder="Search"
220-
value={searchText}
221-
/>
237+
>
238+
<DebouncedSearchTextField
239+
clearable
240+
containerProps={{
241+
sx: {
242+
width: '40%',
243+
},
244+
}}
245+
debounceTime={250}
246+
hideLabel
247+
inputProps={{
248+
'data-pendo-id': `Logs Delivery Streams ${capitalize(mode)}-Clusters-Search`,
249+
}}
250+
label="Search"
251+
onSearch={(value) => setSearchText(value)}
252+
placeholder="Search"
253+
value={searchText}
254+
/>
255+
<RegionSelect
256+
currentCapability="Object Storage"
257+
isGeckoLAEnabled={isGeckoLAEnabled}
258+
label="Region"
259+
onChange={(_, region) => {
260+
setRegionFilter(region?.id ?? '');
261+
}}
262+
regionFilter="core"
263+
regions={regions ?? []}
264+
sx={{
265+
width: '280px !important',
266+
}}
267+
value={regionFilter}
268+
/>
269+
</StyledGrid>
222270
<Box sx={{ mt: 2 }}>
223271
{!isAutoAddAllClustersEnabled &&
224272
formState.errors.stream?.details?.cluster_ids?.message && (
@@ -258,3 +306,18 @@ export const StreamFormClusters = (props: StreamFormClustersProps) => {
258306
</Paper>
259307
);
260308
};
309+
310+
const StyledGrid = styled(Grid)(({ theme }) => ({
311+
'& .MuiAutocomplete-root > .MuiBox-root': {
312+
display: 'flex',
313+
314+
'& > .MuiBox-root': {
315+
margin: '0',
316+
317+
'& > .MuiInputLabel-root': {
318+
margin: 0,
319+
marginRight: theme.spacingFunction(12),
320+
},
321+
},
322+
},
323+
}));

packages/manager/src/features/Delivery/Streams/StreamForm/Delivery/DestinationAkamaiObjectStorageDetailsSummary.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ describe('DestinationAkamaiObjectStorageDetailsSummary', () => {
3737
);
3838
});
3939

40-
it('renders info icon next to path when it is empty', async () => {
40+
it('does not render log path when it is empty', async () => {
4141
const details = {
4242
bucket_name: 'test bucket',
4343
host: 'test host',
@@ -49,6 +49,6 @@ describe('DestinationAkamaiObjectStorageDetailsSummary', () => {
4949
);
5050

5151
// Log Path info icon:
52-
expect(screen.getByTestId('tooltip-info-icon')).toBeVisible();
52+
expect(screen.queryByText('tooltip-info-icon')).not.toBeInTheDocument();
5353
});
5454
});
Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
1-
import { streamType } from '@linode/api-v4';
2-
import { Stack, TooltipIcon, Typography } from '@linode/ui';
31
import React from 'react';
42

5-
import { getStreamTypeOption } from 'src/features/Delivery/deliveryUtils';
63
import { LabelValue } from 'src/features/Delivery/Shared/LabelValue';
74

85
import type { AkamaiObjectStorageDetails } from '@linode/api-v4';
96

10-
const sxTooltipIcon = {
11-
marginLeft: '4px',
12-
padding: '0px',
13-
};
14-
157
export const DestinationAkamaiObjectStorageDetailsSummary = (
168
props: AkamaiObjectStorageDetails
179
) => {
@@ -24,28 +16,16 @@ export const DestinationAkamaiObjectStorageDetailsSummary = (
2416
<LabelValue
2517
data-testid="access-key-id"
2618
label="Access Key ID"
19+
smHideTooltip={true}
2720
value="*****************"
2821
/>
2922
<LabelValue
3023
data-testid="secret-access-key"
3124
label="Secret Access Key"
25+
smHideTooltip={true}
3226
value="*****************"
3327
/>
34-
<LabelValue label="Log Path" value={path}>
35-
{!path && (
36-
<TooltipIcon
37-
status="info"
38-
sxTooltipIcon={sxTooltipIcon}
39-
text={
40-
<Stack spacing={2}>
41-
<Typography>Default paths:</Typography>
42-
<Typography>{`${getStreamTypeOption(streamType.LKEAuditLogs)?.label} - {stream_type}/{log_type}/ {account}/{partition}/ {%Y/%m/%d/}`}</Typography>
43-
<Typography>{`${getStreamTypeOption(streamType.AuditLogs)?.label} - {stream_type}/{log_type}/ {account}/{%Y/%m/%d/}`}</Typography>
44-
</Stack>
45-
}
46-
/>
47-
)}
48-
</LabelValue>
28+
{!!path && <LabelValue label="Log Path" value={path} />}
4929
</>
5030
);
5131
};

packages/manager/src/features/Delivery/Streams/StreamForm/StreamFormGeneralInfo.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ export const StreamFormGeneralInfo = (props: StreamFormGeneralInfoProps) => {
3939
const capitalizedMode = capitalize(mode);
4040
const description = {
4141
audit_logs:
42-
'Configuration and authentication audit logs that capture state-changing operations (mutations) on Linode cloud infrastructure resources and IAM authentication events. Delivered in cloudevents.io JSON format.',
42+
'Audit logs record state-changing operations on cloud resources and authentication events, delivered in CloudEvents JSON format.',
4343
lke_audit_logs:
44-
'Kubernetes API server audit logs that capture state-changing operations (mutations) on LKE-E cluster resources.',
44+
'Kubernetes API server audit logs capture state-changing operations on LKE-E cluster resources.',
4545
};
4646
const pendoIds = {
4747
audit_logs: `Logs Delivery Streams ${capitalizedMode}-Audit Logs`,
@@ -136,6 +136,7 @@ export const StreamFormGeneralInfo = (props: StreamFormGeneralInfoProps) => {
136136
sx={{
137137
mt: theme.spacingFunction(16),
138138
maxWidth: 480,
139+
whiteSpace: 'preserve-spaces',
139140
}}
140141
>
141142
{description[selectedStreamType]}

0 commit comments

Comments
 (0)