Skip to content

Commit 928b39f

Browse files
change: [DPS-35018] - Logs: Add new status - Provisioning (#13284)
* change: [DPS-35018] - Logs: Add new status - Provisioning * Added changeset: Logs Stream - Provisioning status
1 parent 5793cfc commit 928b39f

File tree

9 files changed

+90
-6
lines changed

9 files changed

+90
-6
lines changed

packages/api-v4/src/delivery/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export const streamStatus = {
22
Active: 'active',
33
Inactive: 'inactive',
4+
Provisioning: 'provisioning',
45
} as const;
56

67
export type StreamStatus = (typeof streamStatus)[keyof typeof streamStatus];
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Added
3+
---
4+
5+
Logs Stream - Provisioning status ([#13284](https://github.com/linode/manager/pull/13284))

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ interface StreamFormSubmitBarProps {
2121
mode: FormMode;
2222
onSubmit: () => void;
2323
onTestConnection: () => void;
24+
submitButtonTooltip?: string;
2425
}
2526

2627
export const FormSubmitBar = (props: StreamFormSubmitBarProps) => {
@@ -35,6 +36,7 @@ export const FormSubmitBar = (props: StreamFormSubmitBarProps) => {
3536
isSubmitting,
3637
isTesting,
3738
disableTestConnection = false,
39+
submitButtonTooltip,
3840
} = props;
3941

4042
const capitalizedFormType = capitalize(formType);
@@ -108,6 +110,7 @@ export const FormSubmitBar = (props: StreamFormSubmitBarProps) => {
108110
alignSelf: 'flex-end',
109111
},
110112
})}
113+
tooltipText={submitButtonTooltip}
111114
>
112115
{buttonLabel}
113116
</Button>

packages/manager/src/features/Delivery/Shared/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ export const streamStatusOptions: AutocompleteOption[] = [
4848
label: 'Inactive',
4949
pendoId: 'Logs Delivery Streams-Status Inactive',
5050
},
51+
{
52+
value: streamStatus.Provisioning,
53+
label: 'Provisioning',
54+
pendoId: 'Logs Delivery Streams-Status Provisioning',
55+
},
5156
];
5257

5358
export type DestinationDetailsForm =

packages/manager/src/features/Delivery/Streams/StreamActionMenu.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const StreamActionMenu = (props: StreamActionMenuProps) => {
3232
},
3333
title: stream.status === streamStatus.Active ? 'Deactivate' : 'Activate',
3434
pendoId: `Logs Delivery Streams-${stream.status === streamStatus.Active ? 'Deactivate' : 'Activate'}`,
35+
disabled: stream.status === streamStatus.Provisioning,
3536
},
3637
{
3738
onClick: () => {

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,48 @@ describe('StreamEdit', () => {
224224
expect(editStreamSpy).toHaveBeenCalled();
225225
});
226226
});
227+
228+
describe('and stream has status: provisioning', () => {
229+
it('should have disabled Edit Stream button and show info tooltip', async () => {
230+
server.use(
231+
http.get('*/monitor/streams/destinations', () => {
232+
return HttpResponse.json(makeResourcePage(mockDestinations));
233+
}),
234+
http.get(`*/monitor/streams/${streamId}`, () => {
235+
return HttpResponse.json({
236+
...mockStream,
237+
status: 'provisioning',
238+
});
239+
})
240+
);
241+
242+
renderWithThemeAndHookFormContext({
243+
component: <StreamEdit />,
244+
});
245+
const loadingElement = screen.queryByTestId(loadingTestId);
246+
await waitForElementToBeRemoved(loadingElement);
247+
248+
const editStreamButton = screen.getByRole('button', {
249+
name: saveStreamButtonText,
250+
});
251+
252+
// Edit stream button should be disabled
253+
expect(editStreamButton).toBeDisabled();
254+
255+
// Edit stream
256+
await userEvent.hover(editStreamButton);
257+
258+
await waitFor(() => {
259+
expect(screen.getByRole('tooltip')).toBeInTheDocument();
260+
});
261+
262+
const disabledButtonTooltip = screen.getByText(
263+
'You cannot save changes while the stream is provisioning.'
264+
);
265+
266+
expect(disabledButtonTooltip).toBeInTheDocument();
267+
});
268+
});
227269
});
228270
});
229271

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
type CreateDestinationPayload,
3+
streamStatus,
34
type StreamStatus,
45
streamType,
56
} from '@linode/api-v4';
@@ -14,7 +15,7 @@ import Grid from '@mui/material/Grid';
1415
import { useNavigate } from '@tanstack/react-router';
1516
import { enqueueSnackbar } from 'notistack';
1617
import * as React from 'react';
17-
import { useEffect, useState } from 'react';
18+
import { useEffect, useMemo, useState } from 'react';
1819
import { type SubmitHandler, useFormContext, useWatch } from 'react-hook-form';
1920

2021
import {
@@ -72,6 +73,18 @@ export const StreamForm = (props: StreamFormProps) => {
7273
name: 'destination',
7374
});
7475

76+
const selectedStreamStatus = useWatch({
77+
control,
78+
name: 'stream.status',
79+
});
80+
const submitButtonTooltip = useMemo(
81+
() =>
82+
selectedStreamStatus === streamStatus.Provisioning
83+
? 'You cannot save changes while the stream is provisioning.'
84+
: undefined,
85+
[selectedStreamStatus]
86+
);
87+
7588
useEffect(() => {
7689
setDestinationVerified(false);
7790
}, [destination, setDestinationVerified]);
@@ -194,7 +207,10 @@ export const StreamForm = (props: StreamFormProps) => {
194207
</Grid>
195208
<Grid size={{ lg: 3, md: 12, sm: 12, xs: 12 }}>
196209
<FormSubmitBar
197-
blockSubmit={!selectedDestinations?.length}
210+
blockSubmit={
211+
selectedStreamStatus === streamStatus.Provisioning ||
212+
!selectedDestinations?.length
213+
}
198214
connectionTested={destinationVerified}
199215
destinationType={destination?.type}
200216
disableTestConnection={disableTestConnection}
@@ -206,6 +222,7 @@ export const StreamForm = (props: StreamFormProps) => {
206222
scrollErrorIntoViewV2(formRef)
207223
)}
208224
onTestConnection={handleTestConnection}
225+
submitButtonTooltip={submitButtonTooltip}
209226
/>
210227
</Grid>
211228
</Grid>

packages/manager/src/features/Delivery/Streams/StreamTableRow.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { LinkWithTooltipAndEllipsis } from 'src/features/Delivery/Shared/LinkWit
1313
import { StreamActionMenu } from 'src/features/Delivery/Streams/StreamActionMenu';
1414

1515
import type { Stream, StreamStatus } from '@linode/api-v4';
16+
import type { Status } from 'src/components/StatusIcon/StatusIcon';
1617
import type { StreamHandlers } from 'src/features/Delivery/Streams/StreamActionMenu';
1718

1819
interface StreamTableRowProps extends StreamHandlers {
@@ -22,6 +23,9 @@ interface StreamTableRowProps extends StreamHandlers {
2223
export const StreamTableRow = React.memo((props: StreamTableRowProps) => {
2324
const { stream, onDelete, onDisableOrEnable, onEdit } = props;
2425
const { id, status } = stream;
26+
const iconStatus = (
27+
['active', 'error', 'inactive'].includes(status) ? status : 'other'
28+
) as Status;
2529

2630
return (
2731
<TableRow key={id}>
@@ -35,7 +39,7 @@ export const StreamTableRow = React.memo((props: StreamTableRowProps) => {
3539
</TableCell>
3640
<TableCell>{getStreamTypeOption(stream.type)?.label}</TableCell>
3741
<TableCell statusCell>
38-
<StatusIcon status={status} />
42+
<StatusIcon pulse={false} status={iconStatus} />
3943
{humanizeStreamStatus(status)}
4044
</TableCell>
4145
<TableCell>{id}</TableCell>
@@ -70,6 +74,8 @@ const humanizeStreamStatus = (status: StreamStatus) => {
7074
return 'Active';
7175
case 'inactive':
7276
return 'Inactive';
77+
case 'provisioning':
78+
return 'Provisioning';
7379
default:
7480
return 'Unknown';
7581
}

packages/validation/src/delivery.schema.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,11 @@ const streamSchemaBase = object({
212212
.min(3, 'Stream name must have at least 3 characters')
213213
.max(maxLength, maxLengthMessage)
214214
.required('Stream name is required.'),
215-
status: mixed<'active' | 'inactive'>().oneOf(['active', 'inactive']),
215+
status: mixed<'active' | 'inactive' | 'provisioning'>().oneOf([
216+
'active',
217+
'inactive',
218+
'provisioning',
219+
]),
216220
type: string()
217221
.oneOf(['audit_logs', 'lke_audit_logs'])
218222
.required('Stream type is required.'),
@@ -229,8 +233,8 @@ export const createStreamSchema = streamSchemaBase;
229233
export const updateStreamSchema = streamSchemaBase
230234
.omit(['type'])
231235
.shape({
232-
status: mixed<'active' | 'inactive'>()
233-
.oneOf(['active', 'inactive'])
236+
status: mixed<'active' | 'inactive' | 'provisioning'>()
237+
.oneOf(['active', 'inactive', 'provisioning'])
234238
.required(),
235239
details: lazy((value) => {
236240
if (

0 commit comments

Comments
 (0)