Skip to content

Commit dc45fcb

Browse files
committed
feat(playground): Show Query
1 parent 79cf42e commit dc45fcb

File tree

10 files changed

+704
-174
lines changed

10 files changed

+704
-174
lines changed

packages/cubejs-client-core/dist/cubejs-client-core.umd.js

Lines changed: 457 additions & 100 deletions
Large diffs are not rendered by default.

packages/cubejs-client-ngx/dist/cubejs-client-ngx.umd.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3950,7 +3950,7 @@
39503950

39513951
function getPromiseCtor(promiseCtor) {
39523952
if (!promiseCtor) {
3953-
promiseCtor = config.Promise || Promise;
3953+
promiseCtor = Promise;
39543954
}
39553955

39563956
if (!promiseCtor) {

packages/cubejs-playground/src/ChartContainer.jsx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,18 @@ class ChartContainer extends React.Component {
178178
<Icon type="down" />
179179
</Button>
180180
</Dropdown>
181+
<Button
182+
onClick={() => {
183+
playgroundAction('Show Query');
184+
this.setState({ showCode: showCode === 'query' ? null : 'query' });
185+
}}
186+
icon="thunderbolt"
187+
size="small"
188+
type={showCode === 'query' ? 'primary' : 'default'}
189+
disabled={!!frameworkItem.docsLink}
190+
>
191+
JSON Query
192+
</Button>
181193
<Button
182194
onClick={() => {
183195
playgroundAction('Show Code');
@@ -215,6 +227,8 @@ class ChartContainer extends React.Component {
215227
</form>
216228
);
217229

230+
const queryText = JSON.stringify(query, null, 2);
231+
218232
const renderChart = () => {
219233
if (frameworkItem && frameworkItem.docsLink) {
220234
return (
@@ -238,6 +252,8 @@ class ChartContainer extends React.Component {
238252
);
239253
} else if (showCode === 'code') {
240254
return <PrismCode code={codeExample} />;
255+
} else if (showCode === 'query') {
256+
return <PrismCode code={queryText} />;
241257
} else if (showCode === 'sql') {
242258
return (
243259
<QueryRenderer
@@ -260,13 +276,13 @@ class ChartContainer extends React.Component {
260276
});
261277
}
262278
try {
263-
await navigator.clipboard.writeText(codeExample);
279+
await navigator.clipboard.writeText(showCode === 'query' ? queryText : codeExample);
264280
notification.success({
265-
message: `Code has been copied to clipboard`
281+
message: `Copied to clipboard`
266282
});
267283
} catch (e) {
268284
notification.error({
269-
message: `Can't copy code to clipboard`,
285+
message: `Can't copy to clipboard`,
270286
description: e,
271287
});
272288
}
@@ -278,13 +294,26 @@ class ChartContainer extends React.Component {
278294
icon="copy"
279295
onClick={() => {
280296
copyCodeToClipboard();
281-
playgroundAction('Copy to Clipboard');
297+
playgroundAction('Copy Code to Clipboard');
282298
}}
283299
type="primary"
284300
>
285301
Copy Code to Clipboard
286302
</Button>
287303
);
304+
} else if (showCode === 'query') {
305+
title = (
306+
<Button
307+
icon="copy"
308+
onClick={() => {
309+
copyCodeToClipboard();
310+
playgroundAction('Copy Query to Clipboard');
311+
}}
312+
type="primary"
313+
>
314+
Copy Query to Clipboard
315+
</Button>
316+
);
288317
} else if (showCode === 'sql') {
289318
title = 'SQL';
290319
} else {

packages/cubejs-playground/src/ChartRenderer.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { useState } from 'react';
2+
import PropTypes from 'prop-types';
23
import SourceRender from 'react-source-render';
34
import presetEnv from '@babel/preset-env';
45
import presetReact from '@babel/preset-react';
@@ -68,10 +69,8 @@ ReactDOM.render(<ChartRenderer />, rootElement);
6869
`;
6970

7071
export const ChartRenderer = (props) => {
71-
let {
72+
const {
7273
query,
73-
sourceCodeFn,
74-
title,
7574
resultSet,
7675
error,
7776
sqlQuery,
@@ -80,6 +79,8 @@ export const ChartRenderer = (props) => {
8079
chartType
8180
} = props;
8281

82+
let { sourceCodeFn } = props;
83+
8384
const [chartLibrary, setChartLibrary] = useState('bizcharts');
8485

8586
sourceCodeFn = sourceCodeFn || sourceCodeTemplate;
@@ -131,3 +132,24 @@ export const ChartRenderer = (props) => {
131132
</SourceRender>
132133
);
133134
};
135+
136+
ChartRenderer.propTypes = {
137+
query: PropTypes.object.isRequired,
138+
resultSet: PropTypes.object,
139+
error: PropTypes.object,
140+
sqlQuery: PropTypes.object,
141+
dashboardSource: PropTypes.object,
142+
cubejsApi: PropTypes.object,
143+
chartType: PropTypes.string,
144+
sourceCodeFn: PropTypes.func
145+
};
146+
147+
ChartRenderer.defaultProps = {
148+
resultSet: null,
149+
error: null,
150+
sqlQuery: null,
151+
dashboardSource: null,
152+
cubejsApi: null,
153+
chartType: null,
154+
sourceCodeFn: null
155+
};

packages/cubejs-playground/src/ExplorePage.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import React, { Component } from 'react';
33
import cubejs from '@cubejs-client/core';
44
import { fetch } from 'whatwg-fetch';
5+
import PropTypes from 'prop-types';
56
import DashboardSource from './DashboardSource';
67
import PlaygroundQueryBuilder from './PlaygroundQueryBuilder';
78

@@ -33,9 +34,13 @@ class ExplorePage extends Component {
3334

3435
render() {
3536
const { cubejsToken, apiUrl } = this.state;
37+
const { location, history } = this.props;
38+
const params = new URLSearchParams(location.search);
39+
const query = params.get('query') && JSON.parse(params.get('query')) || {};
3640
return this.cubejsApi() && (
3741
<PlaygroundQueryBuilder
38-
query={{}}
42+
query={query}
43+
setQuery={(q) => history.push(`/explore?query=${JSON.stringify((q))}`)}
3944
cubejsApi={this.cubejsApi()}
4045
apiUrl={apiUrl}
4146
cubejsToken={cubejsToken}
@@ -45,4 +50,12 @@ class ExplorePage extends Component {
4550
}
4651
}
4752

53+
ExplorePage.propTypes = {
54+
location: PropTypes.object.isRequired,
55+
history: PropTypes.object.isRequired
56+
};
57+
58+
ExplorePage.defaultProps = {
59+
};
60+
4861
export default ExplorePage;

packages/cubejs-playground/src/PlaygroundQueryBuilder.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,11 @@ ChartType.propTypes = {
373373
};
374374

375375
const PlaygroundQueryBuilder = ({
376-
query, cubejsApi, apiUrl, cubejsToken, dashboardSource
376+
query, cubejsApi, apiUrl, cubejsToken, dashboardSource, setQuery
377377
}) => (
378378
<QueryBuilder
379379
query={query}
380+
setQuery={setQuery}
380381
cubejsApi={cubejsApi}
381382
render={({
382383
resultSet, error, validatedQuery, isQueryPresent, chartType, updateChartType,
@@ -397,21 +398,21 @@ const PlaygroundQueryBuilder = ({
397398
addMemberName="Measure"
398399
updateMethods={updateMeasures}
399400
/>
400-
<Divider type="vertical" />
401+
<Divider type="vertical"/>
401402
<MemberGroup
402403
members={dimensions}
403404
availableMembers={availableDimensions}
404405
addMemberName="Dimension"
405406
updateMethods={updateDimensions}
406407
/>
407-
<Divider type="vertical" />
408+
<Divider type="vertical"/>
408409
<MemberGroup
409410
members={segments}
410411
availableMembers={availableSegments}
411412
addMemberName="Segment"
412413
updateMethods={updateSegments}
413414
/>
414-
<Divider type="vertical" />
415+
<Divider type="vertical"/>
415416
<TimeGroup
416417
members={timeDimensions}
417418
availableMembers={availableTimeDimensions}
@@ -432,7 +433,7 @@ const PlaygroundQueryBuilder = ({
432433
</Row>
433434
<Row type="flex" justify="space-around" align="top" gutter={24}>
434435
<Col span={24}>
435-
<ChartType chartType={chartType} updateChartType={updateChartType} />
436+
<ChartType chartType={chartType} updateChartType={updateChartType}/>
436437
</Col>
437438
</Row>
438439
</Card>
@@ -460,6 +461,7 @@ const PlaygroundQueryBuilder = ({
460461

461462
PlaygroundQueryBuilder.propTypes = {
462463
query: PropTypes.object,
464+
setQuery: PropTypes.func,
463465
cubejsApi: PropTypes.object,
464466
dashboardSource: PropTypes.object,
465467
apiUrl: PropTypes.string,
@@ -468,6 +470,7 @@ PlaygroundQueryBuilder.propTypes = {
468470

469471
PlaygroundQueryBuilder.defaultProps = {
470472
query: {},
473+
setQuery: null,
471474
cubejsApi: null,
472475
dashboardSource: null,
473476
apiUrl: '/cubejs-api/v1',

packages/cubejs-react/dist/cubejs-react.esm.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,18 @@ function (_React$Component) {
291291
return _componentDidMount.apply(this, arguments);
292292
};
293293
}()
294+
}, {
295+
key: "componentDidUpdate",
296+
value: function componentDidUpdate(prevProps) {
297+
var query = this.props.query;
298+
299+
if (!equals(prevProps.query, query)) {
300+
// eslint-disable-next-line react/no-did-update-set-state
301+
this.setState({
302+
query: query
303+
});
304+
}
305+
}
294306
}, {
295307
key: "isQueryPresent",
296308
value: function isQueryPresent() {
@@ -328,25 +340,19 @@ function (_React$Component) {
328340
add: function add(member) {
329341
var query = _this2.state.query;
330342

331-
_this2.setState(_this2.applyStateChangeHeuristics({
332-
query: _objectSpread({}, query, _defineProperty({}, memberType, (query[memberType] || []).concat(toQuery(member))))
333-
}));
343+
_this2.updateQuery(_defineProperty({}, memberType, (query[memberType] || []).concat(toQuery(member))));
334344
},
335345
remove: function remove(member) {
336346
var query = _this2.state.query;
337347
var members = (query[memberType] || []).concat([]);
338348
members.splice(member.index, 1);
339-
return _this2.setState(_this2.applyStateChangeHeuristics({
340-
query: _objectSpread({}, query, _defineProperty({}, memberType, members))
341-
}));
349+
return _this2.updateQuery(_defineProperty({}, memberType, members));
342350
},
343351
update: function update(member, updateWith) {
344352
var query = _this2.state.query;
345353
var members = (query[memberType] || []).concat([]);
346354
members.splice(member.index, 1, toQuery(updateWith));
347-
return _this2.setState(_this2.applyStateChangeHeuristics({
348-
query: _objectSpread({}, query, _defineProperty({}, memberType, members))
349-
}));
355+
return _this2.updateQuery(_defineProperty({}, memberType, members));
350356
}
351357
};
352358
};
@@ -422,12 +428,32 @@ function (_React$Component) {
422428
updateTimeDimensions: updateMethods('timeDimensions', toTimeDimension),
423429
updateFilters: updateMethods('filters', toFilter),
424430
updateChartType: function updateChartType(newChartType) {
425-
return _this2.setState(_this2.applyStateChangeHeuristics({
431+
return _this2.updateVizState({
426432
chartType: newChartType
427-
}));
433+
});
428434
}
429435
}, queryRendererProps);
430436
}
437+
}, {
438+
key: "updateQuery",
439+
value: function updateQuery(queryUpdate) {
440+
var query = this.state.query;
441+
this.updateVizState({
442+
query: _objectSpread({}, query, queryUpdate)
443+
});
444+
}
445+
}, {
446+
key: "updateVizState",
447+
value: function updateVizState(state) {
448+
var setQuery = this.props.setQuery;
449+
var finalState = this.applyStateChangeHeuristics(state);
450+
this.setState(finalState);
451+
finalState = _objectSpread({}, this.state, finalState);
452+
453+
if (setQuery) {
454+
setQuery(finalState.query);
455+
}
456+
}
431457
}, {
432458
key: "validatedQuery",
433459
value: function validatedQuery() {
@@ -585,12 +611,14 @@ function (_React$Component) {
585611
QueryBuilder.propTypes = {
586612
render: func,
587613
stateChangeHeuristics: func,
614+
setQuery: func,
588615
cubejsApi: object.isRequired,
589616
disableHeuristics: bool,
590617
query: object
591618
};
592619
QueryBuilder.defaultProps = {
593620
query: {},
621+
setQuery: null,
594622
stateChangeHeuristics: null,
595623
disableHeuristics: false,
596624
render: null

0 commit comments

Comments
 (0)