mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
🌊 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.
This commit is contained in:
parent
aec58c14ef
commit
2212a19bc8
19 changed files with 170 additions and 159 deletions
|
@ -19,8 +19,10 @@ import {
|
|||
WiredIngest,
|
||||
WiredStreamDefinition,
|
||||
unwiredIngestSchema,
|
||||
unwiredStreamDefinitionSchema,
|
||||
unwiredStreamDefinitionSchemaBase,
|
||||
wiredIngestSchema,
|
||||
wiredStreamDefinitionSchema,
|
||||
wiredStreamDefinitionSchemaBase,
|
||||
} from './base';
|
||||
import { ElasticsearchAsset, elasticsearchAssetSchema } from './common';
|
||||
|
@ -73,13 +75,13 @@ const ingestUpsertRequestSchema: z.Schema<IngestUpsertRequest> = z.union([
|
|||
* Stream get response
|
||||
*/
|
||||
interface WiredStreamGetResponse extends StreamGetResponseBase {
|
||||
stream: Omit<WiredStreamDefinition, 'name'>;
|
||||
stream: WiredStreamDefinition;
|
||||
inherited_fields: InheritedFieldDefinition;
|
||||
effective_lifecycle: WiredIngestStreamEffectiveLifecycle;
|
||||
}
|
||||
|
||||
interface UnwiredStreamGetResponse extends StreamGetResponseBase {
|
||||
stream: Omit<UnwiredStreamDefinition, 'name'>;
|
||||
stream: UnwiredStreamDefinition;
|
||||
elasticsearch_assets: ElasticsearchAsset[];
|
||||
data_stream_exists: boolean;
|
||||
effective_lifecycle: UnwiredIngestStreamEffectiveLifecycle;
|
||||
|
@ -123,7 +125,7 @@ const ingestStreamUpsertRequestSchema: z.Schema<IngestStreamUpsertRequest> = z.u
|
|||
const wiredStreamGetResponseSchema: z.Schema<WiredStreamGetResponse> = z.intersection(
|
||||
streamGetResponseSchemaBase,
|
||||
z.object({
|
||||
stream: wiredStreamDefinitionSchemaBase,
|
||||
stream: wiredStreamDefinitionSchema,
|
||||
inherited_fields: inheritedFieldDefinitionSchema,
|
||||
effective_lifecycle: wiredIngestStreamEffectiveLifecycleSchema,
|
||||
})
|
||||
|
@ -132,7 +134,7 @@ const wiredStreamGetResponseSchema: z.Schema<WiredStreamGetResponse> = z.interse
|
|||
const unwiredStreamGetResponseSchema: z.Schema<UnwiredStreamGetResponse> = z.intersection(
|
||||
streamGetResponseSchemaBase,
|
||||
z.object({
|
||||
stream: unwiredStreamDefinitionSchemaBase,
|
||||
stream: unwiredStreamDefinitionSchema,
|
||||
elasticsearch_assets: z.array(elasticsearchAssetSchema),
|
||||
data_stream_exists: z.boolean(),
|
||||
effective_lifecycle: unwiredIngestStreamEffectiveLifecycleSchema,
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { omit } from 'lodash';
|
||||
import {
|
||||
IngestStreamGetResponse,
|
||||
InheritedFieldDefinition,
|
||||
|
@ -50,7 +49,7 @@ export async function readStream({
|
|||
|
||||
if (isUnwiredStreamDefinition(streamDefinition)) {
|
||||
return {
|
||||
stream: omit(streamDefinition, 'name'),
|
||||
stream: streamDefinition,
|
||||
elasticsearch_assets: dataStream
|
||||
? await getUnmanagedElasticsearchAssets({
|
||||
dataStream,
|
||||
|
@ -65,7 +64,7 @@ export async function readStream({
|
|||
}
|
||||
|
||||
const body: WiredStreamGetResponse = {
|
||||
stream: omit(streamDefinition, 'name'),
|
||||
stream: streamDefinition,
|
||||
dashboards,
|
||||
effective_lifecycle: findInheritedLifecycle(streamDefinition, ancestors),
|
||||
inherited_fields: ancestors.reduce((acc, def) => {
|
||||
|
|
|
@ -11,7 +11,7 @@ import { css } from '@emotion/css';
|
|||
import { ILM_LOCATOR_ID, IlmLocatorParams } from '@kbn/index-lifecycle-management-common-shared';
|
||||
import {
|
||||
IngestStreamEffectiveLifecycle,
|
||||
ReadStreamDefinition,
|
||||
IngestStreamGetResponse,
|
||||
isDslLifecycle,
|
||||
isErrorLifecycle,
|
||||
isIlmLifecycle,
|
||||
|
@ -44,7 +44,7 @@ export function EntityDetailViewWithoutParams({
|
|||
displayName?: string;
|
||||
id: string;
|
||||
};
|
||||
definition?: ReadStreamDefinition;
|
||||
definition?: IngestStreamGetResponse;
|
||||
}) {
|
||||
const router = useStreamsAppRouter();
|
||||
useStreamsAppBreadcrumbs(() => {
|
||||
|
|
|
@ -6,21 +6,25 @@
|
|||
*/
|
||||
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSearchBar } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ReadStreamDefinition } from '@kbn/streams-schema';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import type { SanitizedDashboardAsset } from '@kbn/streams-plugin/server/routes/dashboards/route';
|
||||
import { IngestStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { AddDashboardFlyout } from './add_dashboard_flyout';
|
||||
import { DashboardsTable } from './dashboard_table';
|
||||
import { useDashboardsApi } from '../../hooks/use_dashboards_api';
|
||||
import { useDashboardsFetch } from '../../hooks/use_dashboards_fetch';
|
||||
|
||||
export function StreamDetailDashboardsView({ definition }: { definition?: ReadStreamDefinition }) {
|
||||
export function StreamDetailDashboardsView({
|
||||
definition,
|
||||
}: {
|
||||
definition?: IngestStreamGetResponse;
|
||||
}) {
|
||||
const [query, setQuery] = useState('');
|
||||
|
||||
const [isAddDashboardFlyoutOpen, setIsAddDashboardFlyoutOpen] = useState(false);
|
||||
|
||||
const dashboardsFetch = useDashboardsFetch(definition?.name);
|
||||
const { addDashboards, removeDashboards } = useDashboardsApi(definition?.name);
|
||||
const dashboardsFetch = useDashboardsFetch(definition?.stream.name);
|
||||
const { addDashboards, removeDashboards } = useDashboardsApi(definition?.stream.name);
|
||||
|
||||
const [isUnlinkLoading, setIsUnlinkLoading] = useState(false);
|
||||
const linkedDashboards = useMemo(() => {
|
||||
|
@ -95,7 +99,7 @@ export function StreamDetailDashboardsView({ definition }: { definition?: ReadSt
|
|||
{definition && isAddDashboardFlyoutOpen ? (
|
||||
<AddDashboardFlyout
|
||||
linkedDashboards={linkedDashboards}
|
||||
entityId={definition.name}
|
||||
entityId={definition.stream.name}
|
||||
onAddDashboards={async (dashboards) => {
|
||||
await addDashboards(dashboards);
|
||||
await dashboardsFetch.refresh();
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { UnwiredReadStreamDefinition } from '@kbn/streams-schema';
|
||||
import { UnwiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { EuiCallOut, EuiFlexGroup, EuiListGroup, EuiText } from '@elastic/eui';
|
||||
import { useStreamsAppParams } from '../../hooks/use_streams_app_params';
|
||||
import { RedirectTo } from '../redirect_to';
|
||||
|
@ -24,13 +24,30 @@ export function ClassicStreamDetailManagement({
|
|||
definition,
|
||||
refreshDefinition,
|
||||
}: {
|
||||
definition: UnwiredReadStreamDefinition;
|
||||
definition: UnwiredStreamGetResponse;
|
||||
refreshDefinition: () => void;
|
||||
}) {
|
||||
const {
|
||||
path: { key, subtab },
|
||||
} = useStreamsAppParams('/{key}/management/{subtab}');
|
||||
|
||||
const legacyDefinition = useMemo(() => {
|
||||
if (!definition) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
dashboards: definition.dashboards,
|
||||
elasticsearch_assets: definition.elasticsearch_assets,
|
||||
inherited_fields: {},
|
||||
effective_lifecycle: definition.effective_lifecycle,
|
||||
name: definition.stream.name,
|
||||
data_stream_exists: definition.data_stream_exists,
|
||||
stream: {
|
||||
...definition.stream,
|
||||
},
|
||||
};
|
||||
}, [definition]);
|
||||
|
||||
const tabs: ManagementTabs = {
|
||||
overview: {
|
||||
content: <UnmanagedStreamOverview definition={definition} />,
|
||||
|
@ -43,7 +60,10 @@ export function ClassicStreamDetailManagement({
|
|||
if (definition.data_stream_exists) {
|
||||
tabs.enrich = {
|
||||
content: (
|
||||
<StreamDetailEnrichment definition={definition} refreshDefinition={refreshDefinition} />
|
||||
<StreamDetailEnrichment
|
||||
definition={legacyDefinition}
|
||||
refreshDefinition={refreshDefinition}
|
||||
/>
|
||||
),
|
||||
label: i18n.translate('xpack.streams.streamDetailView.enrichmentTab', {
|
||||
defaultMessage: 'Extract field',
|
||||
|
@ -63,7 +83,7 @@ export function ClassicStreamDetailManagement({
|
|||
return <Wrapper tabs={tabs} streamId={key} subtab={subtab} />;
|
||||
}
|
||||
|
||||
function UnmanagedStreamOverview({ definition }: { definition: UnwiredReadStreamDefinition }) {
|
||||
function UnmanagedStreamOverview({ definition }: { definition: UnwiredStreamGetResponse }) {
|
||||
const {
|
||||
core: {
|
||||
http: { basePath },
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { isWiredReadStream, ReadStreamDefinition } from '@kbn/streams-schema';
|
||||
import { IngestStreamGetResponse, isWiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { WiredStreamDetailManagement } from './wired';
|
||||
import { ClassicStreamDetailManagement } from './classic';
|
||||
|
||||
|
@ -14,7 +14,7 @@ export function StreamDetailManagement({
|
|||
refreshDefinition,
|
||||
isLoadingDefinition,
|
||||
}: {
|
||||
definition?: ReadStreamDefinition;
|
||||
definition?: IngestStreamGetResponse;
|
||||
refreshDefinition: () => void;
|
||||
isLoadingDefinition: boolean;
|
||||
}) {
|
||||
|
@ -22,7 +22,7 @@ export function StreamDetailManagement({
|
|||
return null;
|
||||
}
|
||||
|
||||
if (isWiredReadStream(definition)) {
|
||||
if (isWiredStreamGetResponse(definition)) {
|
||||
return (
|
||||
<WiredStreamDetailManagement
|
||||
definition={definition}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { WiredReadStreamDefinition } from '@kbn/streams-schema';
|
||||
import { WiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { useStreamsAppParams } from '../../hooks/use_streams_app_params';
|
||||
import { RedirectTo } from '../redirect_to';
|
||||
import { StreamDetailRouting } from '../stream_detail_routing';
|
||||
|
@ -25,7 +25,7 @@ export function WiredStreamDetailManagement({
|
|||
refreshDefinition,
|
||||
isLoadingDefinition,
|
||||
}: {
|
||||
definition?: WiredReadStreamDefinition;
|
||||
definition?: WiredStreamGetResponse;
|
||||
refreshDefinition: () => void;
|
||||
isLoadingDefinition: boolean;
|
||||
}) {
|
||||
|
@ -33,6 +33,22 @@ export function WiredStreamDetailManagement({
|
|||
path: { key, subtab },
|
||||
} = useStreamsAppParams('/{key}/management/{subtab}');
|
||||
|
||||
const legacyDefinition = useMemo(() => {
|
||||
if (!definition) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
dashboards: definition.dashboards,
|
||||
inherited_fields: definition.inherited_fields,
|
||||
elasticsearch_assets: [],
|
||||
effective_lifecycle: definition.effective_lifecycle,
|
||||
name: definition.stream.name,
|
||||
stream: {
|
||||
...definition.stream,
|
||||
},
|
||||
};
|
||||
}, [definition]);
|
||||
|
||||
const tabs = {
|
||||
route: {
|
||||
content: (
|
||||
|
@ -44,7 +60,10 @@ export function WiredStreamDetailManagement({
|
|||
},
|
||||
enrich: {
|
||||
content: (
|
||||
<StreamDetailEnrichment definition={definition} refreshDefinition={refreshDefinition} />
|
||||
<StreamDetailEnrichment
|
||||
definition={legacyDefinition}
|
||||
refreshDefinition={refreshDefinition}
|
||||
/>
|
||||
),
|
||||
label: i18n.translate('xpack.streams.streamDetailView.enrichmentTab', {
|
||||
defaultMessage: 'Extract field',
|
||||
|
|
|
@ -20,9 +20,8 @@ import moment from 'moment';
|
|||
import React, { useMemo } from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import {
|
||||
ReadStreamDefinition,
|
||||
isUnwiredReadStream,
|
||||
isWiredReadStream,
|
||||
IngestStreamGetResponse,
|
||||
isUnWiredStreamGetResponse,
|
||||
isWiredStreamDefinition,
|
||||
} from '@kbn/streams-schema';
|
||||
import { useDateRange } from '@kbn/observability-utils-browser/hooks/use_date_range';
|
||||
|
@ -44,7 +43,7 @@ const formatNumber = (val: number) => {
|
|||
});
|
||||
};
|
||||
|
||||
export function StreamDetailOverview({ definition }: { definition?: ReadStreamDefinition }) {
|
||||
export function StreamDetailOverview({ definition }: { definition?: IngestStreamGetResponse }) {
|
||||
const {
|
||||
dependencies: {
|
||||
start: {
|
||||
|
@ -131,14 +130,17 @@ export function StreamDetailOverview({ definition }: { definition?: ReadStreamDe
|
|||
|
||||
const docCountFetch = useStreamsAppFetch(
|
||||
async ({ signal }) => {
|
||||
if (!definition || (isUnwiredReadStream(definition) && !definition.data_stream_exists)) {
|
||||
if (
|
||||
!definition ||
|
||||
(isUnWiredStreamGetResponse(definition) && !definition.data_stream_exists)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
return streamsRepositoryClient.fetch('GET /api/streams/{id}/_details', {
|
||||
signal,
|
||||
params: {
|
||||
path: {
|
||||
id: definition.name as string,
|
||||
id: definition.stream.name,
|
||||
},
|
||||
query: {
|
||||
start: String(start),
|
||||
|
@ -154,14 +156,14 @@ export function StreamDetailOverview({ definition }: { definition?: ReadStreamDe
|
|||
const [selectedTab, setSelectedTab] = React.useState<string | undefined>(undefined);
|
||||
|
||||
const tabs = [
|
||||
...(definition && isWiredReadStream(definition)
|
||||
...(definition && isWiredStreamDefinition(definition.stream)
|
||||
? [
|
||||
{
|
||||
id: 'streams',
|
||||
name: i18n.translate('xpack.streams.entityDetailOverview.tabs.streams', {
|
||||
defaultMessage: 'Streams',
|
||||
}),
|
||||
content: <ChildStreamList stream={definition} />,
|
||||
content: <ChildStreamList definition={definition} />,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
@ -170,7 +172,7 @@ export function StreamDetailOverview({ definition }: { definition?: ReadStreamDe
|
|||
name: i18n.translate('xpack.streams.entityDetailOverview.tabs.quicklinks', {
|
||||
defaultMessage: 'Quick Links',
|
||||
}),
|
||||
content: <QuickLinks stream={definition} />,
|
||||
content: <QuickLinks definition={definition} />,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -274,8 +276,8 @@ export function StreamDetailOverview({ definition }: { definition?: ReadStreamDe
|
|||
|
||||
const EMPTY_DASHBOARD_LIST: SanitizedDashboardAsset[] = [];
|
||||
|
||||
function QuickLinks({ stream }: { stream?: ReadStreamDefinition }) {
|
||||
const dashboardsFetch = useDashboardsFetch(stream?.name);
|
||||
function QuickLinks({ definition }: { definition?: IngestStreamGetResponse }) {
|
||||
const dashboardsFetch = useDashboardsFetch(definition?.stream.name);
|
||||
|
||||
return (
|
||||
<DashboardsTable
|
||||
|
@ -285,7 +287,7 @@ function QuickLinks({ stream }: { stream?: ReadStreamDefinition }) {
|
|||
);
|
||||
}
|
||||
|
||||
function ChildStreamList({ stream }: { stream?: ReadStreamDefinition }) {
|
||||
function ChildStreamList({ definition }: { definition?: IngestStreamGetResponse }) {
|
||||
const {
|
||||
dependencies: {
|
||||
start: {
|
||||
|
@ -305,15 +307,15 @@ function ChildStreamList({ stream }: { stream?: ReadStreamDefinition }) {
|
|||
);
|
||||
|
||||
const childDefinitions = useMemo(() => {
|
||||
if (!stream) {
|
||||
if (!definition) {
|
||||
return [];
|
||||
}
|
||||
return streamsListFetch.value?.streams.filter(
|
||||
(d) => isWiredStreamDefinition(d) && d.name.startsWith(stream.name as string)
|
||||
(d) => isWiredStreamDefinition(d) && d.name.startsWith(definition.stream.name)
|
||||
);
|
||||
}, [stream, streamsListFetch.value?.streams]);
|
||||
}, [definition, streamsListFetch.value?.streams]);
|
||||
|
||||
if (stream && childDefinitions?.length === 1) {
|
||||
if (definition && childDefinitions?.length === 1) {
|
||||
return (
|
||||
<EuiFlexItem grow>
|
||||
<EuiFlexGroup alignItems="center" justifyContent="center">
|
||||
|
@ -342,7 +344,7 @@ function ChildStreamList({ stream }: { stream?: ReadStreamDefinition }) {
|
|||
iconType="plusInCircle"
|
||||
href={router.link('/{key}/management/{subtab}', {
|
||||
path: {
|
||||
key: stream?.name as string,
|
||||
key: definition?.stream.name,
|
||||
subtab: 'route',
|
||||
},
|
||||
})}
|
||||
|
|
|
@ -42,6 +42,7 @@ import {
|
|||
RoutingDefinition,
|
||||
IngestUpsertRequest,
|
||||
getAncestorsAndSelf,
|
||||
WiredStreamGetResponse,
|
||||
} from '@kbn/streams-schema';
|
||||
import { useUnsavedChangesPrompt } from '@kbn/unsaved-changes-prompt';
|
||||
import { AbortableAsyncState } from '@kbn/observability-utils-browser/hooks/use_abortable_async';
|
||||
|
@ -74,7 +75,7 @@ function useRoutingState({
|
|||
definition,
|
||||
toasts,
|
||||
}: {
|
||||
definition?: ReadStreamDefinition;
|
||||
definition?: WiredStreamGetResponse;
|
||||
toasts: IToasts;
|
||||
}) {
|
||||
const [lastDisplayedToast, setLastDisplayedToast] = React.useState<Toast | undefined>();
|
||||
|
@ -157,7 +158,7 @@ export function StreamDetailRouting({
|
|||
definition,
|
||||
refreshDefinition,
|
||||
}: {
|
||||
definition?: ReadStreamDefinition;
|
||||
definition?: WiredStreamGetResponse;
|
||||
refreshDefinition: () => void;
|
||||
}) {
|
||||
const { appParams, core } = useKibana();
|
||||
|
@ -287,7 +288,7 @@ function ControlBar({
|
|||
routingAppState,
|
||||
refreshDefinition,
|
||||
}: {
|
||||
definition: ReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
routingAppState: ReturnType<typeof useRoutingState>;
|
||||
refreshDefinition: () => void;
|
||||
}) {
|
||||
|
@ -326,7 +327,7 @@ function ControlBar({
|
|||
signal,
|
||||
params: {
|
||||
path: {
|
||||
id: definition.name,
|
||||
id: definition.stream.name,
|
||||
},
|
||||
body: {
|
||||
if: emptyEqualsToAlways(routingAppState.childUnderEdit.child.if),
|
||||
|
@ -345,7 +346,7 @@ function ControlBar({
|
|||
}
|
||||
|
||||
const childUnderEdit = routingAppState.childUnderEdit?.child;
|
||||
const { name, stream } = definition;
|
||||
const { stream } = definition;
|
||||
|
||||
const routing = routingAppState.childStreams.map((child) =>
|
||||
child.destination === childUnderEdit?.destination ? childUnderEdit : child
|
||||
|
@ -362,7 +363,7 @@ function ControlBar({
|
|||
signal,
|
||||
params: {
|
||||
path: {
|
||||
id: name,
|
||||
id: stream.name,
|
||||
},
|
||||
body: request,
|
||||
},
|
||||
|
@ -483,7 +484,7 @@ function PreviewPanel({
|
|||
definition,
|
||||
routingAppState,
|
||||
}: {
|
||||
definition: ReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
routingAppState: ReturnType<typeof useRoutingState>;
|
||||
}) {
|
||||
const {
|
||||
|
@ -513,7 +514,7 @@ function PreviewPanel({
|
|||
signal,
|
||||
params: {
|
||||
path: {
|
||||
id: definition.name,
|
||||
id: definition.stream.name,
|
||||
},
|
||||
body: {
|
||||
if: emptyEqualsToAlways(debouncedChildUnderEdit.child.if),
|
||||
|
@ -688,7 +689,7 @@ function ChildStreamList({
|
|||
draggingChildStream,
|
||||
},
|
||||
}: {
|
||||
definition: ReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
routingAppState: ReturnType<typeof useRoutingState>;
|
||||
availableStreams: string[];
|
||||
}) {
|
||||
|
@ -801,7 +802,7 @@ function ChildStreamList({
|
|||
selectChildUnderEdit({
|
||||
isNew: true,
|
||||
child: {
|
||||
destination: `${definition.name}.child`,
|
||||
destination: `${definition.stream.name}.child`,
|
||||
if: cloneDeep(EMPTY_EQUALS_CONDITION),
|
||||
},
|
||||
});
|
||||
|
@ -819,31 +820,35 @@ function ChildStreamList({
|
|||
);
|
||||
}
|
||||
|
||||
function CurrentStreamEntry({ definition }: { definition: ReadStreamDefinition }) {
|
||||
function CurrentStreamEntry({ definition }: { definition: WiredStreamGetResponse }) {
|
||||
const router = useStreamsAppRouter();
|
||||
const breadcrumbs: EuiBreadcrumb[] = getAncestorsAndSelf(definition.name).map((parentId) => {
|
||||
const isBreadcrumbsTail = parentId === definition.name;
|
||||
const breadcrumbs: EuiBreadcrumb[] = getAncestorsAndSelf(definition.stream.name).map(
|
||||
(parentId) => {
|
||||
const isBreadcrumbsTail = parentId === definition.stream.name;
|
||||
|
||||
return {
|
||||
text: parentId,
|
||||
href: isBreadcrumbsTail
|
||||
? undefined
|
||||
: router.link('/{key}/{tab}/{subtab}', {
|
||||
path: {
|
||||
key: parentId,
|
||||
tab: 'management',
|
||||
subtab: 'route',
|
||||
},
|
||||
}),
|
||||
};
|
||||
});
|
||||
return {
|
||||
text: parentId,
|
||||
href: isBreadcrumbsTail
|
||||
? undefined
|
||||
: router.link('/{key}/{tab}/{subtab}', {
|
||||
path: {
|
||||
key: parentId,
|
||||
tab: 'management',
|
||||
subtab: 'route',
|
||||
},
|
||||
}),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isRoot(definition.name) && <EuiBreadcrumbs breadcrumbs={breadcrumbs} truncate={false} />}
|
||||
{!isRoot(definition.stream.name) && (
|
||||
<EuiBreadcrumbs breadcrumbs={breadcrumbs} truncate={false} />
|
||||
)}
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiPanel hasShadow={false} hasBorder paddingSize="s">
|
||||
<EuiText size="s">{definition.name}</EuiText>
|
||||
<EuiText size="s">{definition.stream.name}</EuiText>
|
||||
<EuiText size="xs" color="subdued">
|
||||
{i18n.translate('xpack.streams.streamDetailRouting.currentStream', {
|
||||
defaultMessage: 'Current stream',
|
||||
|
|
|
@ -23,11 +23,7 @@ import type {
|
|||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import useToggle from 'react-use/lib/useToggle';
|
||||
import {
|
||||
isRootStreamDefinition,
|
||||
isWiredReadStream,
|
||||
ReadStreamDefinition,
|
||||
} from '@kbn/streams-schema';
|
||||
import { isRootStreamDefinition, WiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { FieldType } from './field_type';
|
||||
import { FieldStatusBadge } from './field_status';
|
||||
import { FieldEntry, SchemaEditorEditingState } from './hooks/use_editing_state';
|
||||
|
@ -36,7 +32,7 @@ import { FieldParent } from './field_parent';
|
|||
import { SchemaEditorQueryAndFiltersState } from './hooks/use_query_and_filters';
|
||||
|
||||
interface FieldsTableContainerProps {
|
||||
definition: ReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
unmappedFieldsResult?: string[];
|
||||
isLoadingUnmappedFields: boolean;
|
||||
query?: Query;
|
||||
|
@ -101,15 +97,13 @@ export const FieldsTableContainer = ({
|
|||
}, [inheritedFields, query]);
|
||||
|
||||
const mappedFields = useMemo(() => {
|
||||
if (isWiredReadStream(definition)) {
|
||||
return Object.entries(definition.stream.ingest.wired.fields).map(([name, field]) => ({
|
||||
name,
|
||||
type: field.type,
|
||||
format: field.format,
|
||||
parent: definition.name,
|
||||
status: 'mapped' as const,
|
||||
}));
|
||||
}
|
||||
return Object.entries(definition.stream.ingest.wired.fields).map(([name, field]) => ({
|
||||
name,
|
||||
type: field.type,
|
||||
format: field.format,
|
||||
parent: definition.stream.name,
|
||||
status: 'mapped' as const,
|
||||
}));
|
||||
return [];
|
||||
}, [definition]);
|
||||
|
||||
|
@ -124,11 +118,11 @@ export const FieldsTableContainer = ({
|
|||
return unmappedFieldsResult
|
||||
? unmappedFieldsResult.map((field) => ({
|
||||
name: field,
|
||||
parent: definition.name,
|
||||
parent: definition.stream.name,
|
||||
status: 'unmapped' as const,
|
||||
}))
|
||||
: [];
|
||||
}, [definition.name, unmappedFieldsResult]);
|
||||
}, [definition.stream.name, unmappedFieldsResult]);
|
||||
|
||||
const filteredUnmappedFields = useMemo(() => {
|
||||
if (!unmappedFieldsResult) return [];
|
||||
|
@ -172,7 +166,7 @@ export const FieldsTableContainer = ({
|
|||
};
|
||||
|
||||
interface FieldsTableProps {
|
||||
definition: ReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
fields: FieldEntry[];
|
||||
editingState: SchemaEditorEditingState;
|
||||
unpromotingState: SchemaEditorUnpromotingState;
|
||||
|
@ -326,7 +320,10 @@ const FieldsTable = ({ definition, fields, editingState, unpromotingState }: Fie
|
|||
return <FieldType type={fieldType} />;
|
||||
} else if (columnId === 'parent') {
|
||||
return (
|
||||
<FieldParent parent={field.parent} linkEnabled={field.parent !== definition.name} />
|
||||
<FieldParent
|
||||
parent={field.parent}
|
||||
linkEnabled={field.parent !== definition.stream.name}
|
||||
/>
|
||||
);
|
||||
} else if (columnId === 'status') {
|
||||
return <FieldStatusBadge status={field.status} />;
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ReadStreamDefinition } from '@kbn/streams-schema';
|
||||
import { WiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { SchemaEditorEditingState } from '../hooks/use_editing_state';
|
||||
import { ChildrenAffectedCallout } from './children_affected_callout';
|
||||
import { SamplePreviewTable } from './sample_preview_table';
|
||||
|
@ -27,7 +27,7 @@ import { FieldSummary } from './field_summary';
|
|||
|
||||
export type SchemaEditorFlyoutProps = {
|
||||
streamsRepositoryClient: StreamsRepositoryClient;
|
||||
definition: ReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
} & SchemaEditorEditingState;
|
||||
|
||||
export const SchemaEditorFlyout = (props: SchemaEditorFlyoutProps) => {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { StreamsRepositoryClient } from '@kbn/streams-plugin/public/api';
|
|||
import { css } from '@emotion/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiCallOut } from '@elastic/eui';
|
||||
import { NamedFieldDefinitionConfig, ReadStreamDefinition } from '@kbn/streams-schema';
|
||||
import { NamedFieldDefinitionConfig, WiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { getFormattedError } from '../../../util/errors';
|
||||
import { useStreamsAppFetch } from '../../../hooks/use_streams_app_fetch';
|
||||
import { PreviewTable } from '../../preview_table';
|
||||
|
@ -18,7 +18,7 @@ import { isFullFieldDefinition } from '../hooks/use_editing_state';
|
|||
import { LoadingPanel } from '../../loading_panel';
|
||||
|
||||
interface SamplePreviewTableProps {
|
||||
definition: ReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
nextFieldDefinition?: Partial<NamedFieldDefinitionConfig>;
|
||||
streamsRepositoryClient: StreamsRepositoryClient;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ const SamplePreviewTableContent = ({
|
|||
signal,
|
||||
params: {
|
||||
path: {
|
||||
id: definition.name,
|
||||
id: definition.stream.name,
|
||||
},
|
||||
body: {
|
||||
field_definitions: [nextFieldDefinition],
|
||||
|
@ -53,7 +53,7 @@ const SamplePreviewTableContent = ({
|
|||
},
|
||||
});
|
||||
},
|
||||
[definition.name, nextFieldDefinition, streamsRepositoryClient],
|
||||
[definition.stream.name, nextFieldDefinition, streamsRepositoryClient],
|
||||
{
|
||||
disableToastOnError: true,
|
||||
}
|
||||
|
|
|
@ -5,11 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
ReadStreamDefinition,
|
||||
NamedFieldDefinitionConfig,
|
||||
isWiredReadStream,
|
||||
} from '@kbn/streams-schema';
|
||||
import { NamedFieldDefinitionConfig, WiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { StreamsRepositoryClient } from '@kbn/streams-plugin/public/api';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import useToggle from 'react-use/lib/useToggle';
|
||||
|
@ -39,7 +35,7 @@ export const useEditingState = ({
|
|||
toastsService,
|
||||
}: {
|
||||
streamsRepositoryClient: StreamsRepositoryClient;
|
||||
definition: ReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
refreshDefinition: () => void;
|
||||
refreshUnmappedFields: () => void;
|
||||
toastsService: ToastsStart;
|
||||
|
@ -95,8 +91,7 @@ export const useEditingState = ({
|
|||
const saveChanges = useMemo(() => {
|
||||
return selectedField &&
|
||||
isFullFieldDefinition(nextFieldDefinition) &&
|
||||
hasChanges(selectedField, nextFieldDefinition) &&
|
||||
isWiredReadStream(definition)
|
||||
hasChanges(selectedField, nextFieldDefinition)
|
||||
? async () => {
|
||||
toggleIsSaving(true);
|
||||
try {
|
||||
|
@ -104,7 +99,7 @@ export const useEditingState = ({
|
|||
signal: abortController.signal,
|
||||
params: {
|
||||
path: {
|
||||
id: definition.name,
|
||||
id: definition.stream.name,
|
||||
},
|
||||
body: {
|
||||
ingest: {
|
||||
|
|
|
@ -11,8 +11,8 @@ import useToggle from 'react-use/lib/useToggle';
|
|||
import { useAbortController } from '@kbn/observability-utils-browser/hooks/use_abort_controller';
|
||||
import { ToastsStart } from '@kbn/core-notifications-browser';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { WiredReadStreamDefinition } from '@kbn/streams-schema';
|
||||
import { omit } from 'lodash';
|
||||
import { WiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
|
||||
export type SchemaEditorUnpromotingState = ReturnType<typeof useUnpromotingState>;
|
||||
|
||||
|
@ -24,7 +24,7 @@ export const useUnpromotingState = ({
|
|||
toastsService,
|
||||
}: {
|
||||
streamsRepositoryClient: StreamsRepositoryClient;
|
||||
definition: WiredReadStreamDefinition;
|
||||
definition: WiredStreamGetResponse;
|
||||
refreshDefinition: () => void;
|
||||
refreshUnmappedFields: () => void;
|
||||
toastsService: ToastsStart;
|
||||
|
@ -47,7 +47,7 @@ export const useUnpromotingState = ({
|
|||
signal: abortController.signal,
|
||||
params: {
|
||||
path: {
|
||||
id: definition.name,
|
||||
id: definition.stream.name,
|
||||
},
|
||||
body: {
|
||||
ingest: {
|
||||
|
@ -81,8 +81,8 @@ export const useUnpromotingState = ({
|
|||
}
|
||||
}, [
|
||||
abortController.signal,
|
||||
definition.name,
|
||||
definition.stream.ingest,
|
||||
definition.stream.name,
|
||||
refreshDefinition,
|
||||
refreshUnmappedFields,
|
||||
selectedField,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiProgress, EuiPortal } from '@elastic/eui';
|
||||
import { css } from '@emotion/css';
|
||||
import { WiredReadStreamDefinition } from '@kbn/streams-schema';
|
||||
import { WiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import { useEditingState } from './hooks/use_editing_state';
|
||||
import { SchemaEditorFlyout } from './flyout';
|
||||
import { useKibana } from '../../hooks/use_kibana';
|
||||
|
@ -21,7 +21,7 @@ import { useQueryAndFilters } from './hooks/use_query_and_filters';
|
|||
import { FieldStatusFilterGroup } from './filters/status_filter_group';
|
||||
|
||||
interface SchemaEditorProps {
|
||||
definition?: WiredReadStreamDefinition;
|
||||
definition?: WiredStreamGetResponse;
|
||||
refreshDefinition: () => void;
|
||||
isLoadingDefinition: boolean;
|
||||
}
|
||||
|
@ -59,12 +59,12 @@ const Content = ({
|
|||
signal,
|
||||
params: {
|
||||
path: {
|
||||
id: definition.name,
|
||||
id: definition.stream.name,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
[definition.name, streamsRepositoryClient]
|
||||
[definition.stream.name, streamsRepositoryClient]
|
||||
);
|
||||
|
||||
const editingState = useEditingState({
|
||||
|
@ -88,7 +88,7 @@ const Content = ({
|
|||
// If the definition changes (e.g. navigating to parent stream), reset the entire editing state.
|
||||
useEffect(() => {
|
||||
reset();
|
||||
}, [definition.name, reset]);
|
||||
}, [definition.stream.name, reset]);
|
||||
|
||||
return (
|
||||
<EuiFlexItem>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isWiredStreamGetResponse } from '@kbn/streams-schema';
|
||||
import React from 'react';
|
||||
import { useKibana } from '../../hooks/use_kibana';
|
||||
import { useStreamsAppFetch } from '../../hooks/use_streams_app_fetch';
|
||||
|
@ -37,43 +36,14 @@ export function StreamDetailView() {
|
|||
loading,
|
||||
} = useStreamsAppFetch(
|
||||
({ signal }) => {
|
||||
return streamsRepositoryClient
|
||||
.fetch('GET /api/streams/{id}', {
|
||||
signal,
|
||||
params: {
|
||||
path: {
|
||||
id: key,
|
||||
},
|
||||
return streamsRepositoryClient.fetch('GET /api/streams/{id}', {
|
||||
signal,
|
||||
params: {
|
||||
path: {
|
||||
id: key,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (isWiredStreamGetResponse(response)) {
|
||||
return {
|
||||
dashboards: response.dashboards,
|
||||
inherited_fields: response.inherited_fields,
|
||||
elasticsearch_assets: [],
|
||||
effective_lifecycle: response.effective_lifecycle,
|
||||
name: key,
|
||||
stream: {
|
||||
name: key,
|
||||
...response.stream,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
dashboards: response.dashboards,
|
||||
elasticsearch_assets: response.elasticsearch_assets,
|
||||
inherited_fields: {},
|
||||
effective_lifecycle: response.effective_lifecycle,
|
||||
name: key,
|
||||
data_stream_exists: response.data_stream_exists,
|
||||
stream: {
|
||||
name: key,
|
||||
...response.stream,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
[streamsRepositoryClient, key]
|
||||
);
|
||||
|
|
|
@ -113,6 +113,7 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
|
|||
expect(dashboards).to.eql([]);
|
||||
|
||||
expect(stream).to.eql({
|
||||
name: TEST_STREAM_NAME,
|
||||
ingest: {
|
||||
lifecycle: { inherit: {} },
|
||||
processing: [
|
||||
|
|
|
@ -9,7 +9,7 @@ import expect from '@kbn/expect';
|
|||
import {
|
||||
StreamUpsertRequest,
|
||||
StreamGetResponse,
|
||||
WiredReadStreamDefinition,
|
||||
WiredStreamGetResponse,
|
||||
} from '@kbn/streams-schema';
|
||||
import { DeploymentAgnosticFtrProviderContext } from '../../../ftr_provider_context';
|
||||
import {
|
||||
|
@ -187,7 +187,7 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
|
|||
},
|
||||
});
|
||||
expect(
|
||||
(logsDeeplyNestedStreamname.body as WiredReadStreamDefinition).stream.ingest.wired.fields
|
||||
(logsDeeplyNestedStreamname.body as WiredStreamGetResponse).stream.ingest.wired.fields
|
||||
).to.eql({
|
||||
field2: {
|
||||
type: 'keyword',
|
||||
|
|
|
@ -10,7 +10,6 @@ import {
|
|||
IngestStreamEffectiveLifecycle,
|
||||
IngestStreamLifecycle,
|
||||
IngestStreamUpsertRequest,
|
||||
WiredReadStreamDefinition,
|
||||
WiredStreamGetResponse,
|
||||
isDslLifecycle,
|
||||
isIlmLifecycle,
|
||||
|
@ -103,11 +102,9 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
|
|||
expect(response).to.have.property('acknowledged', true);
|
||||
|
||||
const updatedRootDefinition = await getStream(apiClient, 'logs');
|
||||
expect((updatedRootDefinition as WiredReadStreamDefinition).stream.ingest.lifecycle).to.eql(
|
||||
{
|
||||
dsl: { data_retention: '999d' },
|
||||
}
|
||||
);
|
||||
expect((updatedRootDefinition as WiredStreamGetResponse).stream.ingest.lifecycle).to.eql({
|
||||
dsl: { data_retention: '999d' },
|
||||
});
|
||||
expect(updatedRootDefinition.effective_lifecycle).to.eql({
|
||||
dsl: { data_retention: '999d' },
|
||||
from: 'logs',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue