Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow date_nanos dates in timestamp selection #795

Merged
merged 1 commit into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions public/pages/DefineDetector/components/Timestamp/Timestamp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,15 @@ export function Timestamp(props: TimestampProps) {
get(opensearchState, 'dataTypes.date', []) as string[]
);

const timeStampFieldOptions = isEmpty(dateFields)
const dateNanoFields = Array.from(
get(opensearchState, 'dataTypes.date_nanos', []) as string[]
);

const allDateFields = dateFields.concat(dateNanoFields);

const timeStampFieldOptions = isEmpty(allDateFields)
? []
: dateFields.map((dateField) => ({ label: dateField }));
: allDateFields.map((dateField) => ({ label: dateField }));

return (
<ContentPanel
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

import React from 'react';
import { Provider } from 'react-redux';
import {
HashRouter as Router,
RouteComponentProps,
Route,
Switch,
} from 'react-router-dom';
import { render } from '@testing-library/react';
import { Timestamp } from '../Timestamp';
import { DetectorDefinitionFormikValues } from '../../../models/interfaces';
import { CoreServicesContext } from '../../../../../components/CoreServices/CoreServices';
import { FormikProps, Formik } from 'formik';
import { coreServicesMock } from '../../../../../../test/mocks';

import { mockedStore } from '../../../../../redux/utils/testUtils';

const initialState = {
opensearch: {
indices: [
{
label: 'test-index',
health: 'green',
},
],
aliases: [],
dataTypes: {
date: ['created_at'],
date_nanos: ['timestamp'],
},
requesting: false,
searchResult: {},
errorMessage: '',
},
};

const values = {
name: 'test-ad',
description: 'desc',
index: [
{
label: 'test-index',
health: 'green',
},
],
filters: [],
filterQuery: JSON.stringify({ bool: { filter: [] } }, null, 4),
timeField: '',
interval: 10,
windowDelay: 1,
} as DetectorDefinitionFormikValues;

const formikProps = {
values: { values },
errors: {},
touched: {
index: true,
name: true,
timeField: true,
},
isSubmitting: false,
isValidating: false,
submitCount: 0,
initialErrors: {},
initialTouched: {},
isValid: true,
dirty: true,
validateOnBlur: true,
validateOnChange: true,
validateOnMount: true,
} as FormikProps<DetectorDefinitionFormikValues>;

describe('<Timestamp /> spec', () => {
test('renders the component', () => {
const { container } = render(
<Provider store={mockedStore(initialState)}>
<Router>
<Switch>
<Route
render={(props: RouteComponentProps) => (
<CoreServicesContext.Provider value={coreServicesMock}>
<Formik initialValues={values} onSubmit={jest.fn()}>
<Timestamp formikProps={formikProps} />
</Formik>
</CoreServicesContext.Provider>
)}
/>
</Switch>
</Router>
</Provider>
);
expect(container.firstChild).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Timestamp /> spec renders the component 1`] = `
<div
class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow"
style="padding: 20px;"
>
<div
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentSpaceBetween euiFlexGroup--directionRow euiFlexGroup--responsive"
style="padding: 0px;"
>
<div
class="euiFlexItem"
>
<h3
class="euiTitle euiTitle--small"
data-test-subj="contentPanelTitle"
>
Timestamp
</h3>
<div
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow euiFlexGroup--responsive"
>
<div
class="euiFlexItem content-panel-subTitle"
style="line-height: normal; max-width: 75%;"
>
Select the time field you want to use for the time filter.
</div>
</div>
</div>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<div
class="euiFlexGroup euiFlexGroup--gutterMedium euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentSpaceBetween euiFlexGroup--directionRow euiFlexGroup--responsive"
>
<div
class="euiFlexItem"
/>
</div>
</div>
</div>
<div>
<hr
class="euiHorizontalRule euiHorizontalRule--full euiHorizontalRule--marginSmall"
/>
<div
style="padding: 10px 0px;"
>
<div
class="euiFormRow"
hint="Choose the time field you want to use for time filter."
id="random_html_id-row"
title="Timestamp field"
>
<div
class="euiFormRow__labelWrapper"
>
<label
aria-invalid="false"
class="euiFormLabel euiFormRow__label"
for="random_html_id"
>
<div
style="line-height: 8px;"
>
<p>
Timestamp field
</p>
<br />
<div
class="euiText euiText--medium sublabel"
style="max-width: 400px;"
>
Choose the time field you want to use for time filter.
</div>
</div>
</label>
</div>
<div
class="euiFormRow__fieldWrapper"
>
<div
aria-expanded="false"
aria-haspopup="listbox"
class="euiComboBox"
data-test-subj="timestampFilter"
role="combobox"
>
<div
class="euiFormControlLayout"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<div
class="euiComboBox__inputWrap euiComboBox__inputWrap--noWrap"
data-test-subj="comboBoxInput"
tabindex="-1"
>
<p
class="euiComboBoxPlaceholder"
>
Find timestamp
</p>
<div
class="euiComboBox__input"
style="font-size: 14px; display: inline-block;"
>
<input
aria-controls=""
data-test-subj="comboBoxSearchInput"
id="random_html_id"
role="textbox"
style="box-sizing: content-box; width: 2px;"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
<div
class="euiFormControlLayoutIcons euiFormControlLayoutIcons--right"
>
<button
aria-label="Open list of options"
class="euiFormControlLayoutCustomIcon euiFormControlLayoutCustomIcon--clickable"
data-test-subj="comboBoxToggleListButton"
type="button"
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
role="img"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5.277 10.088c.02.014.04.03.057.047.582.55 1.134.812 1.666.812.586 0 1.84-.293 3.713-.88L9 6.212V2H7v4.212l-1.723 3.876Zm-.438.987L3.539 14h8.922l-1.32-2.969C9.096 11.677 7.733 12 7 12c-.74 0-1.463-.315-2.161-.925ZM6 2H5V1h6v1h-1v4l3.375 7.594A1 1 0 0 1 12.461 15H3.54a1 1 0 0 1-.914-1.406L6 6V2Z"
/>
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
1 change: 1 addition & 0 deletions public/redux/reducers/opensearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface DataTypes {
half_float?: string[];
boolean?: string[];
date?: string[];
date_nanos?: string[];
keyword?: string[];
text?: string[];
integer_range?: string[];
Expand Down
Loading