Skip to content

Commit 313d436

Browse files
[8.19] [Streams 🌊] Make management view the main page for individual stream (#224461) (#224573)
# Backport This will backport the following commits from `main` to `8.19`: - [[Streams 🌊] Make management view the main page for individual stream (#224461)](#224461) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Marco Antonio Ghiani","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-06-19T12:58:19Z","message":"[Streams 🌊] Make management view the main page for individual stream (#224461)\n\n## 📓 Summary\n\nCloses https://github.com/elastic/streams-program/issues/329\n\nImplement all necessary changes to make the management page the primary\npage when landing on a stream detail.\n\n\nhttps://github.com/user-attachments/assets/0e21c1cb-ad07-4711-9bc0-8cbe0760faca\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>","sha":"dbb72ee827bc99263e9d5e338388b31fbec18f9e","branchLabelMapping":{"^v9.1.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:obs-ux-logs","backport:version","Feature:Streams","v9.1.0","v8.19.0"],"title":"[Streams 🌊] Make management view the main page for individual stream ","number":224461,"url":"https://github.com/elastic/kibana/pull/224461","mergeCommit":{"message":"[Streams 🌊] Make management view the main page for individual stream (#224461)\n\n## 📓 Summary\n\nCloses https://github.com/elastic/streams-program/issues/329\n\nImplement all necessary changes to make the management page the primary\npage when landing on a stream detail.\n\n\nhttps://github.com/user-attachments/assets/0e21c1cb-ad07-4711-9bc0-8cbe0760faca\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>","sha":"dbb72ee827bc99263e9d5e338388b31fbec18f9e"}},"sourceBranch":"main","suggestedTargetBranches":["8.19"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/224461","number":224461,"mergeCommit":{"message":"[Streams 🌊] Make management view the main page for individual stream (#224461)\n\n## 📓 Summary\n\nCloses https://github.com/elastic/streams-program/issues/329\n\nImplement all necessary changes to make the management page the primary\npage when landing on a stream detail.\n\n\nhttps://github.com/user-attachments/assets/0e21c1cb-ad07-4711-9bc0-8cbe0760faca\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>","sha":"dbb72ee827bc99263e9d5e338388b31fbec18f9e"}},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> --------- Co-authored-by: Marco Antonio Ghiani <[email protected]>
1 parent cabac75 commit 313d436

File tree

21 files changed

+258
-272
lines changed

21 files changed

+258
-272
lines changed

config/serverless.oblt.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ pricing.tiers.products:
66
- name: observability
77
tier: complete # Accepted values for this tier are: complete, logs_essentials
88

9-
# Make sure the plugins belonging to this project type are loaded
10-
plugins.allowlistPluginGroups: ['platform', 'observability']
11-
129
# Disabled Observability plugins
1310
xpack.ux.enabled: false
1411
xpack.legacy_uptime.enabled: false

x-pack/platform/plugins/private/translations/translations/fr-FR.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47257,7 +47257,6 @@
4725747257
"xpack.streams.streamDetailSchemaEditorUnmapSuccessToast": "Le champ {field} a bien été démappé",
4725847258
"xpack.streams.streamDetailView.dashboardsTab": "Tableaux de bord",
4725947259
"xpack.streams.streamDetailView.dataStream": "Flux de données",
47260-
"xpack.streams.streamDetailView.enrichmentTab": "Extraire le champ",
4726147260
"xpack.streams.streamDetailView.indexTemplate": "Modèle d'index",
4726247261
"xpack.streams.streamDetailView.ingestPipeline": "Pipeline d'ingestion",
4726347262
"xpack.streams.streamDetailView.managementTab.bottomBar.cancel": "Annuler les modifications",

x-pack/platform/plugins/private/translations/translations/ja-JP.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47220,7 +47220,6 @@
4722047220
"xpack.streams.streamDetailSchemaEditorUnmapSuccessToast": "{field}は正常にマッピング解除されました",
4722147221
"xpack.streams.streamDetailView.dashboardsTab": "ダッシュボード",
4722247222
"xpack.streams.streamDetailView.dataStream": "データストリーム",
47223-
"xpack.streams.streamDetailView.enrichmentTab": "フィールドを抽出",
4722447223
"xpack.streams.streamDetailView.indexTemplate": "インデックステンプレート",
4722547224
"xpack.streams.streamDetailView.ingestPipeline": "パイプラインを投入",
4722647225
"xpack.streams.streamDetailView.managementTab.bottomBar.cancel": "変更をキャンセル",

x-pack/platform/plugins/private/translations/translations/zh-CN.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47298,7 +47298,6 @@
4729847298
"xpack.streams.streamDetailSchemaEditorUnmapSuccessToast": "已成功对 {field} 取消映射",
4729947299
"xpack.streams.streamDetailView.dashboardsTab": "仪表板",
4730047300
"xpack.streams.streamDetailView.dataStream": "数据流",
47301-
"xpack.streams.streamDetailView.enrichmentTab": "提取字段",
4730247301
"xpack.streams.streamDetailView.indexTemplate": "索引模板",
4730347302
"xpack.streams.streamDetailView.ingestPipeline": "采集管道",
4730447303
"xpack.streams.streamDetailView.managementTab.bottomBar.cancel": "取消更改",

x-pack/platform/plugins/shared/streams_app/.storybook/get_mock_streams_app_context.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import type { StreamsPluginStart } from '@kbn/streams-plugin/public';
2424
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
2525
import { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public';
2626
import { ObservabilityAIAssistantPublicStart } from '@kbn/observability-ai-assistant-plugin/public';
27+
import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks';
2728
import type { StreamsAppKibanaContext } from '../public/hooks/use_kibana';
2829
import { StreamsTelemetryService } from '../public/telemetry/service';
2930

@@ -70,6 +71,7 @@ export function getMockStreamsAppContext(): StreamsAppKibanaContext {
7071
share: {} as unknown as SharePublicStart,
7172
navigation: {} as unknown as NavigationPublicStart,
7273
savedObjectsTagging: {} as unknown as SavedObjectTaggingPluginStart,
74+
fieldFormats: fieldFormatsServiceMock.createStartContract(),
7375
fieldsMetadata: fieldsMetadataPluginPublicMock.createStartContract(),
7476
licensing: {} as unknown as LicensingPluginStart,
7577
indexManagement: {} as unknown as IndexManagementPluginStart,

x-pack/platform/plugins/shared/streams_app/kibana.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"dataViews",
1717
"discover",
1818
"discoverShared",
19+
"fieldFormats",
1920
"fieldsMetadata",
2021
"licensing",
2122
"indexManagement",

x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_lifecycle/index.tsx

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
* 2.0.
66
*/
77

8-
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiSpacer } from '@elastic/eui';
8+
import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
99
import React, { useMemo, useState } from 'react';
1010
import { IngestStreamLifecycle, Streams, isIlmLifecycle, isRoot } from '@kbn/streams-schema';
1111
import { PolicyFromES } from '@kbn/index-lifecycle-management-common-shared';
1212
import { i18n } from '@kbn/i18n';
1313
import { useAbortController } from '@kbn/react-hooks';
14+
import { css } from '@emotion/react';
1415
import { useKibana } from '../../../hooks/use_kibana';
1516
import { EditLifecycleModal, LifecycleEditAction } from './modal';
1617
import { RetentionSummary } from './summary';
@@ -153,7 +154,7 @@ export function StreamDetailLifecycle({
153154
};
154155

155156
return (
156-
<>
157+
<EuiFlexGroup gutterSize="m" direction="column">
157158
<EditLifecycleModal
158159
action={openEditModal}
159160
definition={definition}
@@ -162,51 +163,50 @@ export function StreamDetailLifecycle({
162163
getIlmPolicies={getIlmPolicies}
163164
updateInProgress={updateInProgress}
164165
/>
165-
166-
<EuiPanel grow={false} hasShadow={false} hasBorder paddingSize="s">
167-
<EuiFlexGroup gutterSize="m">
168-
<EuiFlexItem grow={1}>
169-
<RetentionSummary definition={definition} />
166+
<EuiFlexGroup gutterSize="m" css={flexRowCss}>
167+
<EuiPanel grow={false} hasShadow={false} hasBorder paddingSize="m">
168+
<RetentionSummary
169+
definition={definition}
170+
isLoadingStats={isLoadingStats}
171+
stats={stats}
172+
statsError={statsError}
173+
/>
174+
</EuiPanel>
175+
<EuiPanel grow hasShadow={false} hasBorder paddingSize="m">
176+
<RetentionMetadata
177+
definition={definition}
178+
lifecycleActions={lifecycleActions}
179+
openEditModal={(action) => setOpenEditModal(action)}
180+
isLoadingStats={isLoadingStats}
181+
stats={stats}
182+
statsError={statsError}
183+
/>
184+
</EuiPanel>
185+
</EuiFlexGroup>
186+
<EuiFlexGroup gutterSize="m" css={flexRowCss}>
187+
{definition.privileges.monitor && (
188+
<EuiFlexItem grow={2}>
189+
<EuiPanel hasShadow={false} hasBorder paddingSize="m">
190+
<IngestionRate
191+
definition={definition}
192+
isLoadingStats={isLoadingStats}
193+
stats={stats}
194+
/>
195+
</EuiPanel>
170196
</EuiFlexItem>
171-
172-
<EuiFlexItem grow={4}>
173-
<RetentionMetadata
174-
definition={definition}
175-
lifecycleActions={lifecycleActions}
176-
openEditModal={(action) => setOpenEditModal(action)}
177-
isLoadingStats={isLoadingStats}
178-
stats={stats}
179-
statsError={statsError}
180-
/>
197+
)}
198+
{definition.privileges.lifecycle && isIlmLifecycle(definition.effective_lifecycle) ? (
199+
<EuiFlexItem grow={3}>
200+
<EuiPanel hasShadow={false} hasBorder paddingSize="m">
201+
<IlmSummary definition={definition} lifecycle={definition.effective_lifecycle} />
202+
</EuiPanel>
181203
</EuiFlexItem>
182-
</EuiFlexGroup>
183-
</EuiPanel>
184-
185-
<EuiSpacer size="m" />
186-
187-
<EuiFlexItem grow={false}>
188-
<EuiFlexGroup gutterSize="m">
189-
{definition.privileges.monitor && (
190-
<EuiFlexItem grow={2}>
191-
<EuiPanel grow={true} hasShadow={false} hasBorder paddingSize="s">
192-
<IngestionRate
193-
definition={definition}
194-
isLoadingStats={isLoadingStats}
195-
stats={stats}
196-
/>
197-
</EuiPanel>
198-
</EuiFlexItem>
199-
)}
200-
201-
{definition.privileges.lifecycle && isIlmLifecycle(definition.effective_lifecycle) ? (
202-
<EuiFlexItem grow={3}>
203-
<EuiPanel grow={true} hasShadow={false} hasBorder paddingSize="s">
204-
<IlmSummary definition={definition} lifecycle={definition.effective_lifecycle} />
205-
</EuiPanel>
206-
</EuiFlexItem>
207-
) : null}
208-
</EuiFlexGroup>
209-
</EuiFlexItem>
210-
</>
204+
) : null}
205+
</EuiFlexGroup>
206+
</EuiFlexGroup>
211207
);
212208
}
209+
210+
const flexRowCss = css`
211+
flex-grow: 0;
212+
`;

x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_lifecycle/metadata.tsx

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import React, { ReactNode } from 'react';
1616
import { useBoolean } from '@kbn/react-hooks';
1717
import {
1818
EuiBadge,
19-
EuiButton,
19+
EuiButtonEmpty,
2020
EuiContextMenuItem,
2121
EuiContextMenuPanel,
2222
EuiFlexGroup,
@@ -25,13 +25,15 @@ import {
2525
EuiIconTip,
2626
EuiLink,
2727
EuiLoadingSpinner,
28-
EuiPanel,
2928
EuiPopover,
3029
EuiText,
3130
EuiToolTip,
32-
formatNumber,
31+
useEuiTheme,
3332
} from '@elastic/eui';
3433
import { i18n } from '@kbn/i18n';
34+
import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '@kbn/field-types';
35+
import { css } from '@emotion/react';
36+
import { useKibana } from '../../../hooks/use_kibana';
3537
import { LifecycleEditAction } from './modal';
3638
import { IlmLink } from './ilm_link';
3739
import { useStreamsAppRouter } from '../../../hooks/use_streams_app_router';
@@ -54,8 +56,12 @@ export function RetentionMetadata({
5456
isLoadingStats: boolean;
5557
statsError?: Error;
5658
}) {
57-
const [isMenuOpen, { toggle: toggleMenu, off: closeMenu }] = useBoolean(false);
59+
const { euiTheme } = useEuiTheme();
5860
const router = useStreamsAppRouter();
61+
const [isMenuOpen, { toggle: toggleMenu, off: closeMenu }] = useBoolean(false);
62+
63+
const dateFormatter = useDateFormatter();
64+
5965
const lifecycle = definition.effective_lifecycle;
6066

6167
const contextualMenu =
@@ -74,17 +80,20 @@ export function RetentionMetadata({
7480
: undefined
7581
}
7682
>
77-
<EuiButton
83+
<EuiButtonEmpty
7884
data-test-subj="streamsAppRetentionMetadataEditDataRetentionButton"
7985
size="s"
80-
fullWidth
8186
onClick={toggleMenu}
8287
disabled={!definition.privileges.lifecycle}
88+
iconType="pencil"
89+
css={css`
90+
margin-bottom: -${euiTheme.size.s};
91+
`}
8392
>
8493
{i18n.translate('xpack.streams.entityDetailViewWithoutParams.editDataRetention', {
8594
defaultMessage: 'Edit data retention',
8695
})}
87-
</EuiButton>
96+
</EuiButtonEmpty>
8897
</EuiToolTip>
8998
}
9099
isOpen={isMenuOpen}
@@ -147,13 +156,13 @@ export function RetentionMetadata({
147156
);
148157

149158
return (
150-
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="s">
159+
<>
151160
<MetadataRow
152161
metadata={i18n.translate('xpack.streams.streamDetailLifecycle.retentionPeriodLabel', {
153162
defaultMessage: 'Retention period',
154163
})}
155164
value={
156-
<EuiFlexGroup responsive={false}>
165+
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center" responsive={false}>
157166
<EuiFlexItem grow={false}>
158167
<EuiBadge color={isDisabledLifecycle(lifecycle) ? 'default' : 'accent'}>
159168
{isDslLifecycle(lifecycle)
@@ -167,9 +176,9 @@ export function RetentionMetadata({
167176
})}
168177
</EuiBadge>
169178
</EuiFlexItem>
179+
{contextualMenu}
170180
</EuiFlexGroup>
171181
}
172-
button={contextualMenu}
173182
dataTestSubj="streamsAppRetentionMetadataRetentionPeriod"
174183
/>
175184
<EuiHorizontalRule margin="s" />
@@ -186,65 +195,63 @@ export function RetentionMetadata({
186195
/>
187196
<EuiHorizontalRule margin="s" />
188197
<MetadataRow
189-
metadata={i18n.translate('xpack.streams.streamDetailLifecycle.ingestionRate', {
190-
defaultMessage: 'Ingestion',
191-
})}
192-
tip={i18n.translate('xpack.streams.streamDetailLifecycle.ingestionRateDetails', {
193-
defaultMessage:
194-
'Approximate average (stream total size divided by the number of days since creation).',
198+
metadata={i18n.translate('xpack.streams.streamDetailLifecycle.lastUupdated', {
199+
defaultMessage: 'Last updated',
195200
})}
196201
value={
197202
<PrivilegesWarningIconWrapper
198203
hasPrivileges={definition.privileges.monitor}
199-
title="ingestionRate"
204+
title="lastUpdated"
200205
>
201206
{statsError ? (
202207
'-'
203208
) : isLoadingStats || !stats ? (
204209
<EuiLoadingSpinner size="s" />
205-
) : stats.bytesPerDay ? (
206-
formatIngestionRate(stats.bytesPerDay)
207210
) : (
208-
'-'
211+
dateFormatter.convert(stats.lastActivity)
209212
)}
210213
</PrivilegesWarningIconWrapper>
211214
}
212215
/>
213216
<EuiHorizontalRule margin="s" />
214217
<MetadataRow
215-
metadata={i18n.translate('xpack.streams.streamDetailLifecycle.totalDocs', {
216-
defaultMessage: 'Total doc count',
218+
metadata={i18n.translate('xpack.streams.streamDetailLifecycle.ingestionRate', {
219+
defaultMessage: 'Ingestion',
220+
})}
221+
tip={i18n.translate('xpack.streams.streamDetailLifecycle.ingestionRateDetails', {
222+
defaultMessage:
223+
'Approximate average (stream total size divided by the number of days since creation).',
217224
})}
218225
value={
219226
<PrivilegesWarningIconWrapper
220227
hasPrivileges={definition.privileges.monitor}
221-
title="totalDocCount"
228+
title="ingestionRate"
222229
>
223230
{statsError ? (
224231
'-'
225232
) : isLoadingStats || !stats ? (
226233
<EuiLoadingSpinner size="s" />
234+
) : stats.bytesPerDay ? (
235+
formatIngestionRate(stats.bytesPerDay)
227236
) : (
228-
formatNumber(stats.totalDocs, '0,0')
237+
'-'
229238
)}
230239
</PrivilegesWarningIconWrapper>
231240
}
232241
/>
233-
</EuiPanel>
242+
</>
234243
);
235244
}
236245

237246
function MetadataRow({
238247
metadata,
239248
value,
240249
tip,
241-
button,
242250
dataTestSubj,
243251
}: {
244252
metadata: string;
245253
value: ReactNode;
246254
tip?: string;
247-
button?: ReactNode;
248255
dataTestSubj?: string;
249256
}) {
250257
return (
@@ -267,8 +274,13 @@ function MetadataRow({
267274
) : null}
268275
</EuiFlexGroup>
269276
</EuiFlexItem>
270-
<EuiFlexItem grow={4}>{value}</EuiFlexItem>
271-
<EuiFlexItem grow={1}>{button}</EuiFlexItem>
277+
<EuiFlexItem grow={5}>{value}</EuiFlexItem>
272278
</EuiFlexGroup>
273279
);
274280
}
281+
282+
const useDateFormatter = () => {
283+
const { fieldFormats } = useKibana().dependencies.start;
284+
285+
return fieldFormats.getDefaultInstance(KBN_FIELD_TYPES.DATE, [ES_FIELD_TYPES.DATE]);
286+
};

0 commit comments

Comments
 (0)