Skip to content

Commit 70838e0

Browse files
committed
temp
1 parent b1420c2 commit 70838e0

File tree

7 files changed

+266
-100
lines changed

7 files changed

+266
-100
lines changed

js/packages/quary-extension-ui/src/App.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { ErrorView } from '@ui/views/ErrorView'
1616
import { ExecuteSQLView } from '@ui/views/ExecuteSQL'
1717
import { ImportSourcesView } from '@ui/views/ImportSourcesView'
1818
import { ChartEditorView } from '@ui/views/ChartEditorView'
19+
import { DashboardEditorView } from '@ui/views/DashboardEditorView'
1920

2021
function App() {
2122
const [view] = useGlobalState()
@@ -111,9 +112,7 @@ function App() {
111112
return <ChartEditorView data={view.data} />
112113
}
113114
case 'dashboardEditor': {
114-
return (
115-
<div>Dashboard editor {JSON.stringify(view.data.dashboardFile)} </div>
116-
)
115+
return <DashboardEditorView response={view.data.dashboardFile} />
117116
}
118117
default:
119118
return <div>Invalid view type {JSON.stringify(view)}</div>

js/packages/quary-extension-ui/src/components/Dashboard/Dashboard.tsx

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,42 @@
1-
import { Layout, Responsive, WidthProvider } from 'react-grid-layout'
1+
import { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout'
22
import _ from 'lodash'
33
import { EventHandler, Component, SyntheticEvent } from 'react'
4+
import './react-grid-layout.css'
5+
import { DashboardItem } from '@quary/proto/quary/service/v1/dashboard_file'
46

57
interface Props {
68
className: string
79
cols: Record<string, number>
8-
onLayoutChange: Function
10+
onLayoutChange: (currentLayout: Layout[], allLayouts: Layouts) => void
911
rowHeight: number
12+
dashboardItems: ItemWithInfo[]
13+
}
14+
15+
export type ItemWithInfo = {
16+
item: DashboardItem
17+
sql: string
1018
}
1119

1220
interface State {
21+
// TODO Need to constrain this string
1322
currentBreakpoint: string
1423
compactType: CompactType
1524
mounted: boolean
1625
resizeHandles: string[]
17-
layouts: Record<string, Layout>
26+
layouts: Layouts
1827
}
1928

2029
export type CompactType = 'horizontal' | 'vertical'
2130

2231
const availableHandles = ['s', 'w', 'e', 'n', 'sw', 'nw', 'se', 'ne']
2332

24-
const ResponsiveReactGridLayout = WidthProvider(Responsive)
25-
2633
export default class Dashboard extends Component<Props, State> {
2734
static defaultProps: Props = {
2835
className: 'layout',
2936
rowHeight: 30,
3037
onLayoutChange() {},
3138
cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
39+
dashboardItems: [],
3240
}
3341

3442
state: State = {
@@ -44,25 +52,17 @@ export default class Dashboard extends Component<Props, State> {
4452
}
4553

4654
generateDOM(): React.ReactNodeArray {
47-
return _.map(this.state.layouts.lg, function (l, i) {
55+
return this.state.layouts.lg.map((l, i) => {
4856
return (
49-
<div key={i} className={l.static ? 'static' : ''}>
50-
{l.static ? (
51-
<span
52-
className="text"
53-
title="This item is static and cannot be removed or resized."
54-
>
55-
Static - {i}
56-
</span>
57-
) : (
58-
<span className="text">{i}</span>
59-
)}
57+
<div key={i}>
58+
<span className="text">{i}</span>
59+
<span className="text">{l.sql}</span>
6060
</div>
6161
)
6262
})
6363
}
6464

65-
onBreakpointChange: (Breakpoint) => void = (breakpoint) => {
65+
onBreakpointChange: (breakpoint: string) => void = (breakpoint) => {
6666
this.setState({
6767
currentBreakpoint: breakpoint,
6868
})
@@ -74,7 +74,7 @@ export default class Dashboard extends Component<Props, State> {
7474
oldCompactType === 'horizontal'
7575
? 'vertical'
7676
: oldCompactType === 'vertical'
77-
? null
77+
? 'vertical'
7878
: 'horizontal'
7979
this.setState({ compactType })
8080
}
@@ -88,13 +88,14 @@ export default class Dashboard extends Component<Props, State> {
8888
})
8989
}
9090

91-
onLayoutChange = (layout, layouts) => {
92-
this.props.onLayoutChange(layout, layouts)
91+
onLayoutChange = (currentLayout: Layout[], allLayouts: Layouts) => {
92+
this.props.onLayoutChange(currentLayout, allLayouts)
9393
}
9494

9595
onNewLayout: EventHandler<SyntheticEvent> = () => {
96+
const layout = generateLayoutFromDashboardItems(this.props.dashboardItems)
9697
this.setState({
97-
layouts: { lg: generateLayout(this.state.resizeHandles) },
98+
layouts: { lg: layout },
9899
})
99100
}
100101

@@ -137,24 +138,58 @@ export default class Dashboard extends Component<Props, State> {
137138
useCSSTransforms={this.state.mounted}
138139
compactType={this.state.compactType}
139140
preventCollision={!this.state.compactType}
141+
/* eslint-disable-next-line react/no-children-prop */
140142
children={this.generateDOM()}
141143
/>
142144
</div>
143145
)
144146
}
145147
}
146148

147-
function generateLayout(resizeHandles) {
148-
return _.map(_.range(0, 25), function (item, i) {
149+
const ResponsiveReactGridLayout = WidthProvider(Responsive)
150+
151+
function generateLayout(resizeHandles: string[]): Array<{
152+
x: number
153+
y: number
154+
w: number
155+
h: number
156+
i: string
157+
resizeHandles: string[]
158+
}> {
159+
return _.map(_.range(0, 25), function (_, i) {
149160
const y = Math.ceil(Math.random() * 4) + 1
150161
return {
151162
x: Math.round(Math.random() * 5) * 2,
152163
y: Math.floor(i / 6) * y,
153164
w: 2,
154165
h: y,
155166
i: i.toString(),
156-
static: Math.random() < 0.05,
157167
resizeHandles,
158168
}
159169
})
160170
}
171+
172+
function generateLayoutFromDashboardItems(
173+
dashboardItems: ItemWithInfo[],
174+
): Array<{
175+
x: number
176+
y: number
177+
w: number
178+
h: number
179+
i: string
180+
resizeHandles: string[]
181+
sql: string
182+
}> {
183+
console.log(dashboardItems)
184+
return dashboardItems.map(({ item, sql }, i) => {
185+
return {
186+
x: item.topLeftX,
187+
y: item.topLeftY,
188+
w: item.width,
189+
h: item.height,
190+
i: i.toString(),
191+
resizeHandles: ['se'],
192+
sql,
193+
}
194+
})
195+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
.react-grid-layout {
2+
position: relative;
3+
transition: height 200ms ease;
4+
}
5+
.react-grid-item {
6+
transition: all 200ms ease;
7+
transition-property: left, top, width, height;
8+
}
9+
.react-grid-item img {
10+
pointer-events: none;
11+
user-select: none;
12+
}
13+
.react-grid-item.cssTransforms {
14+
transition-property: transform, width, height;
15+
}
16+
.react-grid-item.resizing {
17+
transition: none;
18+
z-index: 1;
19+
will-change: width, height;
20+
}
21+
22+
.react-grid-item.react-draggable-dragging {
23+
transition: none;
24+
z-index: 3;
25+
will-change: transform;
26+
}
27+
28+
.react-grid-item.dropping {
29+
visibility: hidden;
30+
}
31+
32+
.react-grid-item.react-grid-placeholder {
33+
background: red;
34+
opacity: 0.2;
35+
transition-duration: 100ms;
36+
z-index: 2;
37+
-webkit-user-select: none;
38+
-moz-user-select: none;
39+
-ms-user-select: none;
40+
-o-user-select: none;
41+
user-select: none;
42+
}
43+
44+
.react-grid-item.react-grid-placeholder.placeholder-resizing {
45+
transition: none;
46+
}
47+
48+
.react-grid-item > .react-resizable-handle {
49+
position: absolute;
50+
width: 20px;
51+
height: 20px;
52+
}
53+
54+
.react-grid-item > .react-resizable-handle::after {
55+
content: "";
56+
position: absolute;
57+
right: 3px;
58+
bottom: 3px;
59+
width: 5px;
60+
height: 5px;
61+
border-right: 2px solid rgba(0, 0, 0, 0.4);
62+
border-bottom: 2px solid rgba(0, 0, 0, 0.4);
63+
}
64+
65+
.react-resizable-hide > .react-resizable-handle {
66+
display: none;
67+
}
68+
69+
.react-grid-item > .react-resizable-handle.react-resizable-handle-sw {
70+
bottom: 0;
71+
left: 0;
72+
cursor: sw-resize;
73+
transform: rotate(90deg);
74+
}
75+
.react-grid-item > .react-resizable-handle.react-resizable-handle-se {
76+
bottom: 0;
77+
right: 0;
78+
cursor: se-resize;
79+
}
80+
.react-grid-item > .react-resizable-handle.react-resizable-handle-nw {
81+
top: 0;
82+
left: 0;
83+
cursor: nw-resize;
84+
transform: rotate(180deg);
85+
}
86+
.react-grid-item > .react-resizable-handle.react-resizable-handle-ne {
87+
top: 0;
88+
right: 0;
89+
cursor: ne-resize;
90+
transform: rotate(270deg);
91+
}
92+
.react-grid-item > .react-resizable-handle.react-resizable-handle-w,
93+
.react-grid-item > .react-resizable-handle.react-resizable-handle-e {
94+
top: 50%;
95+
margin-top: -10px;
96+
cursor: ew-resize;
97+
}
98+
.react-grid-item > .react-resizable-handle.react-resizable-handle-w {
99+
left: 0;
100+
transform: rotate(135deg);
101+
}
102+
.react-grid-item > .react-resizable-handle.react-resizable-handle-e {
103+
right: 0;
104+
transform: rotate(315deg);
105+
}
106+
.react-grid-item > .react-resizable-handle.react-resizable-handle-n,
107+
.react-grid-item > .react-resizable-handle.react-resizable-handle-s {
108+
left: 50%;
109+
margin-left: -10px;
110+
cursor: ns-resize;
111+
}
112+
.react-grid-item > .react-resizable-handle.react-resizable-handle-n {
113+
top: 0;
114+
transform: rotate(225deg);
115+
}
116+
.react-grid-item > .react-resizable-handle.react-resizable-handle-s {
117+
bottom: 0;
118+
transform: rotate(45deg);
119+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ReturnDashboardWithSqlResponse } from '@quary/proto/quary/service/v1/wasm_rust_rpc_calls'
2+
import Dashboard from '@ui/components/Dashboard/Dashboard'
3+
4+
interface Props {
5+
response: ReturnDashboardWithSqlResponse
6+
}
7+
8+
export const DashboardEditorView: React.FC<Props> = ({ response }) => (
9+
<div>
10+
<div>{JSON.stringify(response)}</div>
11+
<Dashboard dashboardItems={response.dashboard?.items} />
12+
</div>
13+
)

js/packages/quary-extension/src/web/autoCompleteProvider.ts

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import * as vscode from 'vscode'
2-
import { isErr, Ok } from '@shared/result'
32
import { DefinitionProvider, Uri } from 'vscode'
4-
import { ListAssetsResponse_Asset_AssetType } from '@quary/proto/quary/service/v1/wasm_rust_rpc_calls'
3+
import { isErr, Ok } from '@shared/result'
4+
import {
5+
ListAssetsRequest_AssetsToSkip,
6+
ListAssetsResponse_Asset_AssetType,
7+
} from '@quary/proto/quary/service/v1/wasm_rust_rpc_calls'
58
import { getServices, preInitSetup } from './services'
69

710
// SQL Autocomplete Provider
@@ -27,9 +30,7 @@ export const sqlAutocompleteProvider = (
2730
}
2831
const assets = await services.rust.list_assets({
2932
projectRoot: details.value.projectRoot,
30-
assetsToSkip: {
31-
charts: true,
32-
},
33+
assetsToSkip: ListAssetsRequest_AssetsToSkip.ASSETS_TO_SKIP_CHARTS_AND_DASHBOARDS,
3334
})
3435
if (isErr(assets)) {
3536
return assets
@@ -106,32 +107,28 @@ export const sqlDefinitionProvider = (
106107
return []
107108
}
108109

109-
const locations = entries.value.definitions.map((location) => {
110+
return entries.value.definitions.map((location) => {
110111
const start = new vscode.Position(
111-
location.range!.start!.line,
112-
location.range!.start!.character,
112+
location.range!.start!.line,
113+
location.range!.start!.character,
113114
)
114115
const end = new vscode.Position(
115-
location.range!.end!.line,
116-
location.range!.end!.character,
116+
location.range!.end!.line,
117+
location.range!.end!.character,
117118
)
118119
const range = new vscode.Range(start, end)
119-
120120
const targetUri = Uri.joinPath(
121-
entries.value.projectRoot,
122-
location.targetFile,
121+
entries.value.projectRoot,
122+
location.targetFile,
123123
)
124-
125124
return {
126125
originSelectionRange: range,
127126
targetUri,
128127
targetRange: new vscode.Range(
129-
new vscode.Position(0, 0),
130-
new vscode.Position(0, 0),
128+
new vscode.Position(0, 0),
129+
new vscode.Position(0, 0),
131130
),
132131
}
133132
})
134-
135-
return locations
136133
},
137134
})

0 commit comments

Comments
 (0)