Skip to content

Commit da88ab0

Browse files
(v2.6) file uploads finalized
1 parent 13621d5 commit da88ab0

File tree

8 files changed

+129
-34
lines changed

8 files changed

+129
-34
lines changed

ui/src/components/ApiAction.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ export default function ApiAction(props: Props) {
6565
}
6666

6767
const handleSendRequest = () => {
68-
updateLocalStorage()
6968
try {
7069
JSON.parse(requestHeaders)
7170
} catch (error: any) {
@@ -74,6 +73,10 @@ export default function ApiAction(props: Props) {
7473
}
7574
const headers = JSON.parse(requestHeaders)
7675
headers['X-Request-LRD'] = true
76+
if (fileParams != null) {
77+
delete headers['Content-Type']
78+
headers['Accept'] = 'multipart/form-data'
79+
}
7780

7881
const options: any = {
7982
credentials: "include",
@@ -151,11 +154,13 @@ export default function ApiAction(props: Props) {
151154
}
152155
setResponseData(JSON.stringify(data, null, 2))
153156
setActiveTab('response')
157+
updateLocalStorage()
154158
}).catch((error) => {
155159
setError("Response error: " + error)
156160
setResponseStatus(500)
157161
setSendingRequest(false)
158162
setActiveTab('response')
163+
updateLocalStorage()
159164
})
160165

161166
}
@@ -195,7 +200,27 @@ export default function ApiAction(props: Props) {
195200
return
196201
}
197202
const body: any = {}
198-
for (const [key] of Object.entries(lrdDocsItem.rules)) {
203+
for (const [key, rule] of Object.entries(lrdDocsItem.rules)) {
204+
if (rule.length == 0) {
205+
continue
206+
}
207+
const theRule = rule[0].split("|")
208+
if (theRule.includes('file') || theRule.includes('image')) {
209+
continue
210+
}
211+
if (key.includes(".*")) {
212+
body[key] = []
213+
continue
214+
}
215+
if (key.includes(".")) {
216+
const keys = key.split(".")
217+
if (keys.length == 2) {
218+
body[keys[0]] = {}
219+
body[keys[0]][keys[1]] = ""
220+
}
221+
continue
222+
}
223+
199224
body[key] = ""
200225
}
201226
const jsonBody = JSON.stringify(body, null, 2)

ui/src/components/ApiInfo.tsx

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import React from 'react';
1+
import React, { useState, useEffect } from 'react';
22
import shortid from 'shortid';
33
import {explode} from '../libs/strings'
44
import type { IAPIInfo } from '../libs/types'
5-
import { ChevronRightIcon, LinkIcon, EnvelopeIcon } from '@heroicons/react/24/solid'
5+
import { ChevronRightIcon, LinkIcon, EnvelopeIcon } from '@heroicons/react/24/outline'
66

77
interface Props {
88
lrdDocsItem: IAPIInfo,
@@ -12,6 +12,22 @@ export default function ApiInfo(props: Props) {
1212

1313
const { lrdDocsItem, method } = props
1414

15+
const [hasFile, setHasFile] = useState(false)
16+
useEffect(() => {
17+
//check if lrdDocsItem has rules
18+
const files: any = []
19+
for (const [key, rule] of Object.entries(lrdDocsItem.rules)) {
20+
if (rule.length == 0) {
21+
continue
22+
}
23+
const theRule = rule[0].split("|")
24+
if (theRule.includes('file') || theRule.includes('image')) {
25+
files.push(key)
26+
}
27+
}
28+
setHasFile(files.length > 0)
29+
}, [])
30+
1531
const StyledRule = (theRule: any): JSX.Element => {
1632
theRule = theRule.rule
1733
const split = theRule.split(':')
@@ -77,7 +93,13 @@ export default function ApiInfo(props: Props) {
7793
</h2>
7894
<h3 className='pt-4'>
7995
<span className='text-sm text-slate-500'>REQUEST SCHEMA</span>
80-
<code className='pl-2 text-xs'>application/json</code>
96+
<code className='pl-2 text-xs'>
97+
{hasFile ? (
98+
'multipart/form-data'
99+
) : (
100+
'application/json'
101+
)}
102+
</code>
81103
</h3>
82104
<div className='pt-4'>
83105

@@ -87,7 +109,8 @@ export default function ApiInfo(props: Props) {
87109

88110
<tr key={shortid.generate()}>
89111
<th className='param-cell'>
90-
¬ <code className='pl-1'>
112+
<span className='text-blue-500 pr-1'>¬</span>
113+
<code className='pl-1'>
91114
{key}
92115
{lrdDocsItem.rules[key].map((rule) => (
93116
rule.split('|').map((theRule) => (

ui/src/components/TopNav.tsx

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
import React, { useEffect } from 'react';
22

33
import useLocalStorage from 'react-use-localstorage';
4-
import { MagnifyingGlassIcon, Cog6ToothIcon, ArrowUpRightIcon, MoonIcon, SunIcon, XMarkIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/solid'
4+
import { MagnifyingGlassIcon,
5+
Cog6ToothIcon,
6+
ArrowUpRightIcon,
7+
MoonIcon,
8+
SunIcon,
9+
XMarkIcon,
10+
Bars3BottomLeftIcon,
11+
RectangleGroupIcon,
12+
FunnelIcon,
13+
CircleStackIcon,
14+
ChatBubbleLeftIcon } from '@heroicons/react/24/outline'
515

616
interface Props {
717
handleChangeSettings: (
@@ -133,8 +143,21 @@ export default function TopNav(props: Props) {
133143
</a>
134144
<div className="modal" id="modal-settings">
135145
<div className="modal-box">
136-
<h3 className="font-bold text-lg">Settings</h3>
137-
<h4 className="font-bold mt-10">Sort By</h4>
146+
<div className="modal-action float-right">
147+
<a href="#" className="btn btn-sm btn-ghost">
148+
<XMarkIcon className="h-6 w-6" /> Close
149+
</a>
150+
</div>
151+
<h3 className="font-bold text-lg mt-7">
152+
<Cog6ToothIcon className="inline-block h-6 w-6 mr-1" />
153+
Settings
154+
</h3>
155+
<hr />
156+
<h4 className="font-bold mt-10">
157+
<Bars3BottomLeftIcon className="inline-block h-6 w-6 mr-1" />
158+
Sort By
159+
</h4>
160+
<hr />
138161
<div className="form-control">
139162
<label className="label">
140163

@@ -148,7 +171,12 @@ export default function TopNav(props: Props) {
148171
<span className="label-text">HTTP Methods</span>
149172
</label>
150173
</div>
151-
<h4 className="font-bold mt-10">Group By</h4>
174+
<h4 className="font-bold mt-10">
175+
<RectangleGroupIcon className="inline-block h-6 w-6 mr-1" />
176+
Group By
177+
</h4>
178+
<hr />
179+
<hr />
152180
<div className="form-control">
153181
<label className="label">
154182

@@ -162,7 +190,11 @@ export default function TopNav(props: Props) {
162190
<span className="label-text">Controller Name</span>
163191
</label>
164192
</div>
165-
<h4 className="font-bold mt-10">Display Settings</h4>
193+
<h4 className="font-bold mt-10">
194+
<FunnelIcon className="inline-block h-6 w-6 mr-1" />
195+
Filter Settings
196+
</h4>
197+
<hr />
166198
<div className="form-control">
167199
<label className="label">
168200
<span className="label-text">GET</span>
@@ -189,7 +221,11 @@ export default function TopNav(props: Props) {
189221
<input type="checkbox" onChange={handleChangeHead} className="toggle toggle-success" checked={showHead == 'true'} />
190222
</label>
191223
</div>
192-
<h4 className="font-bold mt-10">Storage</h4>
224+
<h4 className="font-bold mt-10">
225+
<CircleStackIcon className="inline-block h-6 w-6 mr-1" />
226+
Storage
227+
</h4>
228+
<hr />
193229
<div className="form-control">
194230
<label className="label">
195231
<span className="label-text">
@@ -199,11 +235,11 @@ export default function TopNav(props: Props) {
199235
<button className="btn btn-sm btn-error" onClick={handleClearLocalStorage}>Clear</button>
200236
</label>
201237
</div>
202-
<div className="modal-action">
238+
{/* <div className="modal-action">
203239
<a href="#" className="btn btn-sm">
204240
<XMarkIcon className="h-6 w-6" /> Close
205241
</a>
206-
</div>
242+
</div> */}
207243
</div>
208244
</div>
209245
</div>

ui/src/components/elements/ApiActionCurl.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import "ace-builds/src-noconflict/mode-sh";
88
import "ace-builds/src-noconflict/theme-one_dark";
99
import "ace-builds/src-noconflict/ext-language_tools";
1010

11-
import { ChevronRightIcon } from '@heroicons/react/24/solid';
11+
import { ChevronRightIcon } from '@heroicons/react/24/outline';
1212

1313
interface Props {
1414
curlCommand: string,

ui/src/components/elements/ApiActionInfo.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { IAPIInfo } from '../../libs/types'
55
import { responsesText } from '../../libs/constants'
66
import ReactMarkdown from 'react-markdown'
77
import remarkGfm from 'remark-gfm'
8-
import { ChevronRightIcon, CodeBracketIcon } from '@heroicons/react/24/solid';
8+
import { ChevronRightIcon, CodeBracketIcon } from '@heroicons/react/24/outline';
99
import ApiActionCurl from './ApiActionCurl';
1010

1111
interface Props {
@@ -62,8 +62,7 @@ export default function ApiActionInfo(props: Props) {
6262
)}
6363
<tr>
6464
<th>
65-
Response
66-
<br />HTTP Codes
65+
Status Codes
6766
</th>
6867
<td>
6968
<div className="collapse">

ui/src/components/elements/ApiActionRequest.tsx

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import "ace-builds/src-noconflict/mode-json";
1212
import "ace-builds/src-noconflict/theme-one_dark";
1313
import "ace-builds/src-noconflict/ext-language_tools";
1414

15-
import { PaperAirplaneIcon, ChevronRightIcon } from '@heroicons/react/24/solid'
15+
import { PaperAirplaneIcon, ChevronRightIcon, ExclamationTriangleIcon, LockOpenIcon } from '@heroicons/react/24/outline'
1616

1717

1818
interface Props {
@@ -61,7 +61,11 @@ export default function ApiActionRequest(props: Props) {
6161
//check if lrdDocsItem has rules
6262
const files: any = []
6363
for (const [key, rule] of Object.entries(lrdDocsItem.rules)) {
64-
if (rule.includes('file') || rule.includes('image')) {
64+
if (rule.length == 0) {
65+
continue
66+
}
67+
const theRule = rule[0].split("|")
68+
if (theRule.includes('file') || theRule.includes('image')) {
6569
files.push(key)
6670
}
6771
}
@@ -91,6 +95,13 @@ export default function ApiActionRequest(props: Props) {
9195
<div className="collapse-title text-sm text-slate-500 pl-0">
9296
Set Global Headers
9397
</div>
98+
<div className='text-sm text-slate-500 p-0'>
99+
<ExclamationTriangleIcon className='inline-block w-4 h-4 ml-1 text-yellow-500' />
100+
&nbsp; This request requires a file upload. <br />
101+
<LockOpenIcon className='inline-block w-4 h-4 ml-1 text-slate-500' />
102+
&nbsp; Global headers will be overridden as <code>application/json</code><code>multipart/form-data</code>
103+
<br />
104+
</div>
94105
<div className="collapse-content p-0">
95106
<AceEditor
96107
height='200px'
@@ -134,14 +145,6 @@ export default function ApiActionRequest(props: Props) {
134145
<span className='pl-5 text-sm text-slate-500'>REQUEST BODY</span>
135146
{files.map((file: string) =>
136147
<div key={shortid.generate()}>
137-
<div className='m-2 pl-3'>
138-
<code>
139-
<small>{file}</small>
140-
</code>
141-
{file.includes('.*') && (
142-
<ChevronRightIcon className='inline-block w-4 h-4 ml-1' />
143-
)}
144-
</div>
145148
<Files
146149
className='p-5 bg-gray-800 border border-gray-500 border-double hover:bg-gray-700 hover:border-dashed hover:cursor-pointer'
147150
onChange={(e: any) => handleFileUploaded(e, file)}
@@ -159,10 +162,19 @@ export default function ApiActionRequest(props: Props) {
159162
))}
160163
</div>
161164
)}
162-
{file.includes('.*')
163-
? 'Drop or click to upload multiple files'
164-
: 'Drop or click to upload single file'
165-
}
165+
<span className='text-slate-500'>
166+
<code>
167+
<small>{file}</small>
168+
</code>
169+
{file.includes('.*') && (
170+
<ChevronRightIcon className='inline-block w-4 h-4 ml-1' />
171+
)}
172+
<br />
173+
{file.includes('.*')
174+
? 'Drop or click to upload multiple files'
175+
: 'Drop or click to upload single file'
176+
}
177+
</span>
166178
</Files>
167179
</div>
168180
)}

ui/src/components/elements/ApiActionTabs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22

3-
import { InformationCircleIcon, PaperAirplaneIcon, CircleStackIcon, DocumentTextIcon, ReceiptRefundIcon } from '@heroicons/react/24/solid'
3+
import { InformationCircleIcon, PaperAirplaneIcon, CircleStackIcon, DocumentTextIcon, ReceiptRefundIcon } from '@heroicons/react/24/outline'
44

55
interface Props {
66
responseStatus: number,

ui/src/global.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ td {
4949
.table th.param-cell {
5050
@apply font-normal;
5151
@apply truncate;
52-
border-left: 1px solid rgb(124, 124, 187);
52+
border-left: 2px solid rgb(59 130 246 / var(--tw-border-opacity));
5353
padding-left: 0px;
5454

5555
}

0 commit comments

Comments
 (0)