Skip to content

Commit 2c7db46

Browse files
committed
Add possibility to listen on displayOptions changes
1 parent 783dcfe commit 2c7db46

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ module system it is exported as `GraphQLVoyager` global variable.
3737
+ `displayOptions.sortByAlphabet` [`boolean`, default `false`] - sort fields on graph by alphabet
3838
+ `displayOptions.showLeafFields` [`boolean`, default `true`] - show all scalars and enums
3939
+ `displayOptions.hideRoot` [`boolean`, default `false`] - hide the root type
40+
+ `onDisplayOptionsChange` [function: `(displayOptions) => void`] _(optional)_ - called when user change displayOptions with UI. Can be used to save settings into localstorage or query params
4041
+ `hideDocs` [`boolean`, default `false`] - hide the docs sidebar
4142
+ `hideSettings` [`boolean`, default `false`] - hide settings panel
4243
+ `workerURI` [`string`] _(optional)_ - absolute or relative path to Voyager web worker. By default it will try to load it from `voyager.worker.js`.

demo/index.tsx

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,25 @@ export default class Demo extends React.Component {
1919
introspection: defaultPreset,
2020
};
2121

22+
// not part of state because we parse it in constructor and just use in render
23+
displayOptions = {};
24+
2225
constructor(props) {
2326
super(props);
2427

25-
const { url, withCredentials } = getQueryParams();
28+
const { url, withCredentials, ...restQueryParams } = getQueryParams();
29+
// parse rest of query params we expect them to be in JSON format
30+
// we might pick also some options that are not valid displayOptions but they will be ignored
31+
// by Voyager component
32+
for (const [key, value] of Object.entries(restQueryParams)) {
33+
try {
34+
this.displayOptions[key] = JSON.parse(value);
35+
} catch (_) {
36+
console.log(
37+
`Not expected value for key "${key}" or value >${value}< is not in json format so just ignoring it`,
38+
);
39+
}
40+
}
2641
if (url) {
2742
this.state.introspection = introspectionQuery =>
2843
fetch(url, {
@@ -45,7 +60,11 @@ export default class Demo extends React.Component {
4560

4661
return (
4762
<MuiThemeProvider theme={theme}>
48-
<GraphQLVoyager introspection={introspection}>
63+
<GraphQLVoyager
64+
introspection={introspection}
65+
displayOptions={this.displayOptions}
66+
onDisplayOptionsChange={setQueryParamsWithoutRefresh}
67+
>
4968
<GraphQLVoyager.PanelHeader>
5069
<div className="voyager-panel">
5170
<Logo />
@@ -71,6 +90,19 @@ export default class Demo extends React.Component {
7190
}
7291
}
7392

93+
function setQueryParamsWithoutRefresh(displayOptions) {
94+
if ('URLSearchParams' in window) {
95+
const searchParams = new URLSearchParams(window.location.search);
96+
for (const [key, value] of Object.entries(displayOptions)) {
97+
searchParams.set(key, JSON.stringify(value));
98+
}
99+
var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
100+
history.pushState(null, '', newRelativePathQuery);
101+
} else {
102+
console.log('Missing URLSearchParams so just printing new displayOptions', displayOptions);
103+
}
104+
}
105+
74106
function getQueryParams(): { [key: string]: string } {
75107
const query = window.location.search.substring(1);
76108
const params = {};

src/components/Voyager.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ function normalizeDisplayOptions(options) {
4444
export interface VoyagerProps {
4545
introspection: IntrospectionProvider | Object;
4646
displayOptions?: VoyagerDisplayOptions;
47+
onDisplayOptionsChange?: (displayOptions: VoyagerDisplayOptions) => void;
4748
hideDocs?: boolean;
4849
hideSettings?: boolean;
4950
workerURI?: string;
@@ -64,6 +65,7 @@ export default class Voyager extends React.Component<VoyagerProps> {
6465
hideRoot: PropTypes.bool,
6566
showLeafFields: PropTypes.bool,
6667
}),
68+
onDisplayOptionsChange: PropTypes.func,
6769
hideDocs: PropTypes.bool,
6870
hideSettings: PropTypes.bool,
6971
workerURI: PropTypes.string,
@@ -232,6 +234,9 @@ export default class Voyager extends React.Component<VoyagerProps> {
232234

233235
handleDisplayOptionsChange = delta => {
234236
const displayOptions = { ...this.state.displayOptions, ...delta };
237+
if (this.props.onDisplayOptionsChange) {
238+
this.props.onDisplayOptionsChange(displayOptions);
239+
}
235240
this.updateIntrospection(this.state.introspectionData, displayOptions);
236241
};
237242

0 commit comments

Comments
 (0)