Skip to content

Commit f2ffe3c

Browse files
committed
test
Signed-off-by: Kaituo Li <[email protected]>
1 parent 0434923 commit f2ffe3c

File tree

144 files changed

+28807
-21
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

144 files changed

+28807
-21
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import { EuiFlexGroup, EuiFlexItem, EuiSmallButton } from '@elastic/eui';
13+
import React from 'react';
14+
import { APP_PATH, FORECASTING_FEATURE_NAME } from '../../utils/constants';
15+
import { useLocation } from 'react-router-dom';
16+
import { constructHrefWithDataSourceId, getDataSourceFromURL } from '../../pages/utils/helpers';
17+
18+
export const CreateForecasterButtons = () => {
19+
const location = useLocation();
20+
const MDSQueryParams = getDataSourceFromURL(location);
21+
const dataSourceId = MDSQueryParams.dataSourceId;
22+
23+
const createForecasterUrl = `${FORECASTING_FEATURE_NAME}#` + constructHrefWithDataSourceId(`${APP_PATH.CREATE_FORECASTER}`, dataSourceId, false);
24+
25+
return (
26+
<EuiFlexGroup direction="row" gutterSize="m" justifyContent="center">
27+
<EuiFlexItem grow={false}>
28+
<EuiSmallButton
29+
style={{ width: '200px' }}
30+
fill
31+
href={createForecasterUrl}
32+
data-test-subj="createForecasterButton"
33+
iconType="plusInCircle"
34+
>
35+
Create forecaster
36+
</EuiSmallButton>
37+
</EuiFlexItem>
38+
</EuiFlexGroup>
39+
);
40+
};

public/components/FormattedFormRow/FormattedFormRow.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type FormattedFormRowProps = {
1616
title?: string;
1717
formattedTitle?: ReactNode;
1818
children: ReactElement;
19-
hint?: string | string[];
19+
hint?: string | string[] | ReactNode | ReactNode[];
2020
isInvalid?: boolean;
2121
error?: ReactNode | ReactNode[];
2222
fullWidth?: boolean;
@@ -42,7 +42,8 @@ export const FormattedFormRow = (props: FormattedFormRowProps) => {
4242
))
4343
: null;
4444

45-
const { formattedTitle, linkToolTip, ...euiFormRowProps } = props;
45+
// Extract hintLink to avoid passing it to EuiCompressedFormRow as an unknown prop
46+
const { formattedTitle, hintLink, linkToolTip, ...euiFormRowProps } = props;
4647

