Skip to content

Commit 2212a19

Browse files
authored
🌊 Streams: Convert legacy types in frontend (#208608)
This PR gets rid of the usage of the legacy "readdefinition" types in the frontend except for the enrichment view, because @tonyghiani is working on that in parallel. I first looked into whether we can just use the existing `IngestStreamGetResponse` type, but since it doesn't carry the name of the stream, that is actually super annoying to use - passing the name as a separate argument is pretty annoying and increases the risk of bugs. Even though it's not fully "Elasticsearch"-y, I decided to add the stream name to the `IngestStreamGetResponse` - this way the `stream` property in the response is a regular `StreamDefinition`, so all the functions that act on it can use it right away. This simplifies the frontend code without hurting programmatic API users.
1 parent aec58c1 commit 2212a19

File tree

19 files changed

+171
-160
lines changed

19 files changed

+171
-160
lines changed

‎x-pack/solutions/observability/packages/kbn-streams-schema/src/models/ingest/api.ts‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ import {
1919
WiredIngest,
2020
WiredStreamDefinition,
2121
unwiredIngestSchema,
22+
unwiredStreamDefinitionSchema,
2223
unwiredStreamDefinitionSchemaBase,
2324
wiredIngestSchema,
25+
wiredStreamDefinitionSchema,
2426
wiredStreamDefinitionSchemaBase,
2527
} from './base';
2628
import { ElasticsearchAsset, elasticsearchAssetSchema } from './common';
@@ -73,13 +75,13 @@ const ingestUpsertRequestSchema: z.Schema<IngestUpsertRequest> = z.union([
7375
* Stream get response
7476
*/
7577
interface WiredStreamGetResponse extends StreamGetResponseBase {
76-
stream: Omit<WiredStreamDefinition, 'name'>;
78+
stream: WiredStreamDefinition;
7779
inherited_fields: InheritedFieldDefinition;
7880
effective_lifecycle: WiredIngestStreamEffectiveLifecycle;
7981
}
8082

8183
interface UnwiredStreamGetResponse extends StreamGetResponseBase {
82-
stream: Omit<UnwiredStreamDefinition, 'name'>;
84+
stream: UnwiredStreamDefinition;
8385
elasticsearch_assets: ElasticsearchAsset[];
8486
data_stream_exists: boolean;
8587
effective_lifecycle: UnwiredIngestStreamEffectiveLifecycle;
@@ -123,7 +125,7 @@ const ingestStreamUpsertRequestSchema: z.Schema<IngestStreamUpsertRequest> = z.u
123125
const wiredStreamGetResponseSchema: z.Schema<WiredStreamGetResponse> = z.intersection(
124126
streamGetResponseSchemaBase,
125127
z.object({
126-
stream: wiredStreamDefinitionSchemaBase,
128+
stream: wiredStreamDefinitionSchema,
127129
inherited_fields: inheritedFieldDefinitionSchema,
128130
effective_lifecycle: wiredIngestStreamEffectiveLifecycleSchema,
129131
})
@@ -132,7 +134,7 @@ const wiredStreamGetResponseSchema: z.Schema<WiredStreamGetResponse> = z.interse
132134
const unwiredStreamGetResponseSchema: z.Schema<UnwiredStreamGetResponse> = z.intersection(
133135
streamGetResponseSchemaBase,
134136
z.object({
135-
stream: unwiredStreamDefinitionSchemaBase,
137+
stream: unwiredStreamDefinitionSchema,
136138
elasticsearch_assets: z.array(elasticsearchAssetSchema),
137139
data_stream_exists: z.boolean(),
138140
effective_lifecycle: unwiredIngestStreamEffectiveLifecycleSchema,

‎x-pack/solutions/observability/plugins/streams/server/routes/streams/crud/read_stream.ts‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* 2.0.
66
*/
77

8-
import { omit } from 'lodash';
98
import {
109
IngestStreamGetResponse,
1110
InheritedFieldDefinition,
@@ -50,7 +49,7 @@ export async function readStream({
5049

5150
if (isUnwiredStreamDefinition(streamDefinition)) {
5251
return {
53-
stream: omit(streamDefinition, 'name'),
52+
stream: streamDefinition,
5453
elasticsearch_assets: dataStream
5554
? await getUnmanagedElasticsearchAssets({
5655
dataStream,
@@ -65,7 +64,7 @@ export async function readStream({
6564
}
6665

6766
const body: WiredStreamGetResponse = {
68-
stream: omit(streamDefinition, 'name'),
67+
stream: streamDefinition,
6968
dashboards,
7069
effective_lifecycle: findInheritedLifecycle(streamDefinition, ancestors),
7170
inherited_fields: ancestors.reduce((acc, def) => {

‎x-pack/solutions/observability/plugins/streams_app/public/components/entity_detail_view/index.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { css } from '@emotion/css';
1111
import { ILM_LOCATOR_ID, IlmLocatorParams } from '@kbn/index-lifecycle-management-common-shared';
1212
import {
1313
IngestStreamEffectiveLifecycle,
14-
ReadStreamDefinition,
14+
IngestStreamGetResponse,
1515
isDslLifecycle,
1616
isErrorLifecycle,
1717
isIlmLifecycle,
@@ -44,7 +44,7 @@ export function EntityDetailViewWithoutParams({
4444
displayName?: string;
4545
id: string;
4646
};
47-
definition?: ReadStreamDefinition;
47+
definition?: IngestStreamGetResponse;
4848
}) {
4949
const router = useStreamsAppRouter();
5050
useStreamsAppBreadcrumbs(() => {

‎x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_dashboards_view/index.tsx‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,25 @@
66
*/
77
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSearchBar } from '@elastic/eui';
88
import { i18n } from '@kbn/i18n';
9-
import { ReadStreamDefinition } from '@kbn/streams-schema';
109
import React, { useMemo, useState } from 'react';
1110
import type { SanitizedDashboardAsset } from '@kbn/streams-plugin/server/routes/dashboards/route';
11+
import { IngestStreamGetResponse } from '@kbn/streams-schema';
1212
import { AddDashboardFlyout } from './add_dashboard_flyout';
1313
import { DashboardsTable } from './dashboard_table';
1414
import { useDashboardsApi } from '../../hooks/use_dashboards_api';
1515
import { useDashboardsFetch } from '../../hooks/use_dashboards_fetch';
1616

17-
export function StreamDetailDashboardsView({ definition }: { definition?: ReadStreamDefinition }) {
17+
export function StreamDetailDashboardsView({
18+
definition,
19+
}: {
20+
definition?: IngestStreamGetResponse;
21+
}) {
1822
const [query, setQuery] = useState('');
1923

2024
const [isAddDashboardFlyoutOpen, setIsAddDashboardFlyoutOpen] = useState(false);
2125

22-
const dashboardsFetch = useDashboardsFetch(definition?.name);
23-
const { addDashboards, removeDashboards } = useDashboardsApi(definition?.name);
26+
const dashboardsFetch = useDashboardsFetch(definition?.stream.name);
27+
const { addDashboards, removeDashboards } = useDashboardsApi(definition?.stream.name);
2428

2529
const [isUnlinkLoading, setIsUnlinkLoading] = useState(false);
2630
const linkedDashboards = useMemo(() => {
@@ -95,7 +99,7 @@ export function StreamDetailDashboardsView({ definition }: { definition?: ReadSt
9599
{definition && isAddDashboardFlyoutOpen ? (
96100
<AddDashboardFlyout
97101
linkedDashboards={linkedDashboards}
98-
entityId={definition.name}
102+
entityId={definition.stream.name}
99103
onAddDashboards={async (dashboards) => {
100104
await addDashboards(dashboards);
101105
await dashboardsFetch.refresh();

‎x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/classic.tsx‎

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* 2.0; you may not use this file except in compliance with the Elastic License
55
* 2.0.
66
*/
7-
import React from 'react';
7+
import React, { useMemo } from 'react';
88
import { i18n } from '@kbn/i18n';
9-
import { UnwiredReadStreamDefinition } from '@kbn/streams-schema';
9+
import { UnwiredStreamGetResponse } from '@kbn/streams-schema';
1010
import { EuiCallOut, EuiFlexGroup, EuiListGroup, EuiText } from '@elastic/eui';
1111
import { useStreamsAppParams } from '../../hooks/use_streams_app_params';
1212
import { RedirectTo } from '../redirect_to';
@@ -24,13 +24,30 @@ export function ClassicStreamDetailManagement({
2424
definition,
2525
refreshDefinition,
2626
}: {
27-
definition: UnwiredReadStreamDefinition;
27+
definition: UnwiredStreamGetResponse;
2828
refreshDefinition: () => void;
2929
}) {
3030
const {
3131
path: { key, subtab },
3232
} = useStreamsAppParams('/{key}/management/{subtab}');
3333

34+
const legacyDefinition = useMemo(() => {
35+
if (!definition) {
36+
return undefined;
37+
}
38+
return {
39+
dashboards: definition.dashboards,
40+
elasticsearch_assets: definition.elasticsearch_assets,
41+
inherited_fields: {},
42+
effective_lifecycle: definition.effective_lifecycle,
43+
name: definition.stream.name,
44+
data_stream_exists: definition.data_stream_exists,
45+
stream: {
46+
...definition.stream,
47+
},
48+
};
49+
}, [definition]);
50+
3451
const tabs: ManagementTabs = {
3552
overview: {
3653
content: <UnmanagedStreamOverview definition={definition} />,
@@ -43,7 +60,10 @@ export function ClassicStreamDetailManagement({
4360
if (definition.data_stream_exists) {
4461
tabs.enrich = {
4562
content: (
46-
<StreamDetailEnrichment definition={definition} refreshDefinition={refreshDefinition} />
63+
<StreamDetailEnrichment
64+
definition={legacyDefinition}
65+
refreshDefinition={refreshDefinition}
66+
/>
4767
),
4868
label: i18n.translate('xpack.streams.streamDetailView.enrichmentTab', {
4969
defaultMessage: 'Extract field',
@@ -63,7 +83,7 @@ export function ClassicStreamDetailManagement({
6383
return <Wrapper tabs={tabs} streamId={key} subtab={subtab} />;
6484
}
6585

66-
function UnmanagedStreamOverview({ definition }: { definition: UnwiredReadStreamDefinition }) {
86+
function UnmanagedStreamOverview({ definition }: { definition: UnwiredStreamGetResponse }) {
6787
const {
6888
core: {
6989
http: { basePath },

‎x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/index.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* 2.0.
66
*/
77
import React from 'react';
8-
import { isWiredReadStream, ReadStreamDefinition } from '@kbn/streams-schema';
8+
import { IngestStreamGetResponse, isWiredStreamGetResponse } from '@kbn/streams-schema';
99
import { WiredStreamDetailManagement } from './wired';
1010
import { ClassicStreamDetailManagement } from './classic';
1111

@@ -14,15 +14,15 @@ export function StreamDetailManagement({
1414
refreshDefinition,
1515
isLoadingDefinition,
1616
}: {
17-
definition?: ReadStreamDefinition;
17+
definition?: IngestStreamGetResponse;
1818
refreshDefinition: () => void;
1919
isLoadingDefinition: boolean;
2020
}) {
2121
if (!definition) {
2222
return null;
2323
}
2424

25-
if (isWiredReadStream(definition)) {
25+
if (isWiredStreamGetResponse(definition)) {
2626
return (
2727
<WiredStreamDetailManagement
2828
definition={definition}

‎x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wired.tsx‎

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* 2.0; you may not use this file except in compliance with the Elastic License
55
* 2.0.
66
*/
7-
import React from 'react';
7+
import React, { useMemo } from 'react';
88
import { i18n } from '@kbn/i18n';
9-
import { WiredReadStreamDefinition } from '@kbn/streams-schema';
9+
import { WiredStreamGetResponse } from '@kbn/streams-schema';
1010
import { useStreamsAppParams } from '../../hooks/use_streams_app_params';
1111
import { RedirectTo } from '../redirect_to';
1212
import { StreamDetailRouting } from '../stream_detail_routing';
@@ -25,14 +25,30 @@ export function WiredStreamDetailManagement({
2525
refreshDefinition,
2626
isLoadingDefinition,
2727
}: {
28-
definition?: WiredReadStreamDefinition;
28+
definition?: WiredStreamGetResponse;
2929
refreshDefinition: () => void;
3030
isLoadingDefinition: boolean;
3131
}) {
3232
const {
3333
path: { key, subtab },
3434
} = useStreamsAppParams('/{key}/management/{subtab}');
3535

36+
const legacyDefinition = useMemo(() => {
37+
if (!definition) {
38+
return undefined;
39+
}
40+
return {
41+
dashboards: definition.dashboards,
42+
inherited_fields: definition.inherited_fields,
43+
elasticsearch_assets: [],
44+
effective_lifecycle: definition.effective_lifecycle,
45+
name: definition.stream.name,
46+
stream: {
47+
...definition.stream,
48+
},
49+
};
50+
}, [definition]);
51+
3652
const tabs = {
3753
route: {
3854
content: (
@@ -44,7 +60,10 @@ export function WiredStreamDetailManagement({
4460
},
4561
enrich: {
4662
content: (
47-
<StreamDetailEnrichment definition={definition} refreshDefinition={refreshDefinition} />
63+
<StreamDetailEnrichment
64+
definition={legacyDefinition}
65+
refreshDefinition={refreshDefinition}
66+
/>
4867
),
4968
label: i18n.translate('xpack.streams.streamDetailView.enrichmentTab', {
5069
defaultMessage: 'Extract field',

‎x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_overview/index.tsx‎

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ import moment from 'moment';
2020
import React, { useMemo } from 'react';
2121
import { css } from '@emotion/css';
2222
import {
23-
ReadStreamDefinition,
24-
isUnwiredReadStream,
25-
isWiredReadStream,
23+
IngestStreamGetResponse,
24+
isUnWiredStreamGetResponse,
2625
isWiredStreamDefinition,
2726
} from '@kbn/streams-schema';
2827
import { useDateRange } from '@kbn/observability-utils-browser/hooks/use_date_range';
@@ -44,7 +43,7 @@ const formatNumber = (val: number) => {
4443
});
4544
};
4645

47-
export function StreamDetailOverview({ definition }: { definition?: ReadStreamDefinition }) {
46+
export function StreamDetailOverview({ definition }: { definition?: IngestStreamGetResponse }) {
4847
const {
4948
dependencies: {
5049
start: {
@@ -131,14 +130,17 @@ export function StreamDetailOverview({ definition }: { definition?: ReadStreamDe
131130

132131
const docCountFetch = useStreamsAppFetch(
133132
async ({ signal }) => {
134-
if (!definition || (isUnwiredReadStream(definition) && !definition.data_stream_exists)) {
133+
if (
134+
!definition ||
135+
(isUnWiredStreamGetResponse(definition) && !definition.data_stream_exists)
136+
) {
135137
return undefined;
136138
}
137139
return streamsRepositoryClient.fetch('GET /api/streams/{id}/_details', {
138140
signal,
139141
params: {
140142
path: {
141-
id: definition.name as string,
143+
id: definition.stream.name,
142144
},
143145
query: {
144146
start: String(start),
@@ -154,14 +156,14 @@ export function StreamDetailOverview({ definition }: { definition?: ReadStreamDe
154156
const [selectedTab, setSelectedTab] = React.useState<string | undefined>(undefined);
155157

156158
const tabs = [
157-
...(definition && isWiredReadStream(definition)
159+
...(definition && isWiredStreamDefinition(definition.stream)
158160
? [
159161
{
160162
id: 'streams',
161163
name: i18n.translate('xpack.streams.entityDetailOverview.tabs.streams', {
162164
defaultMessage: 'Streams',
163165
}),
164-
content: <ChildStreamList stream={definition} />,
166+
content: <ChildStreamList definition={definition} />,
165167
},
166168
]
167169
: []),
@@ -170,7 +172,7 @@ export function StreamDetailOverview({ definition }: { definition?: ReadStreamDe
170172
name: i18n.translate('xpack.streams.entityDetailOverview.tabs.quicklinks', {
171173
defaultMessage: 'Quick Links',
172174
}),
173-
content: <QuickLinks stream={definition} />,
175+
content: <QuickLinks definition={definition} />,
174176
},
175177
];
176178

@@ -274,8 +276,8 @@ export function StreamDetailOverview({ definition }: { definition?: ReadStreamDe
274276

275277
const EMPTY_DASHBOARD_LIST: SanitizedDashboardAsset[] = [];
276278

277-
function QuickLinks({ stream }: { stream?: ReadStreamDefinition }) {
278-
const dashboardsFetch = useDashboardsFetch(stream?.name);
279+
function QuickLinks({ definition }: { definition?: IngestStreamGetResponse }) {
280+
const dashboardsFetch = useDashboardsFetch(definition?.stream.name);
279281

280282
return (
281283
<DashboardsTable
@@ -285,7 +287,7 @@ function QuickLinks({ stream }: { stream?: ReadStreamDefinition }) {
285287
);
286288
}
287289

288-
function ChildStreamList({ stream }: { stream?: ReadStreamDefinition }) {
290+
function ChildStreamList({ definition }: { definition?: IngestStreamGetResponse }) {
289291
const {
290292
dependencies: {
291293
start: {
@@ -305,15 +307,15 @@ function ChildStreamList({ stream }: { stream?: ReadStreamDefinition }) {
305307
);
306308

307309
const childDefinitions = useMemo(() => {
308-
if (!stream) {
310+
if (!definition) {
309311
return [];
310312
}
311313
return streamsListFetch.value?.streams.filter(
312-
(d) => isWiredStreamDefinition(d) && d.name.startsWith(stream.name as string)
314+
(d) => isWiredStreamDefinition(d) && d.name.startsWith(definition.stream.name)
313315
);
314-
}, [stream, streamsListFetch.value?.streams]);
316+
}, [definition, streamsListFetch.value?.streams]);
315317

316-
if (stream && childDefinitions?.length === 1) {
318+
if (definition && childDefinitions?.length === 1) {
317319
return (
318320
<EuiFlexItem grow>
319321
<EuiFlexGroup alignItems="center" justifyContent="center">
@@ -342,7 +344,7 @@ function ChildStreamList({ stream }: { stream?: ReadStreamDefinition }) {
342344
iconType="plusInCircle"
343345
href={router.link('/{key}/management/{subtab}', {
344346
path: {
345-
key: stream?.name as string,
347+
key: definition?.stream.name,
346348
subtab: 'route',
347349
},
348350
})}

0 commit comments

Comments
 (0)