diff --git a/x-pack/plugins/streams_app/public/components/entity_detail_view/index.tsx b/x-pack/plugins/streams_app/public/components/entity_detail_view/index.tsx
index d2ce4859e66d1..68c5f9d6798ec 100644
--- a/x-pack/plugins/streams_app/public/components/entity_detail_view/index.tsx
+++ b/x-pack/plugins/streams_app/public/components/entity_detail_view/index.tsx
@@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import { EuiFlexGroup, EuiIcon, EuiLink, EuiPanel } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiPanel } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useStreamsAppBreadcrumbs } from '../../hooks/use_streams_app_breadcrumbs';
@@ -71,31 +71,35 @@ export function EntityDetailViewWithoutParams({
return (
-
-
-
-
- {i18n.translate('xpack.streams.entityDetailView.goBackLinkLabel', {
- defaultMessage: 'Back',
+
+
+
+
+
+ {i18n.translate('xpack.streams.entityDetailView.goBackLinkLabel', {
+ defaultMessage: 'Back',
+ })}
+
+
+
+
+
+ }
+ >
+ {
+ return {
+ name: tabKey,
+ label,
+ href,
+ selected: selectedTab === tabKey,
+ };
})}
-
-
-
- }
- >
- {
- return {
- name: tabKey,
- label,
- href,
- selected: selectedTab === tabKey,
- };
- })}
- />
-
+ />
+
+
{selectedTabObject.content}
);
diff --git a/x-pack/plugins/streams_app/public/components/stream_detail_enriching/index.tsx b/x-pack/plugins/streams_app/public/components/stream_detail_enriching/index.tsx
new file mode 100644
index 0000000000000..d879142162353
--- /dev/null
+++ b/x-pack/plugins/streams_app/public/components/stream_detail_enriching/index.tsx
@@ -0,0 +1,18 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { StreamDefinition } from '@kbn/streams-plugin/common';
+import React from 'react';
+
+export function StreamDetailEnriching({
+ definition: _definition,
+ refreshDefinition: _refreshDefinition,
+}: {
+ definition?: StreamDefinition;
+ refreshDefinition: () => void;
+}) {
+ return <>{'TODO'}>;
+}
diff --git a/x-pack/plugins/streams_app/public/components/stream_detail_management/index.tsx b/x-pack/plugins/streams_app/public/components/stream_detail_management/index.tsx
new file mode 100644
index 0000000000000..534d883905b17
--- /dev/null
+++ b/x-pack/plugins/streams_app/public/components/stream_detail_management/index.tsx
@@ -0,0 +1,92 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import React from 'react';
+import { i18n } from '@kbn/i18n';
+import { StreamDefinition } from '@kbn/streams-plugin/common';
+import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { useStreamsAppParams } from '../../hooks/use_streams_app_params';
+import { RedirectTo } from '../redirect_to';
+import { useStreamsAppRouter } from '../../hooks/use_streams_app_router';
+import { StreamDetailRouting } from '../stream_detail_routing';
+import { StreamDetailEnriching } from '../stream_detail_enriching';
+import { StreamDetailSchemaEditor } from '../stream_detail_schema_editor';
+
+type ManagementSubTabs = 'route' | 'enrich' | 'schemaEditor';
+
+function isValidManagementSubTab(value: string): value is ManagementSubTabs {
+ return ['route', 'enrich', 'schemaEditor'].includes(value);
+}
+
+export function StreamDetailManagement({
+ definition,
+ refreshDefinition,
+}: {
+ definition?: StreamDefinition;
+ refreshDefinition: () => void;
+}) {
+ const {
+ path: { key, subtab },
+ } = useStreamsAppParams('/{key}/management/{subtab}');
+ const router = useStreamsAppRouter();
+
+ const tabs = {
+ route: {
+ content: (
+
+ ),
+ label: i18n.translate('xpack.streams.streamDetailView.routingTab', {
+ defaultMessage: 'Streams Partitioning',
+ }),
+ },
+ enrich: {
+ content: (
+
+ ),
+ label: i18n.translate('xpack.streams.streamDetailView.enrichingTab', {
+ defaultMessage: 'Extract field',
+ }),
+ },
+ schemaEditor: {
+ content: (
+
+ ),
+ label: i18n.translate('xpack.streams.streamDetailView.schemaEditorTab', {
+ defaultMessage: 'Schema editor',
+ }),
+ },
+ };
+
+ if (!isValidManagementSubTab(subtab)) {
+ return (
+
+ );
+ }
+
+ const selectedTabObject = tabs[subtab];
+
+ return (
+
+
+ {
+ router.push('/{key}/management/{subtab}', {
+ path: { key, subtab: optionId },
+ query: {},
+ });
+ }}
+ options={Object.keys(tabs).map((id) => ({
+ id,
+ label: tabs[id as ManagementSubTabs].label,
+ }))}
+ />
+
+ {selectedTabObject.content}
+
+ );
+}
diff --git a/x-pack/plugins/streams_app/public/components/stream_detail_overview/index.tsx b/x-pack/plugins/streams_app/public/components/stream_detail_overview/index.tsx
index 93a573fd4c01f..c051d114317ea 100644
--- a/x-pack/plugins/streams_app/public/components/stream_detail_overview/index.tsx
+++ b/x-pack/plugins/streams_app/public/components/stream_detail_overview/index.tsx
@@ -114,54 +114,58 @@ export function StreamDetailOverview({ definition }: { definition?: StreamDefini
return (
<>
-
-
- {
- if (!isUpdate) {
+
+
+
+ {
+ if (!isUpdate) {
+ histogramQueryFetch.refresh();
+ return;
+ }
+
+ if (dateRange) {
+ setTimeRange({ from: dateRange.from, to: dateRange?.to, mode: dateRange.mode });
+ }
+ }}
+ onRefresh={() => {
histogramQueryFetch.refresh();
- return;
- }
-
- if (dateRange) {
- setTimeRange({ from: dateRange.from, to: dateRange?.to, mode: dateRange.mode });
- }
- }}
- onRefresh={() => {
- histogramQueryFetch.refresh();
- }}
- placeholder={i18n.translate(
- 'xpack.streams.entityDetailOverview.searchBarPlaceholder',
- {
- defaultMessage: 'Filter data by using KQL',
- }
- )}
- dateRangeFrom={timeRange.from}
- dateRangeTo={timeRange.to}
- />
-
-
- {i18n.translate('xpack.streams.streamDetailOverview.openInDiscoverButtonLabel', {
- defaultMessage: 'Open in Discover',
- })}
-
-
-
-
-
+ }}
+ placeholder={i18n.translate(
+ 'xpack.streams.entityDetailOverview.searchBarPlaceholder',
+ {
+ defaultMessage: 'Filter data by using KQL',
+ }
+ )}
+ dateRangeFrom={timeRange.from}
+ dateRangeTo={timeRange.to}
+ />
+
+
+ {i18n.translate('xpack.streams.streamDetailOverview.openInDiscoverButtonLabel', {
+ defaultMessage: 'Open in Discover',
+ })}
+
-
+
+
+
+
+
+
+
+
>
);
diff --git a/x-pack/plugins/streams_app/public/components/stream_detail_routing/index.tsx b/x-pack/plugins/streams_app/public/components/stream_detail_routing/index.tsx
new file mode 100644
index 0000000000000..af65c7eab4235
--- /dev/null
+++ b/x-pack/plugins/streams_app/public/components/stream_detail_routing/index.tsx
@@ -0,0 +1,18 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { StreamDefinition } from '@kbn/streams-plugin/common';
+import React from 'react';
+
+export function StreamDetailRouting({
+ definition: _definition,
+ refreshDefinition: _refreshDefinition,
+}: {
+ definition?: StreamDefinition;
+ refreshDefinition: () => void;
+}) {
+ return <>{'TODO'}>;
+}
diff --git a/x-pack/plugins/streams_app/public/components/stream_detail_schema_editor/index.tsx b/x-pack/plugins/streams_app/public/components/stream_detail_schema_editor/index.tsx
new file mode 100644
index 0000000000000..7d3e9322e8d4f
--- /dev/null
+++ b/x-pack/plugins/streams_app/public/components/stream_detail_schema_editor/index.tsx
@@ -0,0 +1,18 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { StreamDefinition } from '@kbn/streams-plugin/common';
+import React from 'react';
+
+export function StreamDetailSchemaEditor({
+ definition: _definition,
+ refreshDefinition: _refreshDefinition,
+}: {
+ definition?: StreamDefinition;
+ refreshDefinition: () => void;
+}) {
+ return <>{'TODO'}>;
+}
diff --git a/x-pack/plugins/streams_app/public/components/stream_detail_view/index.tsx b/x-pack/plugins/streams_app/public/components/stream_detail_view/index.tsx
index ebf72a58d32a8..4f213e855c175 100644
--- a/x-pack/plugins/streams_app/public/components/stream_detail_view/index.tsx
+++ b/x-pack/plugins/streams_app/public/components/stream_detail_view/index.tsx
@@ -11,11 +11,13 @@ import { useStreamsAppParams } from '../../hooks/use_streams_app_params';
import { useStreamsAppFetch } from '../../hooks/use_streams_app_fetch';
import { useKibana } from '../../hooks/use_kibana';
import { StreamDetailOverview } from '../stream_detail_overview';
+import { StreamDetailManagement } from '../stream_detail_management';
export function StreamDetailView() {
- const {
- path: { key, tab },
- } = useStreamsAppParams('/{key}/{tab}');
+ const { path } = useStreamsAppParams('/{key}/*');
+
+ const key = path.key;
+ const tab = 'tab' in path ? path.tab : 'management';
const {
dependencies: {
@@ -25,7 +27,7 @@ export function StreamDetailView() {
},
} = useKibana();
- const { value: streamEntity } = useStreamsAppFetch(
+ const { value: streamEntity, refresh } = useStreamsAppFetch(
({ signal }) => {
return streamsRepositoryClient.fetch('GET /api/streams/{id}', {
signal,
@@ -54,7 +56,7 @@ export function StreamDetailView() {
},
{
name: 'management',
- content: <>>,
+ content: ,
label: i18n.translate('xpack.streams.streamDetailView.managementTab', {
defaultMessage: 'Management',
}),
diff --git a/x-pack/plugins/streams_app/public/components/stream_list_view/index.tsx b/x-pack/plugins/streams_app/public/components/stream_list_view/index.tsx
index e0530fc6bf5f0..7ffda5f40295a 100644
--- a/x-pack/plugins/streams_app/public/components/stream_list_view/index.tsx
+++ b/x-pack/plugins/streams_app/public/components/stream_list_view/index.tsx
@@ -6,7 +6,7 @@
*/
import React, { useState } from 'react';
import { i18n } from '@kbn/i18n';
-import { EuiFlexGroup, EuiSearchBar } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiSearchBar } from '@elastic/eui';
import { useKibana } from '../../hooks/use_kibana';
import { useStreamsAppFetch } from '../../hooks/use_streams_app_fetch';
import { StreamsAppPageHeader } from '../streams_app_page_header';
@@ -36,27 +36,33 @@ export function StreamListView() {
return (
-
- }
- />
+
+
+ }
+ />
+
- {
- setQuery(nextQuery.queryText);
- }}
- />
-
+
+ {
+ setQuery(nextQuery.queryText);
+ }}
+ />
+
+
+
+
diff --git a/x-pack/plugins/streams_app/public/components/streams_app_page_body/index.tsx b/x-pack/plugins/streams_app/public/components/streams_app_page_body/index.tsx
index 0f13dc31e277b..04b44f82df0fd 100644
--- a/x-pack/plugins/streams_app/public/components/streams_app_page_body/index.tsx
+++ b/x-pack/plugins/streams_app/public/components/streams_app_page_body/index.tsx
@@ -17,6 +17,7 @@ export function StreamsAppPageBody({ children }: { children: React.ReactNode })
className={css`
border-top: 1px solid ${theme.colors.lightShade};
border-radius: 0px;
+ display: flex;
`}
paddingSize="l"
>
diff --git a/x-pack/plugins/streams_app/public/components/streams_app_page_template/index.tsx b/x-pack/plugins/streams_app/public/components/streams_app_page_template/index.tsx
index c474f54c22745..942d2937dba81 100644
--- a/x-pack/plugins/streams_app/public/components/streams_app_page_template/index.tsx
+++ b/x-pack/plugins/streams_app/public/components/streams_app_page_template/index.tsx
@@ -35,7 +35,15 @@ export function StreamsAppPageTemplate({ children }: { children: React.ReactNode
},
}}
>
-
+
{children}
diff --git a/x-pack/plugins/streams_app/public/hooks/use_streams_app_params.ts b/x-pack/plugins/streams_app/public/hooks/use_streams_app_params.ts
index 2931a6fa64f8b..d7a6e175e5491 100644
--- a/x-pack/plugins/streams_app/public/hooks/use_streams_app_params.ts
+++ b/x-pack/plugins/streams_app/public/hooks/use_streams_app_params.ts
@@ -8,7 +8,8 @@ import { type PathsOf, type TypeOf, useParams } from '@kbn/typed-react-router-co
import type { StreamsAppRoutes } from '../routes/config';
export function useStreamsAppParams>(
- path: TPath
+ path: TPath,
+ optional: boolean = false
): TypeOf {
- return useParams(path)! as TypeOf;
+ return useParams(path, optional)! as TypeOf;
}
diff --git a/x-pack/plugins/streams_app/public/routes/config.tsx b/x-pack/plugins/streams_app/public/routes/config.tsx
index e3efdc6d871e7..6ae0fec51ad7a 100644
--- a/x-pack/plugins/streams_app/public/routes/config.tsx
+++ b/x-pack/plugins/streams_app/public/routes/config.tsx
@@ -44,6 +44,22 @@ const streamsAppRoutes = {
'/{key}': {
element: ,
},
+ '/{key}/management': {
+ element: (
+
+ ),
+ },
+ '/{key}/management/{subtab}': {
+ element: ,
+ params: t.type({
+ path: t.type({
+ subtab: t.string,
+ }),
+ }),
+ },
'/{key}/{tab}': {
element: ,
params: t.type({