4748
return (
4849
<EuiCompressedFormRow
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import { EuiFlexGroup, EuiFlexItem, EuiSmallButton } from '@elastic/eui';
13+
import React from 'react';
14+
import { APP_PATH, FORECASTING_FEATURE_NAME } from '../../utils/constants';
15+
import { useLocation } from 'react-router-dom';
16+
import { constructHrefWithDataSourceId, getDataSourceFromURL } from '../../pages/utils/helpers';
17+
18+
export const RefreshForecastersButton = () => {
19+
const location = useLocation();
20+
const MDSQueryParams = getDataSourceFromURL(location);
21+
const dataSourceId = MDSQueryParams.dataSourceId;
22+
23+
const refreshForecastersUrl = `${FORECASTING_FEATURE_NAME}#` + constructHrefWithDataSourceId(`${APP_PATH.LIST_FORECASTERS}`, dataSourceId, false);
24+
25+
return (
26+
<EuiFlexGroup direction="row" gutterSize="m" justifyContent="center">
27+
<EuiFlexItem grow={false}>
28+
<EuiSmallButton
29+
style={{ width: '200px' }}
30+
href={refreshForecastersUrl}
31+
data-test-subj="refreshForecastersButton"
32+
iconType="refresh"
33+
>
34+
Refresh
35+
</EuiSmallButton>
36+
</EuiFlexItem>
37+
</EuiFlexGroup>
38+
);
39+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import React from 'react';
13+
import { render } from '@testing-library/react';
14+
import { Router } from 'react-router-dom';
15+
import { createMemoryHistory } from 'history';
16+
import { RefreshForecastersButton } from '../RefreshForecastersButton';
17+
18+
describe('<RefreshForecastersButton /> spec', () => {
19+
beforeAll(() => {
20+
Object.defineProperty(window, 'location', {
21+
value: {
22+
href: 'http://test.com',
23+
pathname: '/',
24+
search: '',
25+
hash: '',
26+
},
27+
writable: true
28+
});
29+
});
30+
31+
test('renders component', () => {
32+
const history = createMemoryHistory();
33+
const { container, getByText } = render(
34+
<Router history={history}>
35+
<RefreshForecastersButton />
36+
</Router>
37+
);
38+
39+
expect(container.firstChild).toMatchSnapshot();
40+
expect(getByText('Refresh')).toBeInTheDocument();
41+
});
42+
});

public/forecasting_app.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import { CoreStart, AppMountParameters } from '../../../src/core/public';
13+
import React from 'react';
14+
import ReactDOM from 'react-dom';
15+
import { HashRouter as Router, Route } from 'react-router-dom';
16+
import { ForecastMain } from './pages/main/ForecastMain';
17+
import { Provider } from 'react-redux';
18+
import configureStore from './redux/configureStore';
19+
import { CoreServicesContext } from './components/CoreServices/CoreServices';
20+
21+
export function renderApp(coreStart: CoreStart, params: AppMountParameters, landingPage: string | undefined, hideInAppSideNavBar: boolean) {
22+
const http = coreStart.http;
23+
const store = configureStore(http);
24+
25+
// Load Chart's dark mode CSS (if applicable)
26+
const isDarkMode = coreStart.uiSettings.get('theme:darkMode') || false;
27+
if (isDarkMode) {
28+
require('@elastic/charts/dist/theme_only_dark.css');
29+
} else {
30+
require('@elastic/charts/dist/theme_only_light.css');
31+
}
32+
33+
ReactDOM.render(
34+
<Provider store={store}>
35+
<Router>
36+
<Route
37+
render={(props) => (
38+
<CoreServicesContext.Provider value={coreStart}>
39+
<ForecastMain
40+
setHeaderActionMenu={params.setHeaderActionMenu}
41+
landingPage={landingPage}
42+
hideInAppSideNavBar={hideInAppSideNavBar}
43+
{...props}
44+
/>
45+
</CoreServicesContext.Provider>
46+
)}
47+
/>
48+
</Router>
49+
</Provider>,
50+
params.element
51+
);
52+
return () => ReactDOM.unmountComponentAtNode(params.element);
53+
}

public/models/interfaces.ts

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import { InitProgress } from '../../server/models/interfaces';
1313
import { DATA_TYPES } from '../utils/constants';
14-
import { DETECTOR_STATE } from '../../server/utils/constants';
14+
import { DETECTOR_STATE, FORECASTER_STATE } from '../../server/utils/constants';
1515
import { Duration } from 'moment';
1616
import moment from 'moment';
1717
import { MDSQueryParams } from '../../server/models/types';
@@ -231,6 +231,56 @@ export type DetectorListItem = {
231231
detectorType?: string;
232232
};
233233

234+
export type Forecaster = {
235+
primaryTerm: number;
236+
seqNo: number;
237+
id: string;
238+
name: string;
239+
description: string;
240+
timeField: string;
241+
indices: string[];
242+
resultIndex?: string;
243+
resultIndexMinAge?: number;
244+
resultIndexMinSize?: number;
245+
resultIndexTtl?: number;
246+
flattenCustomResultIndex?: boolean;
247+
filterQuery: { [key: string]: any };
248+
featureAttributes: FeatureAttributes[];
249+
windowDelay: { period: Schedule };
250+
forecastInterval: { period: Schedule };
251+
shingleSize: number;
252+
uiMetadata: UiMetaData;
253+
lastUpdateTime: number;
254+
enabled?: boolean;
255+
enabledTime?: number;
256+
disabledTime?: number;
257+
curState: FORECASTER_STATE; // combined state of realTime and runOnce
258+
stateError: string; // combined error of realTime and runOnce
259+
initProgress?: InitProgress; // realTime
260+
categoryField?: string[];
261+
taskId?: string; // runOnce
262+
taskState?: FORECASTER_STATE; // runOnce
263+
taskProgress?: number; // runOnce
264+
taskError?: string; // runOnce
265+
lastStateUpdateTime?: number;
266+
imputationOption?: ImputationOption;
267+
suggestedSeasonality?: number;
268+
recencyEmphasis?: number;
269+
horizon?: number;
270+
history?: number;
271+
lastUiBreakingChangeTime?: number;
272+
};
273+
274+
export type ForecasterListItem = {
275+
id: string;
276+
name: string;
277+
indices: string[];
278+
curState: FORECASTER_STATE;
279+
realTimeLastUpdateTime: number;
280+
runOnceLastUpdateTime: number;
281+
stateError: string;
282+
};
283+
234284
export type EntityData = {
235285
name: string;
236286
value: string;
@@ -342,3 +392,31 @@ export interface MDSStates {
342392
queryParams: MDSQueryParams;
343393
selectedDataSourceId: string | undefined;
344394
}
395+
396+
/* export type ForecastData = {
397+
dataQuality: number;
398+
forecasterId?: string;
399+
endTime: number;
400+
startTime: number;
401+
plotTime?: number;
402+
entity?: EntityData[];
403+
features?: { [key: string]: ForecastFeatureAggregationData };
404+
aggInterval?: string;
405+
}; */
406+
407+
export type ForecastFeatureAggregationData = {
408+
data: number;
409+
name?: string;
410+
endTime: number;
411+
startTime: number;
412+
plotTime?: number;
413+
lowerBound: number[];
414+
upperBound: number[];
415+
forecastValue: number[];
416+
forecastStartTime: number[];
417+
forecastEndTime: number[];
418+
};
419+
420+
/* export type ForecastResult = {
421+
forecastResult: ForecastData[];
422+
}; */

0 commit comments

Comments
 (0)