Skip to content

Commit 8c91ede

Browse files
upcoming: [DPS-34041] Add actions in Destinations list (linode#12749)
* upcoming: [DPS-34041] Add actions in Destinations list * upcoming: [DPS-34041] CR changes 1 --------- Co-authored-by: Mariah Jacobs <[email protected]>
1 parent 655c6b6 commit 8c91ede

30 files changed

+870
-187
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/api-v4": Upcoming Features
3+
---
4+
5+
DELETE, PUT API endpoints for Destinations ([#12749](https://github.com/linode/manager/pull/12749))

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ export const EventActionKeys = [
344344
'database_migrate',
345345
'database_upgrade',
346346
'destination_create',
347+
'destination_delete',
348+
'destination_update',
347349
'disk_create',
348350
'disk_delete',
349351
'disk_duplicate',

packages/api-v4/src/datastream/destinations.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createDestinationSchema } from '@linode/validation';
1+
import { destinationSchema } from '@linode/validation';
22

33
import { BETA_API_ROOT } from '../constants';
44
import Request, {
@@ -10,7 +10,11 @@ import Request, {
1010
} from '../request';
1111

1212
import type { Filter, ResourcePage as Page, Params } from '../types';
13-
import type { CreateDestinationPayload, Destination } from './types';
13+
import type {
14+
CreateDestinationPayload,
15+
Destination,
16+
UpdateDestinationPayload,
17+
} from './types';
1418

1519
/**
1620
* Returns all the information about a specified Destination.
@@ -45,7 +49,38 @@ export const getDestinations = (params?: Params, filter?: Filter) =>
4549
*/
4650
export const createDestination = (data: CreateDestinationPayload) =>
4751
Request<Destination>(
48-
setData(data, createDestinationSchema),
52+
setData(data, destinationSchema),
4953
setURL(`${BETA_API_ROOT}/monitor/streams/destinations`),
5054
setMethod('POST'),
5155
);
56+
57+
/**
58+
* Updates a Destination.
59+
*
60+
* @param destinationId { number } The ID of the Destination.
61+
* @param data { object } Options for type, label, etc.
62+
*/
63+
export const updateDestination = (
64+
destinationId: number,
65+
data: UpdateDestinationPayload,
66+
) =>
67+
Request<Destination>(
68+
setData(data, destinationSchema),
69+
setURL(
70+
`${BETA_API_ROOT}/monitor/streams/destinations/${encodeURIComponent(destinationId)}`,
71+
),
72+
setMethod('PUT'),
73+
);
74+
75+
/**
76+
* Deletes a Destination.
77+
*
78+
* @param destinationId { number } The ID of the Destination.
79+
*/
80+
export const deleteDestination = (destinationId: number) =>
81+
Request<{}>(
82+
setURL(
83+
`${BETA_API_ROOT}/monitor/streams/destinations/${encodeURIComponent(destinationId)}`,
84+
),
85+
setMethod('DELETE'),
86+
);

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,10 @@ export interface CreateDestinationPayload {
126126
label: string;
127127
type: DestinationType;
128128
}
129+
130+
export type UpdateDestinationPayload = CreateDestinationPayload;
131+
132+
export interface UpdateDestinationPayloadWithId
133+
extends UpdateDestinationPayload {
134+
id: number;
135+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Upcoming Features
3+
---
4+
5+
DataStreams: add actions with handlers in Destinations list, add Edit Destination component ([#12749](https://github.com/linode/manager/pull/12749))
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { screen } from '@testing-library/react';
2+
import { userEvent } from '@testing-library/user-event';
3+
import * as React from 'react';
4+
5+
import { destinationFactory } from 'src/factories/datastream';
6+
import { DestinationActionMenu } from 'src/features/DataStream/Destinations/DestinationActionMenu';
7+
import { renderWithTheme } from 'src/utilities/testHelpers';
8+
9+
const fakeHandler = vi.fn();
10+
11+
describe('DestinationActionMenu', () => {
12+
it('should include proper Stream actions', async () => {
13+
renderWithTheme(
14+
<DestinationActionMenu
15+
destination={destinationFactory.build()}
16+
onDelete={fakeHandler}
17+
onEdit={fakeHandler}
18+
/>
19+
);
20+
21+
const actionMenuButton = screen.queryByLabelText(/^Action menu for/)!;
22+
23+
await userEvent.click(actionMenuButton);
24+
25+
for (const action of ['Edit', 'Delete']) {
26+
expect(screen.getByText(action)).toBeVisible();
27+
}
28+
});
29+
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as React from 'react';
2+
3+
import { ActionMenu } from 'src/components/ActionMenu/ActionMenu';
4+
5+
import type { Destination } from '@linode/api-v4';
6+
7+
export interface DestinationHandlers {
8+
onDelete: (destination: Destination) => void;
9+
onEdit: (destination: Destination) => void;
10+
}
11+
12+
interface DestinationActionMenuProps extends DestinationHandlers {
13+
destination: Destination;
14+
}
15+
16+
export const DestinationActionMenu = (props: DestinationActionMenuProps) => {
17+
const { destination, onDelete, onEdit } = props;
18+
19+
const menuActions = [
20+
{
21+
onClick: () => {
22+
onEdit(destination);
23+
},
24+
title: 'Edit',
25+
},
26+
{
27+
onClick: () => {
28+
onDelete(destination);
29+
},
30+
title: 'Delete',
31+
},
32+
];
33+
34+
return (
35+
<ActionMenu
36+
actionsList={menuActions}
37+
ariaLabel={`Action menu for Destination ${destination.label}`}
38+
/>
39+
);
40+
};

packages/manager/src/features/DataStream/Destinations/DestinationCreate/DestinationCreate.tsx

Lines changed: 0 additions & 131 deletions
This file was deleted.

packages/manager/src/features/DataStream/Destinations/DestinationCreate/DestinationCreate.test.tsx renamed to packages/manager/src/features/DataStream/Destinations/DestinationForm/DestinationCreate.test.tsx

File renamed without changes.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { yupResolver } from '@hookform/resolvers/yup';
2+
import { destinationType } from '@linode/api-v4';
3+
import { useCreateDestinationMutation } from '@linode/queries';
4+
import { destinationSchema } from '@linode/validation';
5+
import { useNavigate } from '@tanstack/react-router';
6+
import * as React from 'react';
7+
import { FormProvider, useForm } from 'react-hook-form';
8+
9+
import { DocumentTitleSegment } from 'src/components/DocumentTitle';
10+
import { LandingHeader } from 'src/components/LandingHeader';
11+
import { DestinationForm } from 'src/features/DataStream/Destinations/DestinationForm/DestinationForm';
12+
13+
import type { LandingHeaderProps } from 'src/components/LandingHeader';
14+
import type { DestinationFormType } from 'src/features/DataStream/Shared/types';
15+
16+
export const DestinationCreate = () => {
17+
const { mutateAsync: createDestination } = useCreateDestinationMutation();
18+
const navigate = useNavigate();
19+
20+
const landingHeaderProps: LandingHeaderProps = {
21+
breadcrumbProps: {
22+
pathname: '/datastream/destinations/create',
23+
crumbOverrides: [
24+
{
25+
label: 'DataStream',
26+
linkTo: '/datastream/destinations',
27+
position: 1,
28+
},
29+
],
30+
},
31+
removeCrumbX: 2,
32+
title: 'Create Destination',
33+
};
34+
35+
const form = useForm<DestinationFormType>({
36+
defaultValues: {
37+
type: destinationType.LinodeObjectStorage,
38+
details: {
39+
region: '',
40+
},
41+
},
42+
mode: 'onBlur',
43+
resolver: yupResolver(destinationSchema),
44+
});
45+
46+
const onSubmit = () => {
47+
const payload = form.getValues();
48+
createDestination(payload).then(() => {
49+
navigate({ to: '/datastream/destinations' });
50+
});
51+
};
52+
53+
return (
54+
<>
55+
<DocumentTitleSegment segment="Create Destination" />
56+
<LandingHeader {...landingHeaderProps} />
57+
<FormProvider {...form}>
58+
<DestinationForm mode="create" onSubmit={onSubmit} />
59+
</FormProvider>
60+
</>
61+
);
62+
};

0 commit comments

Comments
 (0)