@digi-frontend/dgate-api-documentation 1.0.50 → 1.0.52

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 (60) hide show
  1. package/dist/_virtual/index3.js +1 -1
  2. package/dist/_virtual/index4.js +1 -1
  3. package/dist/_virtual/index5.js +1 -1
  4. package/dist/_virtual/index6.js +1 -1
  5. package/dist/node_modules/toposort/index.js +1 -1
  6. package/dist/node_modules/yup/index.esm.js +1 -1
  7. package/dist/src/components/MethodAccordion/MethodAccordion.js +1 -1
  8. package/dist/src/components/MethodAccordion/MethodAccordion.js.map +1 -1
  9. package/dist/src/helpers/docs.helper.js +1 -1
  10. package/dist/src/helpers/docs.helper.js.map +1 -1
  11. package/dist/src/helpers/layout.helper.js +1 -1
  12. package/dist/src/helpers/layout.helper.js.map +1 -1
  13. package/dist/src/layout/docsComponents/DocsAside/DocsAside.js +1 -1
  14. package/dist/src/layout/docsComponents/DocsAside/DocsAside.js.map +1 -1
  15. package/dist/src/layout/docsComponents/DocsContent/DocsContent.js +1 -1
  16. package/dist/src/layout/docsComponents/DocsContent/DocsContent.js.map +1 -1
  17. package/dist/src/layout/docsComponents/DocsContent/EndpointPage/index.js +1 -1
  18. package/dist/src/layout/docsComponents/DocsContent/EndpointPage/index.js.map +1 -1
  19. package/dist/src/layout/docsComponents/DocsContent/TagPage/index.js +1 -1
  20. package/dist/src/layout/docsComponents/DocsContent/TagPage/index.js.map +1 -1
  21. package/dist/src/layout/docsComponents/DocsHeader/DocsHeader.js +1 -1
  22. package/dist/src/layout/docsComponents/DocsHeader/DocsHeader.js.map +1 -1
  23. package/dist/src/layout/docsComponents/DocsSideMenuTree/DocsSideMenuTree.js +1 -1
  24. package/dist/src/layout/docsComponents/DocsSideMenuTree/DocsSideMenuTree.js.map +1 -1
  25. package/dist/src/layout/docsLayout.js +1 -1
  26. package/dist/src/layout/docsLayout.js.map +1 -1
  27. package/dist/src/layout/layout.js +1 -1
  28. package/dist/src/layout/layout.js.map +1 -1
  29. package/dist/src/layout/layout.module.css.js +1 -1
  30. package/dist/src/validator/form.scheme.js +1 -1
  31. package/dist/src/validator/form.scheme.js.map +1 -1
  32. package/dist/styles.css +638 -596
  33. package/dist/types/helpers/docs.helper.d.ts +2 -2
  34. package/dist/types/layout/docsComponents/DocsContent/DocsContent.d.ts +2 -1
  35. package/dist/types/layout/docsComponents/DocsContent/TagPage/index.d.ts +4 -1
  36. package/dist/types/layout/docsComponents/DocsSideMenuTree/DocsSideMenuTree.d.ts +12 -6
  37. package/dist/types/layout/docsLayout.d.ts +5 -4
  38. package/dist/types/layout/layout.d.ts +1 -1
  39. package/dist/types/types/index.d.ts +27 -0
  40. package/dist/types/types/layout.type.d.ts +1 -0
  41. package/dist/types/types/openApi.d.ts +1 -0
  42. package/dist/types/validator/form.scheme.d.ts +1 -0
  43. package/package.json +1 -2
  44. package/src/components/MethodAccordion/MethodAccordion.tsx +372 -4
  45. package/src/helpers/docs.helper.ts +17 -4
  46. package/src/helpers/layout.helper.ts +19 -2
  47. package/src/layout/docsComponents/DocsAside/DocsAside.tsx +6 -7
  48. package/src/layout/docsComponents/DocsContent/DocsContent.tsx +24 -3
  49. package/src/layout/docsComponents/DocsContent/EndpointPage/index.tsx +132 -121
  50. package/src/layout/docsComponents/DocsContent/EndpointPage/style.scss +45 -0
  51. package/src/layout/docsComponents/DocsContent/TagPage/index.tsx +49 -17
  52. package/src/layout/docsComponents/DocsHeader/DocsHeader.tsx +34 -1
  53. package/src/layout/docsComponents/DocsSideMenuTree/DocsSideMenuTree.tsx +106 -79
  54. package/src/layout/docsLayout.tsx +43 -17
  55. package/src/layout/layout.module.css +1 -1
  56. package/src/layout/layout.tsx +36 -18
  57. package/src/types/index.ts +28 -0
  58. package/src/types/layout.type.ts +1 -0
  59. package/src/types/openApi.ts +1 -0
  60. package/src/validator/form.scheme.ts +9 -1
