Skip to content

Commit e28657f

Browse files
Merge pull request #150 from rakutentech/feature/upload
(v2.5) UI code refactored, simplified tabs and prettify curl
2 parents 374f4f1 + c938063 commit e28657f

File tree

7 files changed

+96
-122
lines changed

7 files changed

+96
-122
lines changed

.github/workflows/releaser.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ jobs:
2121
with:
2222
access_token: ${{ github.token }}
2323
- name: Checkout
24-
uses: actions/checkout@v2
24+
uses: actions/checkout@v3
25+
with:
26+
fetch-depth: 0
2527

2628
- uses: actions/setup-node@v3
2729
with:

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ Fixing lints
186186
- Groupby enabled for routes and controllers
187187
- v2.3 Bug fix for localstorage (tabs) and full UI refactored after alpha
188188
- v2.4 Show version on navbar and curl is using ace editor
189+
- v2.5 Groupby final fix and localstorage clear button. Other UI refactor
189190

190191

191192
# Maintainers

ui/src/components/ApiAction.tsx

Lines changed: 8 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ export default function ApiAction(props: Props) {
2828
const [sendingRequest, setSendingRequest] = useState(false);
2929
const [queryParams, setQueryParams] = useState('');
3030
const [bodyParams, setBodyParams] = useState('');
31-
const [showingInfo, setShowingInfo] = useState(true);
32-
const [showingRequest, setShowingRequest] = useState(false);
33-
const [showingResponse, setShowingResponse] = useState(false);
34-
const [showingSQL, setShowingSQL] = useState(false);
35-
const [showingLog, setShowingLog] = useState(false);
3631
const [responseData, setResponseData] = useState("");
3732
const [sqlQueriesCount, setSqlQueriesCount] = useState(0);
3833
const [sqlData, setSqlData] = useState("");
@@ -136,12 +131,12 @@ export default function ApiAction(props: Props) {
136131
delete data._lrd
137132
}
138133
setResponseData(JSON.stringify(data, null, 2))
139-
showResponse()
134+
setActiveTab('response')
140135
}).catch((error) => {
141136
setError("Response error: " + error)
142137
setResponseStatus(500)
143138
setSendingRequest(false)
144-
showResponse()
139+
setActiveTab('response')
145140
})
146141

147142
}
@@ -200,68 +195,23 @@ export default function ApiAction(props: Props) {
200195
}
201196
}
202197

