Skip to content

Commit 70a535d

Browse files
feat: structure for DE work (#4562)
Co-authored-by: Chunchun <yccvivo@gmail.com>
1 parent e2fa08c commit 70a535d

File tree

7 files changed

+347
-7
lines changed

7 files changed

+347
-7
lines changed

src/dataExplorer/components/DataExplorerPage.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {Switch, Route, Link} from 'react-router-dom'
44

55
// Components
66
import DataExplorer from 'src/dataExplorer/components/DataExplorer'
7+
import NewDataExplorer from 'src/dataExplorer/components/NewDataExplorer'
78
import {
89
Page,
910
Icon,
@@ -118,11 +119,10 @@ const DataExplorerPage: FC = () => {
118119
</Page.ControlBarRight>
119120
</Page.ControlBar>
120121
)}
121-
{!newDataExplorer && (
122-
<Page.Contents fullWidth={true} scrollable={false}>
123-
<DataExplorer />
124-
</Page.Contents>
125-
)}
122+
<Page.Contents fullWidth={true} scrollable={false}>
123+
{!newDataExplorer && <DataExplorer />}
124+
{newDataExplorer && <NewDataExplorer />}
125+
</Page.Contents>
126126
</GetResources>
127127
</Page>
128128
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.new-data-explorer-rightside {
2+
.cf-draggable-resizer--handle > .cf-draggable-resizer--handle-pill1,
3+
.cf-draggable-resizer--handle > .cf-draggable-resizer--handle-pill2,
4+
.cf-draggable-resizer--handle > .cf-draggable-resizer--gradient1,
5+
.cf-draggable-resizer--handle > .cf-draggable-resizer--gradient2 {
6+
width: 32px;
7+
height: 2px;
8+
}
9+
10+
.cf-draggable-resizer--handle-dragging > .cf-draggable-resizer--gradient1,
11+
.cf-draggable-resizer--handle-dragging > .cf-draggable-resizer--gradient2 {
12+
min-height: auto;
13+
width: calc(25% - 60px);
14+
}
15+
16+
h1 {
17+
text-align: center;
18+
}
19+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import React, {FC, lazy, Suspense, useState, useContext} from 'react'
2+
import {
3+
DraggableResizer,
4+
Orientation,
5+
RemoteDataState,
6+
SpinnerContainer,
7+
TechnoSpinner,
8+
Button,
9+
IconFont,
10+
ComponentStatus,
11+
ComponentSize,
12+
FlexBox,
13+
FlexDirection,
14+
JustifyContent,
15+
} from '@influxdata/clockface'
16+
import TimeRangeDropdown from 'src/shared/components/TimeRangeDropdown'
17+
import Results from 'src/dataExplorer/components/Results'
18+
import {TimeRange} from 'src/types'
19+
import {SubmitQueryButton} from 'src/timeMachine/components/SubmitQueryButton'
20+
import {downloadTextFile} from 'src/shared/utils/download'
21+
import {event} from 'src/cloud/utils/reporting'
22+
import {QueryContext} from 'src/shared/contexts/query'
23+
import {notify} from 'src/shared/actions/notifications'
24+
25+
import {DEFAULT_TIME_RANGE} from 'src/shared/constants/timeRanges'
26+
import './NewDataExplorer.scss'
27+
28+
const FluxMonacoEditor = lazy(() =>
29+
import('src/shared/components/FluxMonacoEditor')
30+
)
31+
32+
const INITIAL_VERT_RESIZER_HANDLE = 0.2
33+
const INITIAL_HORIZ_RESIZER_HANDLE = 0.2
34+
const fakeNotify = notify
35+
36+
const NewDataExplorer: FC = () => {
37+
const [vertDragPosition, setVertDragPosition] = useState([
38+
INITIAL_VERT_RESIZER_HANDLE,
39+
])
40+
const [horizDragPosition, setHorizDragPosition] = useState([
41+
INITIAL_HORIZ_RESIZER_HANDLE,
42+
])
43+
const {basic} = useContext(QueryContext)
44+
45+
const [text, setText] = useState('')
46+
const [timeRange, setTimeRange] = useState<TimeRange>(DEFAULT_TIME_RANGE)
47+
48+
const download = () => {
49+
event('CSV Download Initiated')
50+
basic(text).promise.then(response => {
51+
if (response.type !== 'SUCCESS') {
52+
return
53+
}
54+
55+
downloadTextFile(response.csv, 'influx.data', '.csv', 'text/csv')
56+
})
57+
}
58+
59+
const submit = () => {}
60+
61+
return (
62+
<DraggableResizer
63+
handleOrientation={Orientation.Vertical}
64+
handlePositions={vertDragPosition}
65+
onChangePositions={setVertDragPosition}
66+
>
67+
<DraggableResizer.Panel>
68+
<h1>[ schema ]</h1>
69+
</DraggableResizer.Panel>
70+
<DraggableResizer.Panel className="new-data-explorer-rightside">
71+
<DraggableResizer
72+
handleOrientation={Orientation.Horizontal}
73+
handlePositions={horizDragPosition}
74+
onChangePositions={setHorizDragPosition}
75+
>
76+
<DraggableResizer.Panel>
77+
<FlexBox
78+
direction={FlexDirection.Column}
79+
justifyContent={JustifyContent.FlexEnd}
80+
margin={ComponentSize.Small}
81+
style={{height: '100%'}}
82+
>
83+
<div
84+
style={{height: '100%', width: '100%', position: 'relative'}}
85+
>
86+
<Suspense
87+
fallback={
88+
<SpinnerContainer
89+
loading={RemoteDataState.Loading}
90+
spinnerComponent={<TechnoSpinner />}
91+
/>
92+
}
93+
>
94+
<FluxMonacoEditor script={text} onChangeScript={setText} />
95+
</Suspense>
96+
</div>
97+
<div style={{width: '100%'}}>
98+
<FlexBox
99+
direction={FlexDirection.Row}
100+
justifyContent={JustifyContent.FlexEnd}
101+
margin={ComponentSize.Small}
102+
>
103+
<Button
104+
titleText="Download query results as a .CSV file"
105+
text="CSV"
106+
icon={IconFont.Download_New}
107+
onClick={download}
108+
status={
109+
text ? ComponentStatus.Default : ComponentStatus.Disabled
110+
}
111+
/>
112+
<TimeRangeDropdown
113+
timeRange={timeRange}
114+
onSetTimeRange={(range: TimeRange) => setTimeRange(range)}
115+
/>
116+
<SubmitQueryButton
117+
className="submit-btn"
118+
text="Run"
119+
icon={IconFont.Play}
120+
submitButtonDisabled={!text}
121+
queryStatus={RemoteDataState.NotStarted}
122+
onSubmit={submit}
123+
onNotify={fakeNotify}
124+
queryID=""
125+
cancelAllRunningQueries={() => {}}
126+
/>
127+
</FlexBox>
128+
</div>
129+
</FlexBox>
130+
</DraggableResizer.Panel>
131+
<DraggableResizer.Panel>
132+
<Results />
133+
</DraggableResizer.Panel>
134+
</DraggableResizer>
135+
</DraggableResizer.Panel>
136+
</DraggableResizer>
137+
)
138+
}
139+
140+
export default NewDataExplorer
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
@import '@influxdata/clockface/dist/variables.scss';
2+
3+
$cf-radius-lg: $cf-radius + 4px;
4+
5+
.data-explorer-results {
6+
height: 100%;
7+
border-radius: $cf-radius-lg;
8+
border: 2px solid transparent;
9+
background-color: $cf-grey-15;
10+
padding: $cf-space-2xs;
11+
}
12+
13+
.data-explorer-results--timezone {
14+
flex-grow: 1;
15+
flex-direction: row-reverse;
16+
display: flex;
17+
}
18+
19+
.data-explorer-results--header {
20+
width: 100%;
21+
}
22+
23+
.data-explorer-results--empty {
24+
height: 100%;
25+
display: flex;
26+
}
27+
28+
.data-explorer-results--empty-header {
29+
align-self: center;
30+
text-align: center;
31+
color: $cf-grey-55;
32+
33+
h3 {
34+
margin: 0;
35+
}
36+
37+
p {
38+
margin: 0;
39+
}
40+
}
41+
42+
.query-stat {
43+
padding: $cf-space-2xs 0;
44+
}
45+
46+
.query-stat--bold {
47+
font-weight: $cf-font-weight--medium;
48+
color: $cf-grey-75;
49+
padding-left: $cf-space-2xs;
50+
padding-right: $cf-space-s;
51+
}
52+
53+
.query-stat--normal {
54+
color: $cf-grey-55;
55+
padding: 0 $cf-space-2xs;
56+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import React, {FC, useState} from 'react'
2+
import {FlexBox, FlexDirection, ComponentStatus} from '@influxdata/clockface'
3+
4+
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
5+
import TimeZoneDropdown from 'src/shared/components/TimeZoneDropdown'
6+
7+
import './Results.scss'
8+
9+
// simplified version migrated from src/flows/pipes/Table/view.tsx
10+
const QueryStat: FC = () => {
11+
const results: Record<string, any> = {}
12+
const processTime = 0
13+
14+
const tableColumn = results?.parsed?.table?.getColumn('table') || []
15+
const lastTableValue = tableColumn[tableColumn.length - 1] || -1
16+
17+
let tableNum = 0
18+
19+
if (typeof lastTableValue === 'string') {
20+
tableNum = parseInt(lastTableValue) + 1
21+
} else if (typeof lastTableValue === 'boolean') {
22+
tableNum = lastTableValue ? 1 : 0
23+
} else {
24+
// number
25+
tableNum = lastTableValue + 1
26+
}
27+
28+
return (
29+
<div className="query-stat">
30+
<span className="query-stat--bold">{`${tableNum} tables`}</span>
31+
<span className="query-stat--bold">{`${results?.parsed?.table?.length ||
32+
0} rows`}</span>
33+
<span className="query-stat--normal">{`${processTime} ms`}</span>
34+
</div>
35+
)
36+
}
37+
38+
const EmptyResults: FC = () => {
39+
return (
40+
<div className="data-explorer-results--empty">
41+
<div className="data-explorer-results--empty-header">
42+
<h3>Query Results</h3>
43+
<p>Select data and run query to view results</p>
44+
</div>
45+
</div>
46+
)
47+
}
48+
49+
const Results: FC = () => {
50+
const [search, setSearch] = useState('')
51+
52+
return (
53+
<div className="data-explorer-results">
54+
<FlexBox direction={FlexDirection.Column} style={{height: '100%'}}>
55+
<div className="data-explorer-results--header">
56+
<FlexBox>
57+
<div style={{width: '300px'}}>
58+
<SearchWidget
59+
placeholderText="Search results..."
60+
onSearch={setSearch}
61+
searchTerm={search}
62+
status={ComponentStatus.Disabled}
63+
/>
64+
</div>
65+
<QueryStat />
66+
<div className="data-explorer-results--timezone">
67+
<TimeZoneDropdown />
68+
</div>
69+
</FlexBox>
70+
</div>
71+
<EmptyResults />
72+
</FlexBox>
73+
</div>
74+
)
75+
}
76+
77+
export default Results
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, {FC, createContext, useState} from 'react'
2+
3+
// types
4+
import {RemoteDataState} from 'src/types'
5+
6+
interface NewDataExplorerContextType {
7+
query: string
8+
loading: RemoteDataState
9+
10+
updateQuery: (q: string) => void
11+
}
12+
13+
const DEFAULT_CONTEXT: NewDataExplorerContextType = {
14+
query: '',
15+
loading: RemoteDataState.NotStarted,
16+
17+
updateQuery: _q => {},
18+
}
19+
20+
export const NewDataExplorerContext = createContext<NewDataExplorerContextType>(
21+
DEFAULT_CONTEXT
22+
)
23+
24+
export const NewDataExplorerProvider: FC = ({children}) => {
25+
const [loading] = useState(RemoteDataState.NotStarted)
26+
const [query, setQuery] = useState('')
27+
28+
return (
29+
<NewDataExplorerContext.Provider
30+
value={{
31+
loading,
32+
query,
33+
updateQuery: setQuery,
34+
}}
35+
>
36+
{children}
37+
</NewDataExplorerContext.Provider>
38+
)
39+
}

0 commit comments

Comments
 (0)