docusaurus-theme-openapi-docs 1.1.12 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/lib/theme/ApiDemoPanel/Authorization/auth-types.js +4 -0
  2. package/lib/theme/ApiDemoPanel/Authorization/index.js +125 -0
  3. package/lib/theme/ApiDemoPanel/Authorization/slice.js +1 -1
  4. package/lib/theme/ApiDemoPanel/Body/index.js +7 -6
  5. package/lib/theme/ApiDemoPanel/Execute/index.js +168 -0
  6. package/lib/theme/ApiDemoPanel/Execute/makeRequest.js +204 -0
  7. package/lib/theme/ApiDemoPanel/FormItem/index.js +7 -0
  8. package/lib/theme/ApiDemoPanel/FormItem/styles.module.css +5 -0
  9. package/lib/theme/ApiDemoPanel/ParamOptions/index.js +1 -1
  10. package/lib/theme/ApiDemoPanel/Request/index.js +78 -0
  11. package/lib/theme/ApiDemoPanel/Request/styles.module.css +17 -0
  12. package/lib/theme/ApiDemoPanel/Response/index.js +16 -12
  13. package/lib/theme/ApiDemoPanel/SecuritySchemes/index.js +24 -19
  14. package/lib/theme/ApiDemoPanel/Server/index.js +1 -0
  15. package/lib/theme/ApiDemoPanel/buildPostmanRequest.js +25 -3
  16. package/lib/theme/ApiDemoPanel/index.js +5 -13
  17. package/lib/theme/ApiDemoPanel/persistanceMiddleware.js +1 -1
  18. package/lib/theme/ApiDemoPanel/react-modal.d.ts +8 -0
  19. package/lib/theme/ApiItem/Layout/styles.module.css +56 -0
  20. package/lib/theme/ParamsItem/index.js +5 -1
  21. package/lib-next/theme/ApiDemoPanel/Authorization/auth-types.js +4 -0
  22. package/lib-next/theme/ApiDemoPanel/Authorization/index.js +149 -0
  23. package/lib-next/theme/ApiDemoPanel/Authorization/slice.js +1 -1
  24. package/lib-next/theme/ApiDemoPanel/Body/index.js +28 -6
  25. package/lib-next/theme/ApiDemoPanel/Execute/index.js +170 -0
  26. package/lib-next/theme/ApiDemoPanel/Execute/makeRequest.js +190 -0
  27. package/lib-next/theme/ApiDemoPanel/FormItem/index.js +9 -1
  28. package/lib-next/theme/ApiDemoPanel/FormItem/styles.module.css +5 -0
  29. package/lib-next/theme/ApiDemoPanel/ParamOptions/index.js +1 -1
  30. package/lib-next/theme/ApiDemoPanel/Request/index.js +60 -0
  31. package/lib-next/theme/ApiDemoPanel/Request/styles.module.css +17 -0
  32. package/lib-next/theme/ApiDemoPanel/Response/index.js +18 -13
  33. package/lib-next/theme/ApiDemoPanel/SecuritySchemes/index.js +22 -20
  34. package/lib-next/theme/ApiDemoPanel/Server/index.js +1 -0
  35. package/lib-next/theme/ApiDemoPanel/buildPostmanRequest.js +25 -3
  36. package/lib-next/theme/ApiDemoPanel/index.js +4 -13
  37. package/lib-next/theme/ApiDemoPanel/persistanceMiddleware.js +1 -1
  38. package/lib-next/theme/ApiDemoPanel/react-modal.d.ts +8 -0
  39. package/lib-next/theme/ApiItem/Layout/styles.module.css +56 -0
  40. package/lib-next/theme/ParamsItem/index.js +5 -1
  41. package/package.json +5 -4
  42. package/src/theme/ApiDemoPanel/Authorization/auth-types.ts +4 -0
  43. package/src/theme/ApiDemoPanel/Authorization/index.tsx +154 -0
  44. package/src/theme/ApiDemoPanel/Authorization/slice.ts +1 -1
  45. package/src/theme/ApiDemoPanel/Body/index.tsx +28 -6
  46. package/src/theme/ApiDemoPanel/Execute/index.tsx +188 -0
  47. package/src/theme/ApiDemoPanel/Execute/makeRequest.ts +197 -0
  48. package/src/theme/ApiDemoPanel/FormItem/index.tsx +11 -2
  49. package/src/theme/ApiDemoPanel/FormItem/styles.module.css +5 -0
  50. package/src/theme/ApiDemoPanel/ParamOptions/index.tsx +1 -1
  51. package/src/theme/ApiDemoPanel/Request/index.tsx +71 -0
  52. package/src/theme/ApiDemoPanel/Request/styles.module.css +17 -0
  53. package/src/theme/ApiDemoPanel/Response/index.tsx +19 -13
  54. package/src/theme/ApiDemoPanel/SecuritySchemes/index.tsx +22 -17
  55. package/src/theme/ApiDemoPanel/Server/index.tsx +1 -0
  56. package/src/theme/ApiDemoPanel/buildPostmanRequest.ts +22 -3
  57. package/src/theme/ApiDemoPanel/index.tsx +4 -13
  58. package/src/theme/ApiDemoPanel/persistanceMiddleware.ts +1 -1
  59. package/src/theme/ApiDemoPanel/react-modal.d.ts +8 -0
  60. package/src/theme/ApiItem/Layout/styles.module.css +56 -0
  61. package/src/theme/ParamsItem/index.js +5 -1