203-
const showInfo = () => {
204-
setShowingRequest(false)
205-
setShowingResponse(false)
206-
setShowingSQL(false)
207-
setShowingInfo(true)
208-
setShowingLog(false)
209-
setActiveTab('info')
210-
}
211-
const showRequest = () => {
212-
setShowingResponse(false)
213-
setShowingSQL(false)
214-
setShowingInfo(false)
215-
setShowingRequest(true)
216-
setShowingLog(false)
217-
setActiveTab('request')
218-
}
219-
const showResponse = () => {
220-
setShowingRequest(false)
221-
setShowingSQL(false)
222-
setShowingInfo(false)
223-
setShowingResponse(true)
224-
setShowingLog(false)
225-
setActiveTab('response')
226-
}
227-
const showSQL = () => {
228-
setShowingRequest(false)
229-
setShowingResponse(false)
230-
setShowingInfo(false)
231-
setShowingSQL(true)
232-
setShowingLog(false)
233-
setActiveTab('sql')
234-
}
235-
const showLog = () => {
236-
setShowingRequest(false)
237-
setShowingResponse(false)
238-
setShowingInfo(false)
239-
setShowingSQL(false)
240-
setShowingLog(true)
241-
setActiveTab('log')
242-
}
243-
244198
return (
245199
<>
246200
<ApiActionTabs
247201
activeTab={activeTab}
248202
responseStatus={responseStatus}
249203
sqlQueriesCount={sqlQueriesCount}
250204
logData={logData}
251-
showInfo={showInfo}
252-
showRequest={showRequest}
253-
showResponse={showResponse}
254-
showSQL={showSQL}
255-
showLog={showLog} />
205+
setActiveTab={setActiveTab} />
256206

257207
<div className='mt-5'>
258208
{error && (
259209
<div className="alert alert-error mt-2 mb-2">{error}</div>
260210
)}
261-
{showingInfo && (
211+
{activeTab == 'info' && (
262212
<ApiActionInfo lrdDocsItem={lrdDocsItem} curlCommand={curlCommand} />
263213
)}
264-
{showingRequest && (
214+
{activeTab == 'request' && (
265215
<ApiActionRequest
266216
requestUri={requestUri}
267217
method={method}
@@ -277,19 +227,19 @@ export default function ApiAction(props: Props) {
277227
setQueryParams={setQueryParams} />
278228
)}
279229

280-
{showingResponse && (
230+
{activeTab == 'response' && (
281231
<ApiActionResponse
282232
responseHeaders={responseHeaders}
283233
responseData={responseData}
284234
timeTaken={timeTaken}
285235
responseStatus={responseStatus}
286236
serverMemory={serverMemory} />
287237
)}
288-
{showingSQL && (
238+
{activeTab == 'sql' && (
289239
<ApiActionSQL sqlData={sqlData} />
290240
)}
291241

292-
{showingLog && (
242+
{activeTab == 'logs' && (
293243
<ApiActionLog logData={logData} />
294244
)}
295245
</div>

ui/src/components/TopNav.tsx

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
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, Cog6ToothIcon, ArrowUpRightIcon, MoonIcon, SunIcon, XMarkIcon, ChatBubbleLeftIcon } from '@heroicons/react/24/solid'
55

66
interface Props {
77
handleChangeSettings: (
@@ -62,6 +62,11 @@ export default function TopNav(props: Props) {
6262
handleChangeSettings(showGet, showPost, showDelete, showPut, showPatch, e.target.checked, sort, groupby)
6363
}
6464

65+
const handleClearLocalStorage = () => {
66+
localStorage.clear()
67+
window.location.reload()
68+
}
69+
6570

6671
const toggleDarkMode = () => {
6772
const dataTheme = document.documentElement.getAttribute('data-theme');
@@ -108,22 +113,22 @@ export default function TopNav(props: Props) {
108113
</div>
109114
<div className="flex-none">
110115
<div className="form-control">
111-
<label htmlFor="search" className="relative text-gray-400 focus-within:text-gray-600 block">
112-
<MagnifyingGlassIcon className="pointer-events-none w-4 h-4 absolute top-1/2 transform -translate-y-1/2 left-3" />
113-
<input type="text" placeholder="Filter APIs" className="input pl-10 input-sm input-bordered" onChange={ (e) => handleSearch(e.target.value) } />
114-
</label>
115-
116-
</div>
116+
<label htmlFor="search" className="relative text-gray-400 focus-within:text-gray-600 block">
117+
<MagnifyingGlassIcon className="pointer-events-none w-4 h-4 absolute top-1/2 transform -translate-y-1/2 left-3" />
118+
<input type="text" placeholder="Filter APIs" className="input pl-10 input-sm input-bordered" onChange={(e) => handleSearch(e.target.value)} />
119+
</label>
120+
121+
</div>
117122
<div className="menu menu-horizontal px-6 ">
118123
<label className="swap swap-rotate">
119124
<input type="checkbox" onChange={toggleDarkMode} />
120-
{theme === 'dark' ? <SunIcon className="h-6 w-6"/> : <MoonIcon className="h-6 w-6"/>}
125+
{theme === 'dark' ? <SunIcon className="h-6 w-6" /> : <MoonIcon className="h-6 w-6" />}
121126
</label>
122127
</div>
123128
<div className="ml-1">
124129
<a href="#modal-settings" className="btn btn-ghost btn-sm">
125130
<span className="pr-1">
126-
<Cog6ToothIcon className="h-6 w-6"/>
131+
<Cog6ToothIcon className="h-6 w-6" />
127132
</span>
128133
</a>
129134
<div className="modal" id="modal-settings">
@@ -132,29 +137,29 @@ export default function TopNav(props: Props) {
132137
<h4 className="font-bold mt-10">Sort By</h4>
133138
<div className="form-control">
134139
<label className="label">
135-
140+
136141
<input type="radio" onChange={handleChangeSort} value="default" className="radio" checked={sort == "default"} />
137142
<span className="label-text">Default</span>
138-
143+
139144
<input type="radio" onChange={handleChangeSort} value="route_names" className="radio" checked={sort == "route_names"} />
140-
<span className="label-text">Routes</span>
141-
145+
<span className="label-text">Route Names</span>
146+
142147
<input type="radio" onChange={handleChangeSort} value="method_names" className="radio" checked={sort == "method_names"} />
143148
<span className="label-text">HTTP Methods</span>
144149
</label>
145150
</div>
146151
<h4 className="font-bold mt-10">Group By</h4>
147152
<div className="form-control">
148153
<label className="label">
149-
154+
150155
<input type="radio" onChange={handleChangeGroupby} value="default" className="radio" checked={groupby == "default"} />
151156
<span className="label-text">Default</span>
152-
157+
153158
<input type="radio" onChange={handleChangeGroupby} value="api_uri" className="radio" checked={groupby == "api_uri"} />
154-
<span className="label-text">API URI</span>
155-
159+
<span className="label-text">API Name</span>
160+
156161
<input type="radio" onChange={handleChangeGroupby} value="controller_full_path" className="radio" checked={groupby == "controller_full_path"} />
157-
<span className="label-text">Controller Names</span>
162+
<span className="label-text">Controller Name</span>
158163
</label>
159164
</div>
160165
<h4 className="font-bold mt-10">Display Settings</h4>
@@ -184,9 +189,19 @@ export default function TopNav(props: Props) {
184189
<input type="checkbox" onChange={handleChangeHead} className="toggle toggle-success" checked={showHead == 'true'} />
185190
</label>
186191
</div>
192+
<h4 className="font-bold mt-10">Storage</h4>
193+
<div className="form-control">
194+
<label className="label">
195+
<span className="label-text">
196+
Clear localstorage
197+
<p><small>Delete localstorage data, request body and queries</small></p>
198+
</span>
199+
<button className="btn btn-sm btn-error" onClick={handleClearLocalStorage}>Clear</button>
200+
</label>
201+
</div>
187202
<div className="modal-action">
188203
<a href="#" className="btn btn-sm">
189-
<XMarkIcon className="h-6 w-6"/> Close
204+
<XMarkIcon className="h-6 w-6" /> Close
190205
</a>
191206
</div>
192207
</div>
@@ -195,16 +210,16 @@ export default function TopNav(props: Props) {
195210
<div className="ml-1 ">
196211
<a className="btn btn-ghost btn-sm" href='/request-docs/api?openapi=true' target="_blank">
197212
<span className="pr-1">
198-
<ArrowUpRightIcon className="h-6 w-6"/>
199-
</span>
213+
<ArrowUpRightIcon className="h-6 w-6" />
214+
</span>
200215
OpenAPI 3.0
201216
</a>
202217
</div>
203218
<div className="ml-1 ">
204219
<a className="btn btn-ghost btn-sm" href='https://github.com/rakutentech/laravel-request-docs/issues/new' target="_blank" rel="noreferrer">
205220
<span className="pr-1">
206-
<ChatBubbleLeftIcon className="h-6 w-6"/>
207-
</span>
221+
<ChatBubbleLeftIcon className="h-6 w-6" />
222+
</span>
208223
Feature request
209224
</a>
210225
</div>

ui/src/components/elements/ApiActionInfo.tsx

Lines changed: 24 additions & 8 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 } from '@heroicons/react/24/solid';
8+
import { ChevronRightIcon, CodeBracketIcon } from '@heroicons/react/24/solid';
99
import ApiActionCurl from './ApiActionCurl';
1010

1111
interface Props {
@@ -19,12 +19,22 @@ export default function ApiActionInfo(props: Props) {
1919
return (
2020
<div className="mockup-window border">
2121
<div className="p-5">
22-
<div className='text-sm'>
23-
{/* eslint-disable-next-line react/no-children-prop */}
24-
<ReactMarkdown children={lrdDocsItem.docBlock} remarkPlugins={[remarkGfm]} />
25-
</div>
22+
{lrdDocsItem.docBlock && (
23+
<div className='text-sm mb-10 text-slate-500'>
24+
{/* eslint-disable-next-line react/no-children-prop */}
25+
<ReactMarkdown children={lrdDocsItem.docBlock} remarkPlugins={[remarkGfm]} />
26+
</div>
27+
)}
2628
<table className="table table-fixed table-compact">
2729
<tbody>
30+
<tr>
31+
<th>Method</th>
32+
<td>
33+
<span className={`method-${lrdDocsItem.httpMethod} uppercase`}>
34+
{lrdDocsItem.httpMethod}
35+
</span>
36+
</td>
37+
</tr>
2838
{lrdDocsItem.controller && (
2939
<tr>
3040
<th>Controller</th>
@@ -43,15 +53,18 @@ export default function ApiActionInfo(props: Props) {
4353
<td>
4454
{lrdDocsItem.middlewares.map((middleware) => (
4555
<div key={shortid.generate()}>
46-
<span className="ml-1 badge badge-normal badge-sm">{middleware}</span>
56+
<span className="badge badge-ghost badge-md mb-1 rounded-sm">{middleware}</span>
4757
<br />
4858
</div>
4959
))}
5060
</td>
5161
</tr>
5262
)}
5363
<tr>
54-
<th>Responses</th>
64+
<th>
65+
Response
66+
<br />HTTP Codes
67+
</th>
5568
<td>
5669
<div className="collapse">
5770
<input type="checkbox" />
@@ -72,7 +85,10 @@ export default function ApiActionInfo(props: Props) {
7285
</td>
7386
</tr>
7487
<tr>
75-
<th>Curl</th>
88+
<th>
89+
<CodeBracketIcon className='inline-block w-4 h-4 mr-1' />
90+
Curl
91+
</th>
7692
<td>
7793
<ApiActionCurl curlCommand={curlCommand} />
7894
</td>

ui/src/components/elements/ApiActionTabs.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,36 @@ interface Props {
66
responseStatus: number,
77
activeTab: string,
88
sqlQueriesCount: number,
9-
logData: string,
10-
showInfo: () => void,
11-
showRequest: () => void,
12-
showResponse: () => void,
13-
showSQL: () => void,
14-
showLog: () => void,
9+
logData: string,
10+
setActiveTab: (tab: string) => void
1511
}
1612

1713
export default function ApiActionTabs(props: Props) {
18-
const { activeTab, responseStatus, sqlQueriesCount, logData, showInfo, showRequest, showResponse, showSQL, showLog } = props
14+
const { activeTab, responseStatus, sqlQueriesCount, logData, setActiveTab } = props
1915

2016
return (
2117
<div className="tabs tabs-boxed">
22-
<a className={`tab ${activeTab == 'info' ? 'tab-active' : ''}`} onClick={showInfo}>
18+
<a className={`tab ${activeTab == 'info' ? 'tab-active' : ''}`} onClick={() => setActiveTab('info')}>
2319
<InformationCircleIcon className='inline-block w-5 h-5 mr-1' /> Info
2420
</a>
25-
<a className={`tab ${activeTab == 'request' ? 'tab-active' : ''}`} onClick={showRequest}>
21+
<a className={`tab ${activeTab == 'request' ? 'tab-active' : ''}`} onClick={() => setActiveTab('request')}>
2622
<PaperAirplaneIcon className='inline-block w-5 h-5 mr-1' /> Request
2723
</a>
28-
<a className={`tab ${activeTab == 'response' ? 'tab-active' : ''}`} onClick={showResponse}>
24+
<a className={`tab ${activeTab == 'response' ? 'tab-active' : ''}`} onClick={() => setActiveTab('response')}>
2925
<ReceiptRefundIcon className='inline-block w-5 h-5 mr-1' /> Response
3026
{responseStatus != 0 && (
3127
<div className={`ml-1 badge badge-sm badge-${responseStatus} badge-info`}>{responseStatus}</div>
3228
)}
3329
</a>
34-
<a className={`tab ${activeTab == 'sql' ? 'tab-active' : ''}`} onClick={showSQL}>
30+
<a className={`tab ${activeTab == 'sql' ? 'tab-active' : ''}`} onClick={() => setActiveTab('sql')}>
3531
<CircleStackIcon className='inline-block w-5 h-5 mr-1' /> SQL
3632
{responseStatus != 0 && (
3733
<div className="ml-1 badge badge-sm badge-warning">
3834
{sqlQueriesCount}
3935
</div>
4036
)}
4137
</a>
42-
<a className={`tab ${activeTab == 'log' ? 'tab-active' : ''}`} onClick={showLog}>
38+
<a className={`tab ${activeTab == 'log' ? 'tab-active' : ''}`} onClick={() => setActiveTab('logs')}>
4339
<DocumentTextIcon className='inline-block w-5 h-5 mr-1' /> Logs
4440
{responseStatus != 0 && (
4541
<div className="ml-1 badge badge-sm badge-info">

0 commit comments

Comments
 (0)