diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a281585b9d7bc..a9ddcddf840cb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -456,6 +456,7 @@ src/platform/packages/shared/kbn-discover-utils @elastic/kibana-data-discovery src/platform/packages/shared/kbn-doc-links @elastic/docs src/platform/packages/shared/kbn-dom-drag-drop @elastic/kibana-visualizations @elastic/kibana-data-discovery src/platform/packages/shared/kbn-ebt-tools @elastic/kibana-core +src/platform/packages/shared/kbn-elapsed-datetime-formatter @elastic/obs-ux-management-team src/platform/packages/shared/kbn-elastic-agent-utils @elastic/obs-ux-logs-team src/platform/packages/shared/kbn-encrypted-saved-objects-shared @elastic/kibana-security src/platform/packages/shared/kbn-es @elastic/kibana-operations diff --git a/package.json b/package.json index 7120670014483..d84d0a3504ab6 100644 --- a/package.json +++ b/package.json @@ -492,6 +492,7 @@ "@kbn/ebt-tools": "link:src/platform/packages/shared/kbn-ebt-tools", "@kbn/ecs-data-quality-dashboard": "link:x-pack/solutions/security/packages/ecs-data-quality-dashboard", "@kbn/ecs-data-quality-dashboard-plugin": "link:x-pack/solutions/security/plugins/ecs_data_quality_dashboard", + "@kbn/elapsed-datetime-formatter": "link:src/platform/packages/shared/kbn-elapsed-datetime-formatter", "@kbn/elastic-agent-utils": "link:src/platform/packages/shared/kbn-elastic-agent-utils", "@kbn/elastic-assistant": "link:x-pack/platform/packages/shared/kbn-elastic-assistant", "@kbn/elastic-assistant-common": "link:x-pack/platform/packages/shared/kbn-elastic-assistant-common", diff --git a/packages/kbn-relative-time-display/package.json b/packages/kbn-relative-time-display/package.json new file mode 100644 index 0000000000000..f57695c48d1c9 --- /dev/null +++ b/packages/kbn-relative-time-display/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/relative-time-display", + "private": true, + "version": "1.0.0", + "license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0" +} diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/BUILD.bazel b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/BUILD.bazel new file mode 100644 index 0000000000000..82d4d3f2e79d8 --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/BUILD.bazel @@ -0,0 +1,34 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") + +SRCS = glob( + [ + "**/*.ts", + "**/*.tsx", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__/**", + "**/integration_tests/**", + "**/mocks/**", + "**/scripts/**", + "**/storybook/**", + "**/test_fixtures/**", + "**/test_helpers/**", + ], +) + +SHARED_DEPS = [ + "@npm//moment", + "//src/platform/packages/shared/kbn-i18n" +] + +js_library( + name = "kbn-elapsed-datetime-formatter", + package_name = "@kbn/elapsed-datetime-formatter", + srcs = ["package.json"] + SRCS, + deps = SHARED_DEPS, + visibility = ["//visibility:public"], +) diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/README.md b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/README.md new file mode 100644 index 0000000000000..9d61e40ccca14 --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/README.md @@ -0,0 +1,7 @@ +# @kbn/elapsed-datetime-formatter + +This package is intended to show the elapsed time from a provided date in days or hours and minutes. It also provides the ability to show a tooltip with the original timestamp in a readable format. + +## Examples + +An alert was created or triggered 2 minutes before the current time, but only has a timestamp. Use this package to show the elapsed time of `2 minutes ago` in human-readable, translatable text. diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/index.ts b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/index.ts new file mode 100644 index 0000000000000..6bc05df1e14a7 --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/index.ts @@ -0,0 +1,11 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export * from './src/elapsed_time'; +export * from './src/datetime'; diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/jest.config.js b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/jest.config.js new file mode 100644 index 0000000000000..6e1977cb5ecb5 --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/jest.config.js @@ -0,0 +1,14 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../..', + roots: ['/src/platform/packages/shared/kbn-elapsed-datetime-formatter'], +}; diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/kibana.jsonc b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/kibana.jsonc new file mode 100644 index 0000000000000..59cc5dda55f32 --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/kibana.jsonc @@ -0,0 +1,7 @@ +{ + "type": "shared-common", + "id": "@kbn/elapsed-datetime-formatter", + "owner": "@elastic/obs-ux-management-team", + "group": "platform", + "visibility": "shared" +} diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/package.json b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/package.json new file mode 100644 index 0000000000000..bf73450125b5c --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/elapsed-datetime-formatter", + "private": true, + "version": "1.0.0", + "license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0" +} \ No newline at end of file diff --git a/x-pack/solutions/observability/plugins/observability/common/utils/formatters/datetime.test.ts b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/datetime.test.ts similarity index 95% rename from x-pack/solutions/observability/plugins/observability/common/utils/formatters/datetime.test.ts rename to src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/datetime.test.ts index aaf0b1e574221..d1dc276c24d02 100644 --- a/x-pack/solutions/observability/plugins/observability/common/utils/formatters/datetime.test.ts +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/datetime.test.ts @@ -1,8 +1,10 @@ /* * 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. + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". */ import moment from 'moment-timezone'; diff --git a/x-pack/solutions/observability/plugins/observability/common/utils/formatters/datetime.ts b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/datetime.ts similarity index 91% rename from x-pack/solutions/observability/plugins/observability/common/utils/formatters/datetime.ts rename to src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/datetime.ts index ebb332797ad2e..e099ed08e2e40 100644 --- a/x-pack/solutions/observability/plugins/observability/common/utils/formatters/datetime.ts +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/datetime.ts @@ -1,8 +1,10 @@ /* * 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. + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". */ import moment from 'moment-timezone'; diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/elapsed_time.test.tsx b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/elapsed_time.test.tsx new file mode 100644 index 0000000000000..da7cb0cc0a840 --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/elapsed_time.test.tsx @@ -0,0 +1,67 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import moment from 'moment'; +import { getElapsedTimeText } from './elapsed_time'; + +jest.mock('@kbn/i18n', () => ({ + i18n: { + translate: (_id: string, { defaultMessage, values }: any) => { + if (values) { + return defaultMessage + .replace( + '{day, plural, one {# day} other {# days}}', + `${values.day} day${values.day === 1 ? '' : 's'}` + ) + .replace( + '{hour, plural, one {# hour} other {# hours}}', + `${values.hour} hour${values.hour === 1 ? '' : 's'}` + ) + .replace( + '{minute, plural, one {# minute} other {# minutes}}', + `${values.minute} minute${values.minute === 1 ? '' : 's'}` + ) + .replace( + '{hour, plural, one {# hour} other {# hours}}, {minute, plural, one {# minute} other {# minutes}}', + `${values.hour} hour${values.hour === 1 ? '' : 's'}, ${values.minute} minute${ + values.minute === 1 ? '' : 's' + }` + ); + } + return defaultMessage; + }, + }, +})); + +describe('getElapsedTimeText', () => { + it('returns days if duration has days', () => { + const duration = moment.duration({ days: 2, hours: 0, minutes: 0 }); + expect(getElapsedTimeText(duration)).toContain('2 days'); + }); + + it('returns hours if duration has hours and no minutes', () => { + const duration = moment.duration({ days: 0, hours: 3, minutes: 0 }); + expect(getElapsedTimeText(duration)).toContain('3 hours'); + }); + + it('returns hours and minutes if duration has both', () => { + const duration = moment.duration({ days: 0, hours: 1, minutes: 15 }); + expect(getElapsedTimeText(duration)).toContain('1 hour, 15 minutes'); + }); + + it('returns minutes if duration has only minutes', () => { + const duration = moment.duration({ days: 0, hours: 0, minutes: 5 }); + expect(getElapsedTimeText(duration)).toContain('5 minutes'); + }); + + it('returns "a few seconds ago" if duration is less than a minute', () => { + const duration = moment.duration({ days: 0, hours: 0, minutes: 0, seconds: 30 }); + expect(getElapsedTimeText(duration)).toBe('a few seconds ago'); + }); +}); diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/elapsed_time.tsx b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/elapsed_time.tsx new file mode 100644 index 0000000000000..c5f7f5cc9549c --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/src/elapsed_time.tsx @@ -0,0 +1,81 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiToolTip } from '@elastic/eui'; +import moment from 'moment'; +import { asAbsoluteDateTime, TimeUnit } from './datetime'; + +interface Props { + /** + * timestamp in milliseconds + */ + time: number; + /** + * Threshold in hours to switch from relative to absolute time display + * If not provided, it defaults to 2 hours + */ + elapsedDisplayThreshold?: number; + timeUnit?: TimeUnit; +} + +export function getElapsedTimeText(duration: moment.Duration) { + const [day, hour, minute] = [duration.days(), duration.hours(), duration.minutes()]; + // keeping days for flexibility, but it is not used in the current implementation. If day is detected, it will be displayed without hours or minutes + if (day > 0) { + return i18n.translate('xpack.observability.alertsTable.highFidelityDurationWithDays', { + defaultMessage: '{day, plural, one {# day} other {# days}} ago', + values: { day }, + }); + } + if (hour > 0 && minute === 0) { + return i18n.translate('xpack.observability.alertsTable.highFidelityDurationWithHours', { + defaultMessage: '{hour, plural, one {# hour} other {# hours}} ago', + values: { hour }, + }); + } + if (hour > 0) { + return i18n.translate( + 'xpack.observability.alertsTable.highFidelityDurationWithHoursAndMinutes', + { + defaultMessage: + '{hour, plural, one {# hour} other {# hours}}, {minute, plural, one {# minute} other {# minutes}} ago', + values: { hour, minute }, + } + ); + } + if (minute > 0) { + return i18n.translate('xpack.observability.alertsTable.highFidelityDuration', { + defaultMessage: '{minute, plural, one {# minute} other {# minutes}} ago', + values: { minute }, + }); + } + return i18n.translate('xpack.observability.alertsTable.highFidelityDurationRecently', { + defaultMessage: 'a few seconds ago', + }); +} + +export function ElapsedTimestampTooltip({ + time, + elapsedDisplayThreshold = 24, + timeUnit = 'milliseconds', +}: Props): JSX.Element { + const duration = moment.duration(new Date().getTime() - time); + const absoluteTimeLabel = asAbsoluteDateTime(time, timeUnit); + + const timeDisplay = + duration.asHours() > elapsedDisplayThreshold ? absoluteTimeLabel : getElapsedTimeText(duration); + + return ( + + <>{timeDisplay} + + ); +} diff --git a/src/platform/packages/shared/kbn-elapsed-datetime-formatter/tsconfig.json b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/tsconfig.json new file mode 100644 index 0000000000000..b396ea0bc88e0 --- /dev/null +++ b/src/platform/packages/shared/kbn-elapsed-datetime-formatter/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": ["@kbn/i18n"] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 21c8e4f48b09b..859dc1643759f 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -840,6 +840,8 @@ "@kbn/ecs-data-quality-dashboard/*": ["x-pack/solutions/security/packages/ecs-data-quality-dashboard/*"], "@kbn/ecs-data-quality-dashboard-plugin": ["x-pack/solutions/security/plugins/ecs_data_quality_dashboard"], "@kbn/ecs-data-quality-dashboard-plugin/*": ["x-pack/solutions/security/plugins/ecs_data_quality_dashboard/*"], + "@kbn/elapsed-datetime-formatter": ["src/platform/packages/shared/kbn-elapsed-datetime-formatter"], + "@kbn/elapsed-datetime-formatter/*": ["src/platform/packages/shared/kbn-elapsed-datetime-formatter/*"], "@kbn/elastic-agent-utils": ["src/platform/packages/shared/kbn-elastic-agent-utils"], "@kbn/elastic-agent-utils/*": ["src/platform/packages/shared/kbn-elastic-agent-utils/*"], "@kbn/elastic-assistant": ["x-pack/platform/packages/shared/kbn-elastic-assistant"], diff --git a/x-pack/solutions/observability/plugins/observability/common/index.ts b/x-pack/solutions/observability/plugins/observability/common/index.ts index 48efc92ab7f39..3e3fbc7081d0d 100644 --- a/x-pack/solutions/observability/plugins/observability/common/index.ts +++ b/x-pack/solutions/observability/plugins/observability/common/index.ts @@ -12,7 +12,6 @@ export { getDurationFormatter, asDuration, asDynamicBytes, - asAbsoluteDateTime, asInteger, } from './utils/formatters'; export { getInspectResponse } from './utils/get_inspect_response'; diff --git a/x-pack/solutions/observability/plugins/observability/common/utils/formatters/duration.ts b/x-pack/solutions/observability/plugins/observability/common/utils/formatters/duration.ts index 2d58338d983cb..9bd3dbfb2c3d4 100644 --- a/x-pack/solutions/observability/plugins/observability/common/utils/formatters/duration.ts +++ b/x-pack/solutions/observability/plugins/observability/common/utils/formatters/duration.ts @@ -6,11 +6,11 @@ */ import { i18n } from '@kbn/i18n'; +import { TimeUnit } from '@kbn/elapsed-datetime-formatter'; import moment from 'moment'; import { memoize } from 'lodash'; import { NOT_AVAILABLE_LABEL } from '../../i18n'; import { asDecimalOrInteger, asInteger, asDecimal } from './formatters'; -import { TimeUnit } from './datetime'; import { Maybe } from '../../typings'; import { isFiniteNumber } from '../is_finite_number'; diff --git a/x-pack/solutions/observability/plugins/observability/common/utils/formatters/index.ts b/x-pack/solutions/observability/plugins/observability/common/utils/formatters/index.ts index 1a431867308b6..3413103e60f2f 100644 --- a/x-pack/solutions/observability/plugins/observability/common/utils/formatters/index.ts +++ b/x-pack/solutions/observability/plugins/observability/common/utils/formatters/index.ts @@ -6,6 +6,5 @@ */ export * from './formatters'; -export * from './datetime'; export * from './duration'; export * from './size'; diff --git a/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/cell_value.tsx b/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/cell_value.tsx index c11163c5c5694..d10004f1744f5 100644 --- a/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/cell_value.tsx +++ b/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/cell_value.tsx @@ -27,6 +27,7 @@ import { import { isEmpty } from 'lodash'; import type { Alert } from '@kbn/alerting-types'; import type { JsonValue } from '@kbn/utility-types'; +import { ElapsedTimestampTooltip } from '@kbn/elapsed-datetime-formatter'; import { RELATED_ACTIONS_COL, RELATED_ALERT_REASON, @@ -93,7 +94,11 @@ export const AlertsTableCellValue: GetObservabilityAlertsTableProp<'renderCellVa ), [ALERT_START]: (value) => ( - + ), [ALERT_RULE_EXECUTION_TIMESTAMP]: (value) => ( diff --git a/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/relative_timestamp_tooltip.tsx b/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/relative_timestamp_tooltip.tsx new file mode 100644 index 0000000000000..7b69d4ccad9e7 --- /dev/null +++ b/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/relative_timestamp_tooltip.tsx @@ -0,0 +1,80 @@ +/* + * 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 { EuiToolTip } from '@elastic/eui'; +import moment from 'moment'; +import { asAbsoluteDateTime, TimeUnit } from '@kbn/elapsed-datetime-formatter'; + +interface Props { + /** + * timestamp in milliseconds + */ + time: number; + /** + * Threshold in hours to switch from relative to absolute time display + * If not provided, it defaults to 2 hours + */ + relativeDisplayThreshold?: number; + timeUnit?: TimeUnit; +} + +export function getRelativeTimeText(duration: moment.Duration) { + const [day, hour, minute] = [duration.days(), duration.hours(), duration.minutes()]; + if (day > 0) { + return i18n.translate('xpack.observability.alertsTable.highFidelityDurationWithDays', { + defaultMessage: '{day, plural, one {# day} other {# days}} ago', + values: { day }, + }); + } + if (hour > 0 && minute === 0) { + return i18n.translate('xpack.observability.alertsTable.highFidelityDurationWithHours', { + defaultMessage: '{hour, plural, one {# hour} other {# hours}} ago', + values: { hour }, + }); + } + if (hour > 0) { + return i18n.translate( + 'xpack.observability.alertsTable.highFidelityDurationWithHoursAndMinutes', + { + defaultMessage: + '{hour, plural, one {# hour} other {# hours}}, {minute, plural, one {# minute} other {# minutes}} ago', + values: { hour, minute }, + } + ); + } + if (minute > 0) { + return i18n.translate('xpack.observability.alertsTable.highFidelityDuration', { + defaultMessage: '{minute, plural, one {# minute} other {# minutes}} ago', + values: { minute }, + }); + } + return i18n.translate('xpack.observability.alertsTable.highFidelityDurationRecently', { + defaultMessage: 'a few seconds ago', + }); +} + +export function RelativeTimestampTooltip({ + time, + relativeDisplayThreshold = 24, + timeUnit = 'milliseconds', +}: Props) { + const duration = moment.duration(new Date().getTime() - time); + const absoluteTimeLabel = asAbsoluteDateTime(time, timeUnit); + + const timeDisplay = + duration.asHours() > relativeDisplayThreshold + ? absoluteTimeLabel + : getRelativeTimeText(duration); + + return ( + + <>{timeDisplay} + + ); +} diff --git a/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/timestamp_tooltip.tsx b/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/timestamp_tooltip.tsx index 7b82455ad5932..572b2522811a2 100644 --- a/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/timestamp_tooltip.tsx +++ b/x-pack/solutions/observability/plugins/observability/public/components/alerts_table/common/timestamp_tooltip.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { EuiToolTip } from '@elastic/eui'; -import { asAbsoluteDateTime, TimeUnit } from '../../../../common/utils/formatters/datetime'; +import { asAbsoluteDateTime, TimeUnit } from '@kbn/elapsed-datetime-formatter'; interface Props { /** diff --git a/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/components/related_alerts/get_related_columns.tsx b/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/components/related_alerts/get_related_columns.tsx index 3070ac5806d3f..6ba863b1641b6 100644 --- a/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/components/related_alerts/get_related_columns.tsx +++ b/x-pack/solutions/observability/plugins/observability/public/pages/alert_details/components/related_alerts/get_related_columns.tsx @@ -6,7 +6,7 @@ */ import type { EuiDataGridColumn } from '@elastic/eui'; -import { ALERT_CASE_IDS, ALERT_RULE_NAME, ALERT_STATUS } from '@kbn/rule-data-utils'; +import { ALERT_CASE_IDS, ALERT_RULE_NAME, ALERT_START, ALERT_STATUS } from '@kbn/rule-data-utils'; import { i18n } from '@kbn/i18n'; export const RELATED_ALERT_REASON = 'relatedAlertReason'; @@ -24,6 +24,15 @@ export const getRelatedColumns = (): EuiDataGridColumn[] => { isSortable: false, actions: false, }, + { + id: ALERT_START, + displayAsText: i18n.translate('xpack.observability.alertsTGrid.startColumnDescription', { + defaultMessage: 'Created', + }), + initialWidth: 120, + isSortable: false, + actions: false, + }, { id: ALERT_RULE_NAME, displayAsText: i18n.translate('xpack.observability.alertsTGrid.ruleNameColumnDescription', { diff --git a/x-pack/solutions/observability/plugins/observability/tsconfig.json b/x-pack/solutions/observability/plugins/observability/tsconfig.json index baa1f1f88bd15..a014cadddbcf7 100644 --- a/x-pack/solutions/observability/plugins/observability/tsconfig.json +++ b/x-pack/solutions/observability/plugins/observability/tsconfig.json @@ -122,8 +122,9 @@ "@kbn/object-utils", "@kbn/task-manager-plugin", "@kbn/core-saved-objects-server", - "@kbn/core-pricing-browser-mocks", "@kbn/esql", + "@kbn/elapsed-datetime-formatter", + "@kbn/core-pricing-browser-mocks" ], "exclude": ["target/**/*"] } diff --git a/x-pack/solutions/observability/plugins/profiling/public/views/storage_explorer/host_breakdown/hosts_table.tsx b/x-pack/solutions/observability/plugins/profiling/public/views/storage_explorer/host_breakdown/hosts_table.tsx index 9ace13585b528..98779f3c05c8d 100644 --- a/x-pack/solutions/observability/plugins/profiling/public/views/storage_explorer/host_breakdown/hosts_table.tsx +++ b/x-pack/solutions/observability/plugins/profiling/public/views/storage_explorer/host_breakdown/hosts_table.tsx @@ -16,7 +16,8 @@ import { EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { asDynamicBytes, asAbsoluteDateTime } from '@kbn/observability-plugin/common'; +import { asDynamicBytes } from '@kbn/observability-plugin/common'; +import { asAbsoluteDateTime } from '@kbn/elapsed-datetime-formatter'; import React, { useMemo, useState } from 'react'; import type { StorageExplorerHostDetails } from '../../../../common/storage_explorer'; import { useProfilingParams } from '../../../hooks/use_profiling_params'; diff --git a/x-pack/solutions/observability/plugins/profiling/tsconfig.json b/x-pack/solutions/observability/plugins/profiling/tsconfig.json index b270101d3c37b..e58fe7ce0a606 100644 --- a/x-pack/solutions/observability/plugins/profiling/tsconfig.json +++ b/x-pack/solutions/observability/plugins/profiling/tsconfig.json @@ -57,7 +57,8 @@ "@kbn/apm-data-access-plugin", "@kbn/ebt-tools", "@kbn/core-security-server", - "@kbn/charts-theme" + "@kbn/charts-theme", + "@kbn/elapsed-datetime-formatter" // add references to other TypeScript projects the plugin depends on // requiredPlugins from ./kibana.json diff --git a/yarn.lock b/yarn.lock index f9657c21bb779..2fddbe09680af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5449,6 +5449,10 @@ version "0.0.0" uid "" +"@kbn/elapsed-datetime-formatter@link:src/platform/packages/shared/kbn-elapsed-datetime-formatter": + version "0.0.0" + uid "" + "@kbn/elastic-agent-utils@link:src/platform/packages/shared/kbn-elastic-agent-utils": version "0.0.0" uid ""