@@ -61,8 +61,10 @@ export const transformPathsToArray = (paths: OpenAPIFile['paths']): TransformedP
61
61
  summary: methodProps.summary || '',
62
62
  responses: Object.entries(methodProps.responses).map(([code, codeProps]) => {
63
63
  const contentType = Object.keys(codeProps.content || {})[0]
64
+ const headers = !codeProps?.headers ? {} : codeProps.headers
64
65
  return {
65
66
  code,
67
+ headers,
66
68
  content: {
67
69
  contentType,
68
70
  schema: {
@@ -78,6 +80,8 @@ export const transformPathsToArray = (paths: OpenAPIFile['paths']): TransformedP
78
80
  obj.parameters = []
79
81
  }
80
82
 
83
+ // load response headers parameters
84
+
81
85
  if (method.toLowerCase() != 'get') {
82
86
  const contentType = Object.keys(methodProps?.requestBody?.content || {})[0]
83
87
  const reqSchema = methodProps?.requestBody?.content?.schema
@@ -103,7 +107,6 @@ export const transformPathsToArray = (paths: OpenAPIFile['paths']): TransformedP
103
107
 
104
108
  obj['requestBody'] = requestBodyData
105
109
  }
106
-
107
110
  return obj
108
111
  }),
109
112
  }))
@@ -112,6 +115,9 @@ export const transformPathsToArray = (paths: OpenAPIFile['paths']): TransformedP
112
115
  }
113
116
 
