diff --git a/CHANGELOG.md b/CHANGELOG.md index a079ec4cfc7..a0241c071a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Added `useInnerText` and `EuiInnerText` component utilities for retrieving text content of elements ([#2100](https://github.com/elastic/eui/pull/2100)) - Converted `EuiRangeHightlight`, `EuiRangeLabel`, `EuiRangeLevels`, `EuiRangeSlider`, `EuiRangeThumb`, `EuiRangeTicks`, `EuiRangeTrack`, and `EuiRangeWrapper` to TypeScript ([#2124](https://github.com/elastic/eui/pull/2124)) - Converted `EuiAccordion` to TypeScript ([#2128](https://github.com/elastic/eui/pull/2128)) +- Exported `prettyDuration` and `commonDurationRanges` for pretty printing date ranges outside `EuiSuperDatePicker` ([#2132](https://github.com/elastic/eui/pull/2132)) **Bug fixes** diff --git a/src-docs/src/routes.js b/src-docs/src/routes.js index 1cb118d3e5e..90ec7b00241 100644 --- a/src-docs/src/routes.js +++ b/src-docs/src/routes.js @@ -29,6 +29,8 @@ import { ColorPaletteExample } from './views/color_palette/color_palette_example import { IsColorDarkExample } from './views/is_color_dark/is_color_dark_example'; +import { PrettyDurationExample } from './views/pretty_duration/pretty_duration_example'; + import { UtilityClassesExample } from './views/utility_classes/utility_classes_example'; // Component examples @@ -376,6 +378,7 @@ const navigation = [ InnerTextExample, I18nExample, IsColorDarkExample, + PrettyDurationExample, MutationObserverExample, OutsideClickDetectorExample, PortalExample, diff --git a/src-docs/src/views/pretty_duration/pretty_duration.js b/src-docs/src/views/pretty_duration/pretty_duration.js new file mode 100644 index 00000000000..791a3bfaf2f --- /dev/null +++ b/src-docs/src/views/pretty_duration/pretty_duration.js @@ -0,0 +1,77 @@ +import React, { Fragment } from 'react'; + +import { + EuiSpacer, + EuiCodeBlock, + EuiText, + prettyDuration, +} from '../../../../src/components'; + +const examples = [ + { + start: '2018-01-17T18:57:57.149Z', + end: '2018-01-17T20:00:00.000Z', + quickRanges: [], + dateFormat: 'MMMM Do YYYY, HH:mm:ss.SSS', + }, + { + start: '2018-01-17T18:57:57.149Z', + end: '2018-01-17T20:00:00.000Z', + quickRanges: [], + dateFormat: 'MMMM Do YYYY @ HH:mm:ss.SSS', + }, + { + start: '2018-01-17T18:57:57.149Z', + end: 'now-2h', + quickRanges: [], + dateFormat: 'MMMM Do YYYY @ HH:mm:ss.SSS', + }, + { + start: 'now-17m', + end: 'now', + quickRanges: [], + dateFormat: 'MMMM Do YYYY @ HH:mm:ss.SSS', + }, + { + start: 'now-17m', + end: 'now-1m', + quickRanges: [], + dateFormat: 'MMMM Do YYYY @ HH:mm:ss.SSS', + }, + { + start: 'now-15m', + end: 'now', + quickRanges: [ + { + start: 'now-15m', + end: 'now', + label: 'quick range 15 minutes custom display', + }, + ], + dateFormat: 'MMMM Do YYYY, HH:mm:ss.SSS', + }, +]; + +export default function prettyDurationExample() { + return ( + + {examples.map(({ start, end, quickRanges, dateFormat }, idx) => ( +
+ + prettyDuration('{start}', '{end}',{' '} + {JSON.stringify(quickRanges)}, ' + {dateFormat}') + + + + + +

{prettyDuration(start, end, quickRanges, dateFormat)}

+
+ + +
+ ))} +
+ ); +} diff --git a/src-docs/src/views/pretty_duration/pretty_duration_example.js b/src-docs/src/views/pretty_duration/pretty_duration_example.js new file mode 100644 index 00000000000..e28292a2f12 --- /dev/null +++ b/src-docs/src/views/pretty_duration/pretty_duration_example.js @@ -0,0 +1,71 @@ +import React, { Fragment } from 'react'; + +import { renderToHtml } from '../../services'; + +import { GuideSectionTypes } from '../../components'; + +import { + EuiAccordion, + EuiCode, + EuiCodeBlock, + EuiSpacer, + commonDurationRanges, +} from '../../../../src/components'; + +import PrettyDuration from './pretty_duration'; +const prettyDurationSource = require('!!raw-loader!./pretty_duration'); +const prettyDurationHtml = renderToHtml(PrettyDuration); + +export const PrettyDurationExample = { + title: 'Pretty Duration', + sections: [ + { + source: [ + { + type: GuideSectionTypes.JS, + code: prettyDurationSource, + }, + { + type: GuideSectionTypes.HTML, + code: prettyDurationHtml, + }, + ], + text: ( + +

+ Use prettyDuration to convert a start and end + date string to a human-friendly format. +

+ +

+ Start and end values for the duration are passed as the first and + second arguments, respectively. These can be timestamps ( + 2018-01-17T18:57:57.149Z) or relative times ( + now-15m). +

+ +

+ An array of quick range values is passed as the third argument. + These are used to pretty format custom ranges. EUI exports + commonDurationRanges which can be passed here. +

+ + + + {JSON.stringify(commonDurationRanges, null, 2)} + + + + + +

+ The output date/time format is specified by the fourth argument. +

+
+ ), + demo: , + }, + ], +}; diff --git a/src/components/date_picker/index.d.ts b/src/components/date_picker/index.d.ts index 2647f4e4891..ff810cec0be 100644 --- a/src/components/date_picker/index.d.ts +++ b/src/components/date_picker/index.d.ts @@ -86,4 +86,19 @@ declare module '@elastic/eui' { export const ReactDatePicker: typeof _ReactDatePicker; export const ReactDatePickerProps: _ReactDatePickerProps; + + interface DurationRange { + start: string; + end: string; + label: string; + } + + export const commonDurationRanges: DurationRange[]; + + export function prettyDuration( + timeFrom: string, + timeTo: string, + quickRanges: DurationRange[], + dateFormat: string + ): string; } diff --git a/src/components/date_picker/index.js b/src/components/date_picker/index.js index 4cd12a69bf6..69a0ec433e7 100644 --- a/src/components/date_picker/index.js +++ b/src/components/date_picker/index.js @@ -2,4 +2,9 @@ export { EuiDatePicker } from './date_picker'; export { EuiDatePickerRange } from './date_picker_range'; -export { EuiSuperDatePicker, EuiSuperUpdateButton } from './super_date_picker'; +export { + EuiSuperDatePicker, + EuiSuperUpdateButton, + prettyDuration, + commonDurationRanges, +} from './super_date_picker'; diff --git a/src/components/date_picker/super_date_picker/index.js b/src/components/date_picker/super_date_picker/index.js index 148086735d8..978ec874cc6 100644 --- a/src/components/date_picker/super_date_picker/index.js +++ b/src/components/date_picker/super_date_picker/index.js @@ -1,3 +1,5 @@ export { EuiSuperDatePicker } from './super_date_picker'; export { EuiSuperUpdateButton } from './super_update_button'; + +export { prettyDuration, commonDurationRanges } from './pretty_duration'; diff --git a/src/components/date_picker/super_date_picker/pretty_duration.js b/src/components/date_picker/super_date_picker/pretty_duration.js index 86c6ac9a1e1..bbc05bede46 100644 --- a/src/components/date_picker/super_date_picker/pretty_duration.js +++ b/src/components/date_picker/super_date_picker/pretty_duration.js @@ -6,6 +6,17 @@ import { parseRelativeParts } from './relative_utils'; const ISO_FORMAT = 'YYYY-MM-DDTHH:mm:ss.SSSZ'; +export const commonDurationRanges = [ + { start: 'now/d', end: 'now/d', label: 'Today' }, + { start: 'now/w', end: 'now/w', label: 'This week' }, + { start: 'now/M', end: 'now/M', label: 'This month' }, + { start: 'now/y', end: 'now/y', label: 'This year' }, + { start: 'now-1d/d', end: 'now-1d/d', label: 'Yesterday' }, + { start: 'now/w', end: 'now', label: 'Week to date' }, + { start: 'now/M', end: 'now', label: 'Month to date' }, + { start: 'now/y', end: 'now', label: 'Year to date' }, +]; + function cantLookup(timeFrom, timeTo, dateFormat) { const displayFrom = formatTimeString(timeFrom, dateFormat); const displayTo = formatTimeString(timeTo, dateFormat, true); diff --git a/src/components/date_picker/super_date_picker/super_date_picker.js b/src/components/date_picker/super_date_picker/super_date_picker.js index a2c0f75d0ec..45e0527fd8b 100644 --- a/src/components/date_picker/super_date_picker/super_date_picker.js +++ b/src/components/date_picker/super_date_picker/super_date_picker.js @@ -6,7 +6,11 @@ import { recentlyUsedRangeShape, quickSelectPanelShape, } from './types'; -import { prettyDuration, showPrettyDuration } from './pretty_duration'; +import { + prettyDuration, + showPrettyDuration, + commonDurationRanges, +} from './pretty_duration'; import { prettyInterval } from './pretty_interval'; import dateMath from '@elastic/datemath'; @@ -20,6 +24,8 @@ import { EuiFormControlLayout } from '../../form'; import { EuiFlexGroup, EuiFlexItem } from '../../flex'; import { AsyncInterval } from './async_interval'; +export { prettyDuration, commonDurationRanges }; + function isRangeInvalid(start, end) { if (start === 'now' && end === 'now') { return true; @@ -105,16 +111,7 @@ export class EuiSuperDatePicker extends Component { end: 'now', isPaused: true, refreshInterval: 0, - commonlyUsedRanges: [ - { start: 'now/d', end: 'now/d', label: 'Today' }, - { start: 'now/w', end: 'now/w', label: 'This week' }, - { start: 'now/M', end: 'now/M', label: 'This month' }, - { start: 'now/y', end: 'now/y', label: 'This year' }, - { start: 'now-1d/d', end: 'now-1d/d', label: 'Yesterday' }, - { start: 'now/w', end: 'now', label: 'Week to date' }, - { start: 'now/M', end: 'now', label: 'Month to date' }, - { start: 'now/y', end: 'now', label: 'Year to date' }, - ], + commonlyUsedRanges: commonDurationRanges, dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', recentlyUsedRanges: [], showUpdateButton: true, diff --git a/src/components/index.js b/src/components/index.js index 2e93265dd77..9218bd62cdc 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -50,6 +50,8 @@ export { EuiDatePickerRange, EuiSuperDatePicker, EuiSuperUpdateButton, + prettyDuration, + commonDurationRanges, } from './date_picker'; export { EuiDelayHide } from './delay_hide';