@@ -8,13 +8,11 @@ import React from "react";
8
8
  import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
9
9
  import sdk from "@paloaltonetworks/postman-collection";
10
10
  import { Provider } from "react-redux";
11
- import Accept from "./Accept";
12
11
  import { createAuth } from "./Authorization/slice";
13
- import Body from "./Body";
14
12
  import Curl from "./Curl";
15
13
  import MethodEndpoint from "./MethodEndpoint";
16
- import ParamOptions from "./ParamOptions";
17
14
  import { createPersistanceMiddleware } from "./persistanceMiddleware";
15
+ import Request from "./Request";
18
16
  import Response from "./Response";
19
17
  import SecuritySchemes from "./SecuritySchemes";
20
18
  import Server from "./Server";
@@ -83,18 +81,11 @@ function ApiDemoPanel({ item, infoPath }) {
83
81
  <Provider store={store2}>
84
82
  <div className={styles.apiDemoPanelContainer}>
85
83
  <MethodEndpoint method={method} path={path} />
86
- <SecuritySchemes infoPath={infoPath} />
87
- <div className={styles.optionsPanel}>
88
- <ParamOptions />
89
- <Body
90
- jsonRequestBodyExample={item.jsonRequestBodyExample}
91
- requestBodyMetadata={item.requestBody}
92
- />
93
- <Accept />
94
- </div>
95
84
  <Server />
96
- <Curl postman={postman} codeSamples={item["x-code-samples"] ?? []} />
85
+ <SecuritySchemes infoPath={infoPath} />
86
+ <Request item={item} />
97
87
  <Response />
88
+ <Curl postman={postman} codeSamples={item["x-code-samples"] ?? []} />
98
89
  </div>
99
90
  </Provider>
100
91
  );
