Skip to content

Commit 7e6ea6f

Browse files
committed
Add More Info toggle
1 parent b8a4719 commit 7e6ea6f

9 files changed

Lines changed: 100 additions & 25 deletions

File tree

resources/dist.zip

14.2 KB
Binary file not shown.

src/lib/RequestStore.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { JSONType, RouterMap, LeafMap, Endpoint } from "../utils/types";
2-
import { parameterise, insertLeafMap, upsert } from "./store-helpers";
2+
import { parameterise, insertLeafMap, upsert, persistOptions } from "./store-helpers";
33
import { omit, unset } from "lodash";
44
import leafMapToEndpoints from "./leafmap-to-endpoints";
55
import stringify from "json-stable-stringify";
66

7+
export type Options = {
8+
// Includes additional data such as response samples
9+
enableMoreInfo: boolean;
10+
}
11+
712
/**
813
* RequestStore handles routing to endpoints
914
* Optimised for fast lookups & insertion via a Radix Tree
@@ -12,11 +17,20 @@ export default class RequestStore {
1217
private store: RouterMap;
1318
private leafMap: LeafMap;
1419
private disabledHosts: Set<string>;
20+
private storeOptions: Options;
1521

1622
constructor() {
1723
this.leafMap = {}; // persist.get() || {};
1824
this.store = {}; // leafMapToRouterMap(this.leafMap);
1925
this.disabledHosts = new Set();
26+
this.storeOptions = persistOptions.get();
27+
}
28+
29+
public options = (options?: Partial<Options>): Readonly<Options> => {
30+
if (!options) return this.storeOptions;
31+
this.storeOptions = { ...this.storeOptions, ...options };
32+
persistOptions.set(this.storeOptions);
33+
return this.storeOptions;
2034
}
2135

2236
public import(json: string): boolean {

src/lib/store-helpers/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
export { default as createLeaf } from "./create-leaf";
22
export { default as parameterise } from "./parameterise";
3-
export { default as persist } from "./persist";
43
export { default as leafMapToRouterMap } from "./leafmap-to-routermap";
54
export { default as upsert } from "./upsert";
65
export { default as findPathnamesInRouter } from "./find-pathnames-in-router";
76
export { default as pruneRouter } from "./prune-router";
7+
export { default as persistOptions } from "./persist-options";
88
export * from "./merge";
99
export * from "./helpers";
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import store2 from "store2";
2+
import type { Options } from "../RequestStore";
3+
4+
const namespace = "openapi-devtools-options";
5+
const key = "options";
6+
const store = store2.namespace(namespace);
7+
8+
export const defaultOptions: Readonly<Options> = {
9+
enableMoreInfo: false,
10+
};
11+
12+
const get = (): Options => {
13+
const options = store.get(key);
14+
if (options) return options;
15+
store.set(key, defaultOptions);
16+
return defaultOptions;
17+
};
18+
const set = (value: Partial<Options>) => {
19+
const options = get();
20+
const newOptions = { ...options, ...value };
21+
store.set(key, newOptions);
22+
};
23+
const clear = () => store.clear();
24+
25+
export default {
26+
get,
27+
set,
28+
clear,
29+
};
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import store from "store2";
1+
import store2 from "store2";
22

33
const namespace = "openapi-devtools";
44

5+
const store = store2.namespace(namespace);
6+
57
const get = () => store.get(namespace);
68
const set = (value: unknown) => store.set(namespace, value);
79
const clear = () => store.clear();

src/ui/ControlConfig.tsx

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
1-
import { useContext } from "react";
2-
import { Button, Tooltip, HStack, useToast } from "@chakra-ui/react";
3-
import copy from 'copy-to-clipboard';
4-
import Context from './context';
5-
import ControlConfigImport from './ControlConfigImport';
1+
import { useState, useContext } from "react";
2+
import { Tooltip, HStack, FormControl, FormLabel } from "@chakra-ui/react";
3+
import { Switch } from "@chakra-ui/react";
4+
import ControlConfigImport from "./ControlConfigImportExport";
5+
import Context from "./context";
6+
7+
const TOGGLEMOREID = "toggle-more-info";
68

79
const ControlConfig = () => {
810
const ctx = useContext(Context);
9-
const toast = useToast();
10-
const onExport = () => {
11-
const stateStr = ctx.export();
12-
copy(stateStr);
13-
toast({
14-
title: "Copied to clipboard.",
15-
status: "success",
16-
duration: 2000,
17-
isClosable: true,
18-
});
11+
const [moreInfoEnabled, setMoreInfoEnabled] = useState(
12+
ctx.options().enableMoreInfo
13+
);
14+
const onToggleMoreInfo = () => {
15+
const enableMoreInfo = !ctx.options().enableMoreInfo;
16+
ctx.options({ enableMoreInfo });
17+
setMoreInfoEnabled(enableMoreInfo);
1918
};
2019
return (
21-
<HStack>
22-
<ControlConfigImport />
23-
<Tooltip label="Export will copy a state string to your clipboard. Save this somewhere on your computer. You can load it by clicking import and pasting the string.">
24-
<Button size="md" onClick={onExport} colorScheme="teal">
25-
Export
26-
</Button>
27-
</Tooltip>
20+
<HStack justifyContent="space-between">
21+
<FormControl display="flex" alignItems="center">
22+
<Tooltip label="Include response examples in the specification. This could include private information. Your choice will persist across sessions.">
23+
<FormLabel htmlFor={TOGGLEMOREID} mb="0">
24+
More info
25+
</FormLabel>
26+
</Tooltip>
27+
<Switch
28+
id={TOGGLEMOREID}
29+
onChange={onToggleMoreInfo}
30+
isChecked={moreInfoEnabled}
31+
/>
32+
</FormControl>
33+
<HStack>
34+
<ControlConfigImport />
35+
</HStack>
2836
</HStack>
2937
);
3038
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
Tooltip,
1515
useToast,
1616
} from "@chakra-ui/react";
17+
import copy from "copy-to-clipboard";
1718
import Context from "./context";
1819

1920
function ControlConfigImport() {
@@ -46,6 +47,17 @@ function ControlConfigImport() {
4647
return result;
4748
};
4849

50+
const onExport = () => {
51+
const stateStr = ctx.export();
52+
copy(stateStr);
53+
toast({
54+
title: "Copied to clipboard.",
55+
status: "success",
56+
duration: 2000,
57+
isClosable: true,
58+
});
59+
};
60+
4961
return (
5062
<>
5163
<Tooltip label="Import a state string that was previously exported. This will open a modal, paste in the string to load the state.">
@@ -54,6 +66,12 @@ function ControlConfigImport() {
5466
</Button>
5567
</Tooltip>
5668

69+
<Tooltip label="Export will copy a state string to your clipboard. Save this somewhere on your computer. You can load it by clicking import and pasting the string.">
70+
<Button size="md" onClick={onExport} colorScheme="teal">
71+
Export
72+
</Button>
73+
</Tooltip>
74+
5775
<Modal
5876
initialFocusRef={initialRef}
5977
finalFocusRef={finalRef}

src/ui/Main.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ function Main() {
145145
endpoints,
146146
export: requestStore.export,
147147
import: importFn,
148+
options: requestStore.options,
148149
}}
149150
>
150151
<div className={classes.wrapper}>

src/ui/context.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createContext } from "react";
22
import RequestStore from "../lib/RequestStore";
33
import { Endpoint, EndpointsByHost } from "../utils/types";
4+
import { defaultOptions } from "../lib/store-helpers/persist-options";
45

56
type ContextType = {
67
endpoints: Endpoint[];
@@ -13,6 +14,7 @@ type ContextType = {
1314
parameterise: typeof RequestStore.prototype.parameterise;
1415
import: typeof RequestStore.prototype.import;
1516
export: typeof RequestStore.prototype.export;
17+
options: typeof RequestStore.prototype.options;
1618
};
1719

1820
const defaultContextValue: ContextType = {
@@ -26,6 +28,7 @@ const defaultContextValue: ContextType = {
2628
parameterise: () => {},
2729
import: () => false,
2830
export: () => '',
31+
options: () => defaultOptions,
2932
};
3033

3134
const Context = createContext<ContextType>(defaultContextValue);

0 commit comments

Comments
 (0)