Skip to content

Commit c48523c

Browse files
frontend path parameters
1 parent 8e8aa8e commit c48523c

File tree

3 files changed

+195
-148
lines changed

3 files changed

+195
-148
lines changed

ui/src/components/ApiInfo.tsx

Lines changed: 28 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ 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 ApiInfoRules from './elements/ApiInfoRules'
56
import { ChevronRightIcon, LinkIcon, EnvelopeIcon } from '@heroicons/react/24/outline'
67

78
interface Props {
@@ -28,66 +29,6 @@ export default function ApiInfo(props: Props) {
2829
setHasFile(files.length > 0)
2930
}, [])
3031

31-
const StyledRule = (theRule: any): JSX.Element => {
32-
theRule = theRule.rule
33-
const split = theRule.split(':')
34-
35-
if (theRule == 'url') {
36-
return (
37-
<div className="block">
38-
<LinkIcon className='inline-block w-4 h-4' /> {theRule}
39-
</div>
40-
)
41-
}
42-
if (theRule == 'email') {
43-
return (
44-
<div className="block">
45-
<EnvelopeIcon className='inline-block w-4 h-4' /> {theRule}
46-
</div>
47-
)
48-
}
49-
50-
if (split.length < 2) {
51-
return (
52-
<div className='' dangerouslySetInnerHTML={{ __html: explode(theRule, 50, "<br/>") }} />
53-
)
54-
}
55-
56-
const keyPart = split[0]
57-
const valuePart = split.slice(1).join(' ')
58-
if (keyPart == 'max') {
59-
return (
60-
<div className="block badge badge-primary badge-outline mt-1 mb-1 rounded-sm">{`<= ${valuePart}`}</div>
61-
)
62-
}
63-
if (keyPart == 'min') {
64-
return (
65-
<div className="block badge badge-primary badge-outline mt-1 mb-1 rounded-sm">{`>= ${valuePart}`}</div>
66-
)
67-
}
68-
if (keyPart == 'date_format') {
69-
return (
70-
<div className="block badge badge-info badge-outline mt-1 mb-1 rounded-sm">
71-
{`Format: ${valuePart}`}
72-
</div>
73-
)
74-
}
75-
if (keyPart == 'regex') {
76-
return (
77-
<>
78-
<div className="inline-block badge badge-info badge-outline mt-1 mb-1 mr-2 rounded-sm">
79-
Regexp
80-
</div>
81-
<code>${valuePart}</code>
82-
</>
83-
)
84-
}
85-
86-
return (
87-
<div className='' dangerouslySetInnerHTML={{ __html: explode(theRule, 50, "<br/>") }} />
88-
)
89-
}
90-
9132
return (
9233
<>
9334
<h2 className='text-lg' id={method + lrdDocsItem.uri}>
@@ -96,105 +37,44 @@ export default function ApiInfo(props: Props) {
9637
</h2>
9738
<h3 className='pt-4'>
9839
<span className='text-sm text-slate-500'>REQUEST SCHEMA</span>
99-
<code className='pl-2 text-xs'>
40+
<br />
41+
<code className='text-xs'>
10042
{hasFile ? (
10143
'multipart/form-data'
10244
) : (
10345
'application/json'
10446
)}
10547
</code>
10648
</h3>
49+
{(Object.keys(lrdDocsItem.path_parameters).length > 0) && (
50+
<h3 className='pt-4'>
51+
<span className='text-sm text-slate-500'>
52+
PATH PARAMETERS
53+
</span>
54+
{(Object.keys(lrdDocsItem.path_parameters).map((rule) => (
55+
<div key={shortid.generate()}>
56+
<ApiInfoRules key={shortid.generate()} mainRule={rule} lrdDocsItem={ lrdDocsItem } />
57+
</div>
58+
)))}
59+
</h3>
60+
)}
61+
62+
<h3 className='pt-4'>
63+
<span className='text-sm text-slate-500'>
64+
{(method == 'POST' || method == 'PUT' || method == 'PATCH') ? 'REQUEST BODY PARAMETERS' : 'QUERY PARAMETERS'}
65+
</span>
66+
{(lrdDocsItem.rules && Object.keys(lrdDocsItem.rules).length == 0) && (
67+
<div className='text-sm text-slate-500'>
68+
No Rules Defined
69+
</div>
70+
)}
71+
</h3>
10772
<div className='pt-4'>
10873

10974
<table className="table table-fixed table-compact w-full">
11075
<tbody>
111-
{lrdDocsItem.rules && Object.keys(lrdDocsItem.rules).map((key) => (
112-
113-
<tr key={shortid.generate()}>
114-
<th className='param-cell'>
115-
<span className='text-blue-500 pr-1'>¬</span>
116-
<code className='pl-1'>
117-
{key}
118-
{(key.endsWith(".*")) ? (
119-
<ChevronRightIcon key={shortid.generate()} className='inline-block w-4 h-4' />
120-
) : (<span key={shortid.generate()}></span>)}
121-
</code>
122-
{lrdDocsItem.rules[key].map((rule) => (
123-
rule.split('|').map((theRule) => (
124-
(theRule == "file" || theRule == "image") ? (
125-
<div key={shortid.generate()} className="block badge badge-success badge-outline ml-4 mt-1 mb-1 rounded-sm title">{theRule}</div>
126-
) : (<span key={shortid.generate()}></span>)
127-
))
128-
))}
129-
{lrdDocsItem.rules[key].map((rule) => (
130-
rule.split('|').map((theRule) => (
131-
(theRule == "required") ? (
132-
<div className='block ml-6' key={shortid.generate()}>
133-
<code className='text-error font-normal'>{theRule}</code>
134-
</div>
135-
) : (<span key={shortid.generate()}></span>)
136-
))
137-
))}
138-
{lrdDocsItem.rules[key].map((rule) => (
139-
rule.split('|').map((theRule) => (
140-
(theRule.startsWith("required_if")) ? (
141-
<div className='block ml-6' key={shortid.generate()}>
142-
<code className='text-red-300 font-normal'>required_if</code>
143-
</div>
144-
) : (<span key={shortid.generate()}></span>)
145-
))
146-
))}
147-
</th>
148-
<td>
149-
{lrdDocsItem.rules[key].map((rule) => (
150-
rule.split('|').map((theRule) => {
151-
if (theRule == "required") {
152-
return (<span key={shortid.generate()}></span>)
153-
}
154-
if (theRule == "integer"
155-
|| theRule == "string"
156-
|| theRule == "bool"
157-
|| theRule == "date"
158-
|| theRule == "file"
159-
|| theRule == "image"
160-
|| theRule == "array"
161-
|| theRule == "nullable") {
162-
return (
163-
<div key={shortid.generate()} className='capitalize text-slate-500'>
164-
{theRule}
165-
</div>)
166-
}
167-
return (<span key={shortid.generate()}></span>)
168-
})
169-
))}
170-
{lrdDocsItem.rules[key].map((rule) => (
171-
rule.split('|').map((theRule) => {
172-
if (theRule == "required") {
173-
return (<span key={shortid.generate()}></span>)
174-
}
175-
return (<span key={shortid.generate()}></span>)
176-
})
177-
))}
178-
{lrdDocsItem.rules[key].map((rule) => (
179-
rule.split('|').map((theRule) => {
180-
if (theRule == "required"
181-
|| theRule == "integer"
182-
|| theRule == "string"
183-
|| theRule == "bool"
184-
|| theRule == "date"
185-
|| theRule == "file"
186-
|| theRule == "image"
187-
|| theRule == "array"
188-
|| theRule == "nullable") {
189-
return (<span key={shortid.generate()}></span>)
190-
}
191-
return (<span key={shortid.generate()}>
192-
<StyledRule rule={theRule} />
193-
</span>)
194-
})
195-
))}
196-
</td>
197-
</tr>
76+
{lrdDocsItem.rules && Object.keys(lrdDocsItem.rules).map((rule) => (
77+
<ApiInfoRules key={shortid.generate()} mainRule={rule} lrdDocsItem={lrdDocsItem} />
19878
))}
19979
</tbody>
20080
</table>
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import React from 'react';
2+
import { explode } from '../../libs/strings'
3+
import shortid from 'shortid';
4+
import type { IAPIInfo } from '../../libs/types'
5+
import { ChevronRightIcon, LinkIcon, EnvelopeIcon } from '@heroicons/react/24/outline'
6+
7+
interface Props {
8+
lrdDocsItem: any,
9+
mainRule: string,
10+
}
11+
12+
export default function ApiInfoRules(props: Props) {
13+
const { lrdDocsItem, mainRule } = props
14+
const StyledRule = (rule: any): JSX.Element => {
15+
const theRule = rule.rule
16+
const split = theRule.split(':')
17+
18+
if (theRule == 'url') {
19+
return (
20+
<div className="block">
21+
<LinkIcon className='inline-block w-4 h-4' /> {theRule}
22+
</div>
23+
)
24+
}
25+
if (theRule == 'email') {
26+
return (
27+
<div className="block">
28+
<EnvelopeIcon className='inline-block w-4 h-4' /> {theRule}
29+
</div>
30+
)
31+
}
32+
33+
if (split.length < 2) {
34+
return (
35+
<div className='' dangerouslySetInnerHTML={{ __html: explode(theRule, 50, "<br/>") }} />
36+
)
37+
}
38+
39+
const keyPart = split[0]
40+
const valuePart = split.slice(1).join(' ')
41+
if (keyPart == 'max') {
42+
return (
43+
<div className="block badge badge-primary badge-outline mt-1 mb-1 rounded-sm">{`<= ${valuePart}`}</div>
44+
)
45+
}
46+
if (keyPart == 'min') {
47+
return (
48+
<div className="block badge badge-primary badge-outline mt-1 mb-1 rounded-sm">{`>= ${valuePart}`}</div>
49+
)
50+
}
51+
if (keyPart == 'date_format') {
52+
return (
53+
<div className="block badge badge-info badge-outline mt-1 mb-1 rounded-sm">
54+
{`Format: ${valuePart}`}
55+
</div>
56+
)
57+
}
58+
if (keyPart == 'regex') {
59+
return (
60+
<>
61+
<div className="inline-block badge badge-info badge-outline mt-1 mb-1 mr-2 rounded-sm">
62+
Regexp
63+
</div>
64+
<code>${valuePart}</code>
65+
</>
66+
)
67+
}
68+
69+
return (
70+
<div className='' dangerouslySetInnerHTML={{ __html: explode(theRule, 50, "<br/>") }} />
71+
)
72+
}
73+
74+
75+
return (
76+
<>
77+
<tr>
78+
<th className='param-cell'>
79+
<span className='text-blue-500 pr-1'>¬</span>
80+
<code className='pl-1'>
81+
{mainRule}
82+
{(mainRule.endsWith(".*")) ? (
83+
<ChevronRightIcon key={shortid.generate()} className='inline-block w-4 h-4' />
84+
) : (<span key={shortid.generate()}></span>)}
85+
</code>
86+
{lrdDocsItem.rules[mainRule].map((rule) => (
87+
rule.split('|').map((theRule) => (
88+
(theRule == "file" || theRule == "image") ? (
89+
<div key={shortid.generate()} className="block badge badge-success badge-outline ml-4 mt-1 mb-1 rounded-sm title">{theRule}</div>
90+
) : (<span key={shortid.generate()}></span>)
91+
))
92+
))}
93+
{lrdDocsItem.rules[mainRule].map((rule) => (
94+
rule.split('|').map((theRule) => (
95+
(theRule == "required") ? (
96+
<div className='block ml-6' key={shortid.generate()}>
97+
<code className='text-error font-normal'>{theRule}</code>
98+
</div>
99+
) : (<span key={shortid.generate()}></span>)
100+
))
101+
))}
102+
{lrdDocsItem.rules[mainRule].map((rule) => (
103+
rule.split('|').map((theRule) => (
104+
(theRule.startsWith("required_if")) ? (
105+
<div className='block ml-6' key={shortid.generate()}>
106+
<code className='text-red-300 font-normal'>required_if</code>
107+
</div>
108+
) : (<span key={shortid.generate()}></span>)
109+
))
110+
))}
111+
</th>
112+
<td>
113+
{lrdDocsItem.rules[mainRule].map((rule) => (
114+
rule.split('|').map((theRule) => {
115+
if (theRule == "required") {
116+
return (<span key={shortid.generate()}></span>)
117+
}
118+
if (theRule == "integer"
119+
|| theRule == "string"
120+
|| theRule == "bool"
121+
|| theRule == "date"
122+
|| theRule == "file"
123+
|| theRule == "image"
124+
|| theRule == "array"
125+
|| theRule == "nullable") {
126+
return (
127+
<div key={shortid.generate()} className='capitalize text-slate-500'>
128+
{theRule}
129+
</div>)
130+
}
131+
return (<span key={shortid.generate()}></span>)
132+
})
133+
))}
134+
{lrdDocsItem.rules[mainRule].map((rule) => (
135+
rule.split('|').map((theRule) => {
136+
if (theRule == "required") {
137+
return (<span key={shortid.generate()}></span>)
138+
}
139+
return (<span key={shortid.generate()}></span>)
140+
})
141+
))}
142+
{lrdDocsItem.rules[mainRule].map((rule) => (
143+
rule.split('|').map((theRule) => {
144+
if (theRule == "required"
145+
|| theRule == "integer"
146+
|| theRule == "string"
147+
|| theRule == "bool"
148+
|| theRule == "date"
149+
|| theRule == "file"
150+
|| theRule == "image"
151+
|| theRule == "array"
152+
|| theRule == "nullable") {
153+
return (<span key={shortid.generate()}></span>)
154+
}
155+
return (<span key={shortid.generate()}>
156+
<StyledRule rule={theRule} />
157+
</span>)
158+
})
159+
))}
160+
</td>
161+
</tr>
162+
163+
</>
164+
)
165+
}

ui/src/libs/types.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ export interface IAPIInfo {
1010
method: string;
1111
http_method: string;
1212
rules: IAPIRule;
13+
path_parameters: IAPIRule;
1314
doc_block: string;
1415
group: string;
1516
group_index: number;
1617
responses: string[];
18+
1719
}
1820

1921
export interface LRDResponse {

0 commit comments

Comments
 (0)