@@ -10,7 +10,7 @@ export function createPersistanceMiddleware(options) {
10
10
  const persistanceMiddleware = (storeAPI) => (next) => (action) => {
11
11
  const result = next(action);
12
12
  const state = storeAPI.getState();
13
- const storage = createStorage(options?.authPersistance);
13
+ const storage = createStorage("sessionStorage");
14
14
 
15
15
  if (action.type === setAuthData.type) {
16
16
  for (const [key, value] of Object.entries(state.auth.data)) {
@@ -0,0 +1,8 @@
1
+ /* ============================================================================
2
+ * Copyright (c) Palo Alto Networks
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ * ========================================================================== */
7
+
8
+ declare module "react-modal";
@@ -71,6 +71,62 @@
71
71
  border-top: unset !important;
72
72
  }
73
73
 
74
+ :global(.theme-api-markdown .details__demo-panel) {
75
+ margin-bottom: 1rem;
76
+ background: var(--openapi-card-background-color);
77
+ border-radius: var(--openapi-card-border-radius);
78
+ }
79
+
80
+ :global(.theme-api-markdown .details__demo-panel > summary) {
81
+ padding-left: 1rem;
82
+ padding-top: 1rem;
83
+ cursor: pointer;
84
+ }
85
+
86
+ :global(.theme-api-markdown .details__demo-panel > div > div > pre) {
87
+ border-top-left-radius: 0;
88
+ border-top-right-radius: 0;
89
+ }
90
+
91
+ :global(.theme-api-markdown .details__demo-panel > summary::marker) {
92
+ display: none;
93
+ content: "";
94
+ }
95
+
96
+ :global(.theme-api-markdown
97
+ .details__demo-panel
98
+ > summary::-webkit-details-marker) {
99
+ display: none;
100
+ content: "";
101
+ }
102
+
103
+ :global(.theme-api-markdown .details__demo-panel > pre) {
104
+ margin-bottom: 0;
105
+ padding-top: 0;
106
+ }
107
+
108
+ :global(.theme-api-markdown .details__request-summary) {
109
+ display: flex;
110
+ justify-content: space-between;
111
+ align-items: center;
112
+ }
113
+
114
+ :global(.theme-api-markdown .details__request-summary > button) {
115
+ margin-bottom: 1rem;
116
+ margin-right: 1rem;
117
+ }
118
+
119
+ :global(.theme-api-markdown .details__response-summary) {
120
+ display: flex;
121
+ justify-content: space-between;
122
+ align-items: center;
123
+ }
124
+
125
+ :global(.theme-api-markdown .details__response-summary > button) {
126
+ margin-bottom: 1rem;
127
+ margin-right: 1rem;
128
+ }
129
+
74
130
  :global(.theme-api-markdown code) {
75
131
  max-width: 600px;
76
132
  max-height: 500px;
@@ -53,7 +53,11 @@ function ParamsItem({
53
53
  ));
54
54
 
55
55
  const renderDefaultValue = guard(
56
- schema.items ? schema.items.default : schema.default,
56
+ schema && schema.items
57
+ ? schema.items.default
58
+ : schema
59
+ ? schema.default
60
+ : undefined,
57
61
  (value) => (
58
62
  <div>
59
63
  <ReactMarkdown children={`**Default value:** \`${value}\``} />
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "docusaurus-theme-openapi-docs",
3
3
  "description": "OpenAPI theme for Docusaurus.",
4
- "version": "1.1.12",
4
+ "version": "1.2.0",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -44,19 +44,20 @@
44
44
  "dependencies": {
45
45
  "@docusaurus/theme-common": "^2.0.1",
46
46
  "@mdx-js/react": "^1.6.21",
47
- "@paloaltonetworks/postman-code-generators": "^1.1.9",
47
+ "@paloaltonetworks/postman-code-generators": "^1.1.12",
48
48
  "@paloaltonetworks/postman-collection": "^4.1.0",
49
49
  "@reduxjs/toolkit": "^1.7.1",
50
50
  "buffer": "^6.0.3",
51
51
  "clsx": "^1.1.1",
52
52
  "crypto-js": "^4.1.1",
53
- "docusaurus-plugin-openapi-docs": "^1.1.12",
53
+ "docusaurus-plugin-openapi-docs": "^1.2.0",
54
54
  "immer": "^9.0.7",
55
55
  "lodash": "^4.17.20",
56
56
  "process": "^0.11.10",
57
57
  "react-live": "^3.1.1",
58
58
  "react-magic-dropzone": "^1.0.1",
59
59
  "react-markdown": "^8.0.1",
60
+ "react-modal": "^3.15.1",
60
61
  "react-redux": "^7.2.0",
61
62
  "redux-devtools-extension": "^2.13.8",
62
63
  "webpack": "^5.61.0",
@@ -69,5 +70,5 @@
69
70
  "engines": {
70
71
  "node": ">=14"
71
72
  },
72
- "gitHead": "a45dcbd12f26156147a50f5f61026c3adee4b1c8"
73
+ "gitHead": "fdbc413e36c3b7c202cc31606124c0a8eb76811b"
73
74
  }
@@ -11,6 +11,10 @@ export function getAuthDataKeys(security: { [key: string]: any }) {
11
11
  return ["token"];
12
12
  }
13
13
 
14
+ if (security.type === "oauth2") {
15
+ return ["token"];
16
+ }
17
+
14
18
  // Basic Auth
15
19
  if (security.type === "http" && security.scheme === "basic") {
16
20
  return ["username", "password"];
@@ -0,0 +1,154 @@
1
+ /* ============================================================================
2
+ * Copyright (c) Palo Alto Networks
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ * ========================================================================== */
7
+
8
+ import React from "react";
9
+
10
+ import FormItem from "../FormItem";
11
+ import FormSelect from "../FormSelect";
12
+ import FormTextInput from "../FormTextInput";
13
+ import { useTypedDispatch, useTypedSelector } from "../hooks";
14
+ import { setAuthData, setSelectedAuth } from "./slice";
15
+
16
+ function Authorization() {
17
+ const data = useTypedSelector((state) => state.auth.data);
18
+ const options = useTypedSelector((state) => state.auth.options);
19
+ const selected = useTypedSelector((state) => state.auth.selected);
20
+
21
+ const dispatch = useTypedDispatch();
22
+
23
+ if (selected === undefined) {
24
+ return null;
25
+ }
26
+
27
+ const selectedAuth = options[selected];
28
+
29
+ const optionKeys = Object.keys(options);
30
+
31
+ return (
32
+ <div>
33
+ {optionKeys.length > 1 && (
34
+ <FormItem label="Security Scheme">
35
+ <FormSelect
36
+ options={optionKeys}
37
+ value={selected}
38
+ onChange={(e) => {
39
+ dispatch(setSelectedAuth(e.target.value));
40
+ }}
41
+ />
42
+ </FormItem>
43
+ )}
44
+ {selectedAuth.map((a) => {
45
+ if (a.type === "http" && a.scheme === "bearer") {
46
+ return (
47
+ <FormItem label="Bearer Token" key={a.key + "-bearer"}>
48
+ <FormTextInput
49
+ placeholder="Bearer Token"
50
+ value={data[a.key].token ?? ""}
51
+ onChange={(e) => {
52
+ const value = e.target.value.trim();
53
+ dispatch(
54
+ setAuthData({
55
+ scheme: a.key,
56
+ key: "token",
57
+ value: value ? value : undefined,
58
+ })
59
+ );
60
+ }}
61
+ />
62
+ </FormItem>
63
+ );
64
+ }
65
+
66
+ if (a.type === "oauth2") {
67
+ return (
68
+ <FormItem label="Bearer Token" key={a.key + "-oauth2"}>
69
+ <FormTextInput
70
+ placeholder="Bearer Token"
71
+ value={data[a.key].token ?? ""}
72
+ onChange={(e) => {
73
+ const value = e.target.value.trim();
74
+ dispatch(
75
+ setAuthData({
76
+ scheme: a.key,
77
+ key: "token",
78
+ value: value ? value : undefined,
79
+ })
80
+ );
81
+ }}
82
+ />
83
+ </FormItem>
84
+ );
85
+ }
86
+
87
+ if (a.type === "http" && a.scheme === "basic") {
88
+ return (
89
+ <React.Fragment key={a.key + "-basic"}>
90
+ <FormItem label="Username">
91
+ <FormTextInput
92
+ placeholder="Username"
93
+ value={data[a.key].username ?? ""}
94
+ onChange={(e) => {
95
+ const value = e.target.value.trim();
96
+ dispatch(
97
+ setAuthData({
98
+ scheme: a.key,
99
+ key: "username",
100
+ value: value ? value : undefined,
101
+ })
102
+ );
103
+ }}
104
+ />
105
+ </FormItem>
106
+ <FormItem label="Password">
107
+ <FormTextInput
108
+ placeholder="Password"
109
+ password
110
+ value={data[a.key].password ?? ""}
111
+ onChange={(e) => {
112
+ const value = e.target.value.trim();
113
+ dispatch(
114
+ setAuthData({
115
+ scheme: a.key,
116
+ key: "password",
117
+ value: value ? value : undefined,
118
+ })
119
+ );
120
+ }}
121
+ />
122
+ </FormItem>
123
+ </React.Fragment>
124
+ );
125
+ }
126
+
127
+ if (a.type === "apiKey") {
128
+ return (
129
+ <FormItem label={`${a.key}`} key={a.key + "-apikey"}>
130
+ <FormTextInput
131
+ placeholder={`${a.key}`}
132
+ value={data[a.key].apiKey ?? ""}
133
+ onChange={(e) => {
134
+ const value = e.target.value.trim();
135
+ dispatch(
136
+ setAuthData({
137
+ scheme: a.key,
138
+ key: "apiKey",
139
+ value: value ? value : undefined,
140
+ })
141
+ );
142
+ }}
143
+ />
144
+ </FormItem>
145
+ );
146
+ }
147
+
148
+ return null;
149
+ })}
150
+ </div>
151
+ );
152
+ }
153
+
154
+ export default Authorization;
@@ -57,7 +57,7 @@ export function createAuth({
57
57
  };
58
58
  options?: ThemeConfig["api"];
59
59
  }): AuthState {
60
- const storage = createStorage(opts?.authPersistance);
60
+ const storage = createStorage("sessionStorage");
61
61
 
62
62
  let data: AuthState["data"] = {};
63
63
  let options: AuthState["options"] = {};
@@ -56,6 +56,7 @@ function BodyWrap({ requestBodyMetadata, jsonRequestBodyExample }: Props) {
56
56
 
57
57
  function Body({ requestBodyMetadata, jsonRequestBodyExample }: Props) {
58
58
  const contentType = useTypedSelector((state) => state.contentType.value);
59
+ const required = requestBodyMetadata?.required;
59
60
 
60
61
  const dispatch = useTypedDispatch();
61
62
 
@@ -84,7 +85,7 @@ function Body({ requestBodyMetadata, jsonRequestBodyExample }: Props) {
84
85
 
85
86
  if (schema?.format === "binary") {
86
87
  return (
87
- <FormItem label="Body">
88
+ <FormItem label="Body" required={required}>
88
89
  <FormFileUpload
89
90
  placeholder={schema.description || "Body"}
90
91
  onChange={(file) => {
@@ -110,7 +111,7 @@ function Body({ requestBodyMetadata, jsonRequestBodyExample }: Props) {
110
111
  schema?.type === "object"
111
112
  ) {
112
113
  return (
113
- <FormItem label="Body">
114
+ <FormItem label="Body" required={required}>
114
115
  <div
115
116
  style={{
116
117
  marginTop: "calc(var(--ifm-pre-padding) / 2)",
@@ -122,7 +123,14 @@ function Body({ requestBodyMetadata, jsonRequestBodyExample }: Props) {
122
123
  {Object.entries(schema.properties ?? {}).map(([key, val]: any) => {
123
124
  if (val.format === "binary") {
124
125
  return (
125
- <FormItem key={key} label={key}>
126
+ <FormItem
127
+ key={key}
128
+ label={key}
129
+ required={
130
+ Array.isArray(schema.required) &&
131
+ schema.required.includes(key)
132
+ }
133
+ >
126
134
  <FormFileUpload
127
135
  placeholder={val.description || key}
128
136
  onChange={(file) => {
@@ -147,7 +155,14 @@ function Body({ requestBodyMetadata, jsonRequestBodyExample }: Props) {
147
155
 
148
156
  if (val.enum) {
149
157
  return (
150
- <FormItem key={key} label={key}>
158
+ <FormItem
159
+ key={key}
160
+ label={key}
161
+ required={
162
+ Array.isArray(schema.required) &&
163
+ schema.required.includes(key)
164
+ }
165
+ >
151
166
  <FormSelect
152
167
  options={["---", ...val.enum]}
153
168
  onChange={(e) => {
@@ -169,7 +184,14 @@ function Body({ requestBodyMetadata, jsonRequestBodyExample }: Props) {
169
184
  }
170
185
  // TODO: support all the other types.
171
186
  return (
172
- <FormItem key={key} label={key}>
187
+ <FormItem
188
+ key={key}
189
+ label={key}
190
+ required={
191
+ Array.isArray(schema.required) &&
192
+ schema.required.includes(key)
193
+ }
194
+ >
173
195
  <FormTextInput
174
196
  placeholder={val.description || key}
175
197
  onChange={(e) => {
@@ -212,7 +234,7 @@ function Body({ requestBodyMetadata, jsonRequestBodyExample }: Props) {
212
234
  }
213
235
 
214
236
  return (
215
- <FormItem label="Body">
237
+ <FormItem label="Body" required={required}>
216
238
  <LiveApp action={dispatch} language={language}>
217
239
  {exampleBodyString}
218
240
  </LiveApp>
@@ -0,0 +1,188 @@
1
+ /* ============================================================================
2
+ * Copyright (c) Palo Alto Networks
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ * ========================================================================== */
7
+
8
+ import React from "react";
9
+
10
+ import sdk from "@paloaltonetworks/postman-collection";
11
+ import Modal from "react-modal";
12
+
13
+ import { useTypedDispatch, useTypedSelector } from "../hooks";
14
+ import { Param } from "../ParamOptions/slice";
15
+ import { setResponse } from "../Response/slice";
16
+ import buildPostmanRequest from "./../buildPostmanRequest";
17
+ import makeRequest from "./makeRequest";
18
+
19
+ function validateRequest(params: {
20
+ path: Param[];
21
+ query: Param[];
22
+ header: Param[];
23
+ cookie: Param[];
24
+ }) {
25
+ for (let paramList of Object.values(params)) {
26
+ for (let param of paramList) {
27
+ if (param.required && !param.value) {
28
+ return false;
29
+ }
30
+ }
31
+ }
32
+ return true;
33
+ }
34
+
35
+ interface Props {
36
+ postman: sdk.Request;
37
+ proxy?: string;
38
+ }
39
+
40
+ function Execute({ postman, proxy }: Props) {
41
+ const pathParams = useTypedSelector((state) => state.params.path);
42
+ const queryParams = useTypedSelector((state) => state.params.query);
43
+ const cookieParams = useTypedSelector((state) => state.params.cookie);
44
+ const headerParams = useTypedSelector((state) => state.params.header);
45
+ const contentType = useTypedSelector((state) => state.contentType.value);
46
+ const body = useTypedSelector((state) => state.body);
47
+ const accept = useTypedSelector((state) => state.accept.value);
48
+ const server = useTypedSelector((state) => state.server.value);
49
+ const params = useTypedSelector((state) => state.params);
50
+ const auth = useTypedSelector((state) => state.auth);
51
+
52
+ const isValidRequest = validateRequest(params);
53
+
54
+ const dispatch = useTypedDispatch();
55
+
56
+ const postmanRequest = buildPostmanRequest(postman, {
57
+ queryParams,
58
+ pathParams,
59
+ cookieParams,
60
+ contentType,
61
+ accept,
62
+ headerParams,
63
+ body,
64
+ server,
65
+ auth,
66
+ });
67
+
68
+ const delay = (ms: number) =>
69
+ new Promise((resolve) => setTimeout(resolve, ms));
70
+
71
+ function openModal() {
72
+ setIsOpen(true);
73
+ }
74
+
75
+ function closeModal() {
76
+ setIsOpen(false);
77
+ }
78
+
79
+ function acceptAgreement() {
80
+ setIsOpen(false);
81
+ setAgreementAccepted(true);
82
+ sessionStorage.setItem("agreement-ack", "true");
83
+ }
84
+
85
+ const [modalIsOpen, setIsOpen] = React.useState(false);
86
+ // Set the following as default value to persist to session and enable modal
87
+ // sessionStorage.getItem("agreement-ack") === "true"
88
+ const [agreementAccepted, setAgreementAccepted] = React.useState(true);
89
+
90
+ const customStyles = {
91
+ overlay: {
92
+ backdropFilter: "blur(10px)",
93
+ backgroundColor: "transparent",
94
+ },
95
+ content: {
96
+ top: "50%",
97
+ left: "50%",
98
+ right: "auto",
99
+ bottom: "auto",
100
+ marginRight: "-50%",
101
+ border: "none",
102
+ padding: "none",
103
+ borderRadius: "var(--openapi-card-border-radius)",
104
+ background: "var(--ifm-card-background-color)",
105
+ transform: "translate(-50%, -50%)",
106
+ maxWidth: "550px",
107
+ },
108
+ };
109
+
110
+ if (agreementAccepted) {
111
+ return (
112
+ <button
113
+ className="button button--sm button--secondary"
114
+ disabled={!isValidRequest}
115
+ onClick={async () => {
116
+ dispatch(setResponse("Fetching..."));
117
+ try {
118
+ await delay(1200);
119
+ const res = await makeRequest(postmanRequest, proxy, body);
120
+ dispatch(setResponse(res));
121
+ } catch (e: any) {
122
+ console.log(e);
123
+ dispatch(setResponse("Connection failed"));
124
+ }
125
+ }}
126
+ >
127
+ Send API Request
128
+ </button>
129
+ );
130
+ } else {
131
+ return (
132
+ <React.Fragment>
133
+ <button
134
+ className="button button--sm button--secondary"
135
+ onClick={openModal}
136
+ >
137
+ Send API Request
138
+ </button>
139
+ <Modal
140
+ isOpen={modalIsOpen}
141
+ onRequestClose={closeModal}
142
+ style={customStyles}
143
+ contentLabel="Terms of Use"
144
+ >
145
+ <form>
146
+ <div className="card">
147
+ <div className="card__header">
148
+ <h2>Terms of Use</h2>
149
+ <hr></hr>
150
+ </div>
151
+ <div className="card__body">
152
+ <p>
153
+ By accepting this agreement the end user acknowledges the
154
+ risks of performing authenticated and non-authenticated API
155
+ requests from the browser.
156
+ </p>
157
+ <p>
158
+ The end user also accepts the responsibility of safeguarding
159
+ API credentials and any potentially sensitive data returned by
160
+ the API.
161
+ </p>
162
+ <br></br>
163
+ </div>
164
+ <div className="card__footer">
165
+ <div className="button-group button-group--block">
166
+ <button
167
+ className="button button--sm button--outline button--success"
168
+ onClick={acceptAgreement}
169
+ >
170
+ AGREE
171
+ </button>
172
+ <button
173
+ className="button button--sm button--outline button--danger"
174
+ onClick={closeModal}
175
+ >
176
+ DISAGREE
177
+ </button>
178
+ </div>
179
+ </div>
180
+ </div>
181
+ </form>
182
+ </Modal>
183
+ </React.Fragment>
184
+ );
185
+ }
186
+ }
187
+
188
+ export default Execute;