114
117
  const validateBodyForResponse = (content, method) => {
118
+ if (!(content?.schema as any) || !(content?.schema as any)?.properties) {
119
+ return {}
120
+ }
115
121
  let _content = JSON.parse((content?.schema as any)?.properties as string)
116
122
  // if (method == 'get') {
117
123
  // if (!_content?.body) {
@@ -132,7 +138,17 @@ export const transformPathsArrayToOrigin = (paths: TransformedPathsArray): OpenA
132
138
  ...rest,
133
139
  tags,
134
140
  summary,
135
- responses: responses.reduce((respAcc, { code, content }) => {
141
+ responses: responses.reduce((respAcc, { code, content, headers }) => {
142
+ const formattedHeaders: Record<string, any> = {}
143
+ if (headers) {
144
+ for (const [key, value] of Object.entries(headers)) {
145
+ formattedHeaders[key] = {
146
+ description: value.description || '',
147
+ required: value.required || false,
148
+ schema: value.schema || {},
149
+ }
150
+ }
151
+ }
136
152
  respAcc[code] = {
137
153
  description: 'Success', // Assuming this is static from the original data
138
154
  content: content.contentType
@@ -145,6 +161,7 @@ export const transformPathsArrayToOrigin = (paths: TransformedPathsArray): OpenA
145
161
  },
146
162
  }
147
163
  : {},
164
+ headers: formattedHeaders,
148
165
  }
149
166
  return respAcc
150
167
  }, {} as Record<string, any>),
@@ -1,12 +1,12 @@
1
1
  import React, { useState } from 'react'
2
2
  import { EndpointData } from 'src/layout/docsLayout'
3
3
  import Codebox from '../Codebox/Codebox'
4
- import { SelectGroup } from 'digitinary-ui'
4
+ import { Option, SelectGroup } from 'digitinary-ui'
5
5
  import { httpStatusCodes } from '../../../constants/index'
6
6
  import { handleStatusColor } from '../../../helpers/methodAccordion.helper'
7
7
  import styles from './style.module.scss'
8
8
 
9
- const httpStatusCodeOptions = httpStatusCodes.map((code) => ({
9
+ const httpStatusCodeOptions: Option[] = httpStatusCodes.map((code) => ({
10
10
  label: (
11
11
  <div className={styles.statusCodeOptionContainer}>
12
12
  <div
@@ -16,15 +16,14 @@ const httpStatusCodeOptions = httpStatusCodes.map((code) => ({
16
16
  <span>{code}</span>
17
17
  </div>
18
18
  ),
19
- value: code,
19
+ value: String(code),
20
20
  }))
21
21
 
22
22
  const DocsAside = ({ data }: { data: EndpointData }) => {
23
23
  const [selectedResStatusCode, setSelectedResStatusCode] = useState(httpStatusCodeOptions[4])
24
- const currentResponse =
25
- Object.entries(data.responses)
26
- .map(([code, data]) => ({ code, data }))
27
- .find((res) => Number(res.code) === selectedResStatusCode.value) || '{}'
24
+ const currentResponse = Object.entries(data.responses)
25
+ .map(([code, data]) => ({ code, data }))
26
+ .find((res) => res.code === selectedResStatusCode.value)
28
27
 
29
28
  const stringifyRequestBody = () => {
30
29
  if (data?.requestBody?.content) {
@@ -6,9 +6,30 @@ import { TagPage } from './TagPage'
6
6
  import { EndpointPage } from './EndpointPage'
7
7
  import { EndpointData, OverviewData } from 'src/layout/docsLayout'
8
8
 
9
- const DocsContent = ({ data }: { data: OverviewData | EndpointData }) => {
10
- const isTagPage = false
11
- return <main>{!isTagPage ? <TagPage data={data} /> : <EndpointPage data={data} />}</main>
9
+ const DocsContent = ({
10
+ data,
11
+ activeType,
12
+ setActiveItemData,
13
+ setActiveType,
14
+ setExpandedSections,
15
+ }: {
16
+ data: OverviewData | EndpointData
17
+ activeType: 'OVERVIEW' | 'ENDPOINT'
18
+ }) => {
19
+ return (
20
+ <main>
21
+ {activeType === 'OVERVIEW' ? (
22
+ <TagPage
23
+ data={data}
24
+ setActiveItemData={setActiveItemData}
25
+ setActiveType={setActiveType}
26
+ setExpandedSections={setExpandedSections}
27
+ />
28
+ ) : (
29
+ <EndpointPage data={data} />
30
+ )}
31
+ </main>
32
+ )
12
33
  }
13
34
 
14
35
  export default DocsContent
@@ -7,43 +7,42 @@ import {
7
7
  RequestOption,
8
8
  } from '../../../../assets/icons/index'
9
9
  import { ArrowIcon, SelectGroup } from 'digitinary-ui'
10
- import { useState } from 'react'
10
+ import { useEffect, useState } from 'react'
11
11
  import { EndpointData } from 'src/layout/docsLayout'
12
+ import { handleStatusColor } from '../../../../helpers/methodAccordion.helper'
13
+ import { httpStatusCodes } from '../../../../constants/index'
14
+ import styles from '../../Codebox/style.module.scss'
15
+ import Tooltip from '../../../../components/Tooltip/Tooltip'
12
16
 
13
17
  export const EndpointPage = ({ data }) => {
18
+ const [activeTab, setActiveTab] = useState('header')
19
+
20
+ const httpStatusCodeOptions = httpStatusCodes.map((code) => ({
21
+ label: (
22
+ <div className={'statusCodeOptionContainer'}>
23
+ <div
24
+ className={'statusCodeOptionCircle'}
25
+ style={{ backgroundColor: handleStatusColor(code) }}
26
+ ></div>
27
+ <span>{code}</span>
28
+ </div>
29
+ ),
30
+ value: code,
31
+ }))
32
+
14
33
  const [expanded, setExpanded] = useState(null)
34
+ const [selectedResStatusCode, setSelectedResStatusCode] = useState(httpStatusCodeOptions[4])
35
+ const [headersList, setHeadersList] = useState({})
36
+ const requestTableData = (data?.parameters || []).filter(
37
+ (param) => param.in?.toLowerCase() === activeTab.toLowerCase()
38
+ )
15
39
 
16
- const requestTableData = [
17
- {
18
- name: 'Parameter Name',
19
- required: 'True',
20
- type: 'String',
21
- enum: 'Active/Expired/Cancelled',
22
- description:
23
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
24
- },
25
- {
26
- name: 'Parameter Name',
27
- required: 'False',
28
- type: 'Boolean',
29
- enum: 'Active/Expired/Cancelled',
30
- description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.sssssss',
31
- },
32
- {
33
- name: 'Parameter Name',
34
- required: 'True',
35
- type: 'Object',
36
- enum: '-',
37
- description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.sssssss',
38
- },
39
- {
40
- name: 'Parameter Name',
41
- required: 'True',
42
- type: 'Array_String',
43
- enum: '-',
44
- description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.sssssss',
45
- },
46
- ]
40
+ useEffect(() => {
41
+ if (selectedResStatusCode && selectedResStatusCode.value) {
42
+ const headerObj = data?.responses[selectedResStatusCode.value]
43
+ setHeadersList(headerObj?.headers)
44
+ }
45
+ }, [selectedResStatusCode])
47
46
 
48
47
  return (
49
48
  <div className="api-details-expanded">
@@ -52,99 +51,116 @@ export const EndpointPage = ({ data }) => {
52
51
  <SVGLoader src={ArrowBack} />
53
52
  </button>
54
53
 
55
- <button className="disabled">Test</button>
54
+ <Tooltip content="Comming soon">
55
+ <button className="disabled">Test</button>
56
+ </Tooltip>
56
57
  </div>
57
58
  <h3> Api Name</h3>
58
- <h1 className="api-title">Endpoint Name</h1>
59
+ <h1 className="api-title">{data?.api?.title}</h1>
59
60
  <div className="url-box">
60
61
  <div style={{ textAlign: 'center' }}>
61
- <span className="method-label post">Post</span>
62
- <span className="url-text">https://apigw sdb-1.test.dgate.digitinary.net/test</span>
62
+ <span className={`method-label ${data?.method?.toLowerCase()}`}>{data.method}</span>
63
+ <span className="url-text">{data?.path}</span>
63
64
  </div>
64
-
65
- <SVGLoader src={CopySticker} className="copy-icon" />
65
+ <span className="icon" onClick={() => navigator.clipboard.writeText(data?.path)}>
66
+ <SVGLoader src={CopySticker} />
67
+ </span>
66
68
  </div>
67
69
 
68
- <p className="api-desc">Endpoint Description</p>
70
+ <p className="api-desc">{data?.api?.description || 'No Description'}</p>
69
71
 
70
72
  <h3>Request</h3>
71
73
 
72
74
  <div className="request-section">
73
75
  <div className="request-tabs">
74
- <button className="tab">
75
- <SVGLoader src={RequestOption} className="icon-left" />
76
- Header
77
- </button>
78
- <button className="tab">
79
- <SVGLoader src={RequestOption} className="icon-left" />
80
- Path
81
- </button>
82
- <button className="tab">
83
- <SVGLoader src={RequestOption} className="icon-left" />
84
- Query
85
- </button>
86
- <button className="tab">
87
- <SVGLoader src={RequestOption} className="icon-left" />
88
- Request Body
89
- </button>
76
+ {['header', 'path', 'query', 'Body'].map((tab) => (
77
+ <button
78
+ key={tab}
79
+ className={`tab ${activeTab === tab ? 'active' : ''}`}
80
+ onClick={() => setActiveTab(tab)}
81
+ >
82
+ <SVGLoader src={RequestOption} className="icon-left" />
83
+ <span className="tab-label">
84
+ {tab === 'requestBody'
85
+ ? 'Request Body'
86
+ : tab.charAt(0).toUpperCase() + tab.slice(1)}
87
+ </span>
88
+ </button>
89
+ ))}
90
90
  </div>
91
- <div className="table-wrapper">
92
- <table className="param-table">
93
- <thead>
94
- <tr>
95
- <th className="head-table-label">Parameter Name</th>
96
- <th className="head-table-label">Required</th>
97
- <th className="head-table-label">Type</th>
98
- <th className="head-table-label">Enum</th>
99
- <th className="head-table-label">Description</th>
100
- </tr>
101
- </thead>
102
- <tbody>
103
- {requestTableData.map((row, index) => (
104
- <tr key={index}>
105
- <td>{row.name}</td>
106
- <td>{row.required}</td>
107
- <td>{row.type}</td>
108
- <td>{row.enum}</td>
109
- <td className="desc-cell">
110
- <div className={`desc-text ${expanded === index ? 'expanded' : ''}`}>
111
- {row.description}
112
- </div>
113
- <button
114
- className="desc-toggle"
115
- onClick={() => setExpanded(expanded === index ? null : index)}
116
- >
117
- <SVGLoader
118
- src={DownArrowIcon}
119
- className={expanded === index ? 'rotated' : ''}
120
- />
121
- </button>
122
- </td>
91
+
92
+ {
93
+ <div className="table-wrapper">
94
+ <table className="param-table">
95
+ <thead>
96
+ <tr>
97
+ <th className="head-table-label">Parameter Name</th>
98
+ <th className="head-table-label">Required</th>
99
+ <th className="head-table-label">Type</th>
100
+ <th className="head-table-label">Enum</th>
101
+ <th className="head-table-label">Description</th>
123
102
  </tr>
124
- ))}
125
- </tbody>
126
- </table>
127
- </div>
103
+ </thead>
104
+ <tbody>
105
+ {data.parameters
106
+ ?.filter((p) => p.in?.toLowerCase() === activeTab.toLowerCase())
107
+ .map((row, index) => (
108
+ <tr key={index}>
109
+ <td>{row.name}</td>
110
+ <td>{row.required ? 'True' : 'False'}</td>
111
+ <td>{row.schema?.type || '-'}</td>
112
+ <td>{Array.isArray(row.schema?.enum) ? row.schema.enum.join(' / ') : '-'}</td>
113
+ <td className="desc-cell">
114
+ <div className={`desc-text ${expanded === index ? 'expanded' : ''}`}>
115
+ {row.description || 'No description'}
116
+ </div>
117
+ <button
118
+ className="desc-toggle"
119
+ onClick={() => setExpanded(expanded === index ? null : index)}
120
+ >
121
+ <SVGLoader
122
+ src={DownArrowIcon}
123
+ className={expanded === index ? 'rotated' : ''}
124
+ />
125
+ </button>
126
+ </td>
127
+ </tr>
128
+ ))}
129
+ </tbody>
130
+ </table>
131
+ </div>
132
+ }
128
133
  </div>
129
134
 
130
135
  <div className="response-section">
131
- <div className="response-drop-test">
132
- <SelectGroup
133
- className="response-drop"
134
- withSearch={false}
135
- isMultiple={false}
136
- clearable={false}
137
- placeholder="200"
138
- options={[]}
139
- //value={selectedStatusCode}
140
- onChange={(value) => {
141
- // setSelectedStatusCode(value)
142
- }}
143
- />
136
+ <h3>Response</h3>
137
+
138
+ <div style={{ width: '7.5rem', marginLeft: 'auto' }}>
139
+ {Object.keys(data?.responses || {})?.length > 0 && (
140
+ <div className={styles.codeboxSection}>
141
+ <div className={`${styles.codeboxHeader}`}>
142
+ <SelectGroup
143
+ size="small"
144
+ withSearch={false}
145
+ isMultiple={false}
146
+ clearable={false}
147
+ placeholder="200"
148
+ options={[
149
+ {
150
+ list: httpStatusCodeOptions,
151
+ },
152
+ ]}
153
+ value={selectedResStatusCode}
154
+ onChange={(value) => {
155
+ setSelectedResStatusCode(value)
156
+ }}
157
+ />
158
+ </div>
159
+ </div>
160
+ )}
144
161
  </div>
145
162
 
146
- <h3>Response</h3>
147
- <button className="tab">
163
+ <button className="tab active ">
148
164
  <SVGLoader src={RequestOption} className="icon-left" />
149
165
  Header
150
166
  </button>
@@ -153,7 +169,7 @@ export const EndpointPage = ({ data }) => {
153
169
  <table className="param-table">
154
170
  <thead>
155
171
  <tr>
156
- <th className="head-table-label">Parameter Name</th>
172
+ <th className="head-table-label">Header Name</th>
157
173
  <th className="head-table-label">Required</th>
158
174
  <th className="head-table-label">Type</th>
159
175
  <th className="head-table-label">Enum</th>
@@ -161,20 +177,15 @@ export const EndpointPage = ({ data }) => {
161
177
  </tr>
162
178
  </thead>
163
179
  <tbody>
164
- <tr>
165
- <td>Parameter Name</td>
166
- <td>True</td>
167
- <td>String</td>
168
- <td>Active/Expired/Cancelled</td>
169
- <td>Borem taciti dolor ...</td>
170
- </tr>
171
- <tr>
172
- <td>Parameter Name</td>
173
- <td>True</td>
174
- <td>Array_Object</td>
175
- <td>-</td>
176
- <td>Borem taciti dolor ...</td>
177
- </tr>
180
+ {Object.keys(headersList).map((key, index) => (
181
+ <tr>
182
+ <td>{key}</td>
183
+ <td>{headersList[key]?.required.toString()}</td>
184
+ <td>{headersList[key]?.schema?.type}</td>
185
+ <td>{headersList[key]?.schema?.enum?.join('/')}</td>
186
+ <td>{headersList[key]?.description}</td>
187
+ </tr>
188
+ ))}
178
189
  </tbody>
179
190
  </table>
180
191
  </div>
@@ -62,6 +62,7 @@ main {
62
62
  font-weight: 400;
63
63
  letter-spacing: 0px;
64
64
  line-height: 1.5rem;
65
+ margin-top: 1.5rem;
65
66
  margin-bottom: 0.5rem;
66
67
  }
67
68
 
@@ -86,6 +87,31 @@ main {
86
87
  text-transform: uppercase;
87
88
  color: #3aaa35;
88
89
  text-decoration: underline;
90
+
91
+ &.get {
92
+ color: #3a6cd1;
93
+ }
94
+ &.post {
95
+ color: #3aaa35;
96
+ }
97
+ &.put {
98
+ color: #faad14;
99
+ }
100
+ &.patch {
101
+ color: #58e2c2;
102
+ }
103
+ &.delete {
104
+ color: #da3f3f;
105
+ }
106
+ &.head {
107
+ color: #9461c9;
108
+ }
109
+ &.trace {
110
+ color: #ffa28f;
111
+ }
112
+ &.options {
113
+ color: #495d97;
114
+ }
89
115
  }
90
116
 
91
117
  .url-box {
@@ -127,13 +153,31 @@ main {
127
153
  cursor: pointer;
128
154
  font-size: 0.875rem;
129
155
  color: #000000;
156
+ display: flex;
157
+ align-items: center;
158
+ gap: 0.375rem;
130
159
  }
131
160
 
132
161
  .tab {
162
+ background: white;
163
+ border: 1px solid #d1d3d8;
164
+ padding: 0.375rem 0.75rem;
165
+ border-radius: 6px;
166
+ cursor: pointer;
167
+ font-size: 0.875rem;
168
+ color: #000000;
133
169
  display: flex;
134
170
  align-items: center;
135
171
  gap: 0.375rem;
172
+
173
+ &.active {
174
+ background-color: #e5edff;
175
+ border-color: #4d75d9;
176
+ color: #000000;
177
+ font-weight: 400;
178
+ }
136
179
  }
180
+
137
181
  .icon-left {
138
182
  width: 0.875rem;
139
183
  height: 0.875rem;
@@ -145,6 +189,7 @@ main {
145
189
  border-radius: 0.8rem;
146
190
  background: white;
147
191
  border: 1px #bbbec5 solid;
192
+ margin-bottom: 2rem;
148
193
  }
149
194
 
150
195
  .param-table {
@@ -3,23 +3,49 @@ import SVGLoader from '../../../../components/SVGLoader/SVGLoader'
3
3
  import { arrowRightGray, CopySticker } from '../../../../assets/icons/index'
4
4
  import { OverviewData } from 'src/layout/docsLayout'
5
5
 
6
- export const TagPage = ({ data }) => {
6
+ export const TagPage = ({ data, setActiveItemData, setActiveType, setExpandedSections }) => {
7
+ const handleClick = (endpoint) => {
8
+ setActiveItemData({
9
+ ...endpoint,
10
+ api: {
11
+ id: data.apiSpecId,
12
+ title: data.title,
13
+ description: data.description,
14
+ version: data.version,
15
+ ...data,
16
+ },
17
+ })
18
+ setActiveType('ENDPOINT')
19
+
20
+ setExpandedSections((prev) => ({
21
+ ...prev,
22
+ [`api-${data.apiSpecId}-section`]: true,
23
+ [`api-${data.apiSpecId}-endpoints`]: true,
24
+ [`api-${data.apiSpecId}-resource-${endpoint.id}`]: true,
25
+ }))
26
+ }
7
27
  return (
8
28
  <div className="api-details-page">
9
29
  <h2 className="welcome">Welcome to</h2>
10
- <h1 className="api-title">{data.title}</h1>
30
+ <h1 className="api-title">{data?.title}</h1>
11
31
  <p className="api-version">
12
- API Version: <span>{data.version}</span>
32
+ API Version: <span>{data?.version}</span>
13
33
  </p>
14
34
 
15
35
  <div className="custom-url-input">
16
36
  <label className="input-label">API Base URL</label>
17
37
  <div className="input-wrapper">
18
- <input type="text" value="https://apigw-sdb-1.test.dgate.digitinary.net/test" readOnly />
38
+ <input
39
+ type="text"
40
+ value={!!data && !!data.servers && data.servers.length > 0 ? data.servers[0]?.url : '-'}
41
+ readOnly
42
+ />
19
43
  <span
20
44
  className="icon"
21
45
  onClick={() =>
22
- navigator.clipboard.writeText('https://apigw-sdb-1.test.dgate.digitinary.net/test')
46
+ navigator.clipboard.writeText(
47
+ `${!!data && !!data.servers && data.servers.length > 0 ? data.servers[0]?.url : '-'}`
48
+ )
23
49
  }
24
50
  >
25
51
  <SVGLoader src={CopySticker} />
@@ -29,17 +55,21 @@ export const TagPage = ({ data }) => {
29
55
 
30
56
  <p className="api-desc">API Description</p>
31
57
  <div className="api-product-tag">
32
- Product with this API <span className="product-tag">Product 01</span>
58
+ Product with this API <span className="product-tag">{data.associatedProduct.name}</span>
33
59
  </div>
34
60
 
35
61
  <h3 className="section-title">Endpoints</h3>
36
62
 
37
- {Object.entries(data.tags).map(([tag, endpoints]) => (
63
+ {Object.entries(data?.tags).map(([tag, endpoints]) => (
38
64
  <div className="endpoint-group" key={tag}>
39
65
  <h4 className="tag-title">{tag}</h4>
40
66
  <div className="endpoint-list">
41
67
  {endpoints.map((endpoint, idx) => (
42
- <div className="endpoint-card" key={`${tag}-${idx}`}>
68
+ <div
69
+ className="endpoint-card"
70
+ onClick={() => handleClick(endpoint)}
71
+ key={`${tag}-${idx}`}
72
+ >
43
73
  <div>
44
74
  <div className="endpoint-card-header">
45
75
  <span className={`method-label ${endpoint.method.toLowerCase()}`}>
@@ -67,16 +97,18 @@ export const TagPage = ({ data }) => {
67
97
  </div>
68
98
  ))}
69
99
 
70
- <div className="versions-section">
71
- <h4>API Versions</h4>
72
- <div className="version-list">
73
- {['1.2.0', '1.3.0', '1.4.0', '1.5.0', '2.2.0'].map((ver) => (
74
- <button key={ver} className="version-btn">
75
- {ver}
76
- </button>
77
- ))}
100
+ {data.apiVersions?.length > 0 && (
101
+ <div className="versions-section">
102
+ <h4>API Versions</h4>
103
+ <div className="version-list">
104
+ {data.apiVersions.map((verObj, index) => (
105
+ <button key={index} className="version-btn">
106
+ {verObj.metaData?.version || 'N/A'}
107
+ </button>
108
+ ))}
109
+ </div>
78
110
  </div>
79
- </div>
111
+ )}
80
112
  </div>
81
113
  )
82
114
  }
@@ -15,7 +15,13 @@ import CommonDialog from '../../../components/dialog/index'
15
15
  import { METHOD_OPTIONS } from '../../../constants/methods.constant'
16
16
  import styles from './DocsHeader.module.scss'
17
17
 
18
- const DocsHeader: React.FC = () => {
18
+ const DocsHeader: React.FC = ({
19
+ transformedOpenApis,
20
+ updateFilteredData,
21
+ }: {
22
+ transformedOpenApis: any[]
23
+ updateFilteredData: any
24
+ }) => {
19
25
  const [showSearchFilter, setShowSearchFilter] = useState<boolean>(false)
20
26
  const [apiName, setApiName] = useState<string>('')
21
27
  const [selectedMethods, setSelectedMethods] = useState<any[]>([])
@@ -33,6 +39,33 @@ const DocsHeader: React.FC = () => {
33
39
  }
34
40
 
35
41
  const handleApplyFilters = (): void => {
42
+ // Reset: no filters applied
43
+ if (!apiName?.trim() && (!selectedMethods || selectedMethods.length === 0)) {
44
+ updateFilteredData(transformedOpenApis, true)
45
+ setShowSearchFilter(false)
46
+ return
47
+ }
48
+
49
+ let filteredItems = [...transformedOpenApis]
50
+
51
+ // Filter by API name
52
+ if (apiName?.trim()) {
53
+ const lowerApiName = apiName.toLowerCase()
54
+ filteredItems = filteredItems.filter((api) => api.title.toLowerCase().includes(lowerApiName))
55
+ }
56
+
57
+ // Filter by selected HTTP methods
58
+ if (selectedMethods?.length) {
59
+ filteredItems = filteredItems.filter((api) => {
60
+ const allMethods = Object.values(api.tags || {})
61
+ .flat()
62
+ .map((endpoint: any) => endpoint.method?.toLowerCase())
63
+
64
+ return selectedMethods.some((method) => allMethods.includes(method.toLowerCase()))
65
+ })
66
+ }
67
+
68
+ updateFilteredData(filteredItems)
36
69
  setShowSearchFilter(false)
37
70
  }
38
71