forked from opensearch-project/OpenSearch-Dashboards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworkspace.tsx
More file actions
111 lines (101 loc) · 3.73 KB
/
workspace.tsx
File metadata and controls
111 lines (101 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiPanel } from '@elastic/eui';
import React, { FC, useState, useMemo, useEffect, useLayoutEffect } from 'react';
import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public';
import { IExpressionLoaderParams } from '../../../../expressions/public';
import { WizardServices } from '../../types';
import { validateSchemaState } from '../utils/validate_schema_state';
import { useTypedSelector } from '../utils/state_management';
import { useVisualizationType } from '../utils/use';
import { PersistedState } from '../../../../visualizations/public';
import hand_field from '../../assets/hand_field.svg';
import fields_bg from '../../assets/fields_bg.svg';
import './workspace.scss';
import { ExperimentalInfo } from './experimental_info';
export const Workspace: FC = ({ children }) => {
const {
services: {
expressions: { ReactExpressionRenderer },
notifications: { toasts },
data,
},
} = useOpenSearchDashboards<WizardServices>();
const { toExpression, ui } = useVisualizationType();
const [expression, setExpression] = useState<string>();
const [searchContext, setSearchContext] = useState<IExpressionLoaderParams['searchContext']>({
query: data.query.queryString.getQuery(),
filters: data.query.filterManager.getFilters(),
timeRange: data.query.timefilter.timefilter.getTime(),
});
const rootState = useTypedSelector((state) => state);
// Visualizations require the uiState to persist even when the expression changes
const uiState = useMemo(() => new PersistedState(), []);
useEffect(() => {
async function loadExpression() {
const schemas = ui.containerConfig.data.schemas;
const [valid, errorMsg] = validateSchemaState(schemas, rootState);
if (!valid) {
if (errorMsg) {
toasts.addWarning(errorMsg);
}
setExpression(undefined);
return;
}
const exp = await toExpression(rootState);
setExpression(exp);
}
loadExpression();
}, [rootState, toExpression, toasts, ui.containerConfig.data.schemas]);
useLayoutEffect(() => {
const subscription = data.query.state$.subscribe(({ state }) => {
setSearchContext({
query: state.query,
timeRange: state.time,
filters: state.filters,
});
});
return () => {
subscription.unsubscribe();
};
}, [data.query.state$]);
return (
<section className="wizWorkspace">
<EuiFlexGroup className="wizCanvasControls">
<EuiFlexItem>
<ExperimentalInfo />
</EuiFlexItem>
</EuiFlexGroup>
<EuiPanel className="wizCanvas" data-test-subj="visualizationLoader">
{expression ? (
<ReactExpressionRenderer
expression={expression}
searchContext={searchContext}
uiState={uiState}
/>
) : (
<EuiFlexItem className="wizWorkspace__empty" data-test-subj="emptyWorkspace">
<EuiEmptyPrompt
title={<h2>Add a field to start</h2>}
body={
<>
<p>Drag a field to the configuration panel to generate a visualization.</p>
<span className="wizWorkspace__container">
<EuiIcon className="wizWorkspace__fieldSvg" type={fields_bg} size="original" />
<EuiIcon
className="wizWorkspace__handFieldSvg"
type={hand_field}
size="original"
/>
</span>
</>
}
/>
</EuiFlexItem>
)}
</EuiPanel>
</section>
);
};