@digi-frontend/dgate-api-documentation 1.0.53 → 1.0.55

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 (31) 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/node_modules/toposort/index.js +1 -1
  5. package/dist/node_modules/yup/index.esm.js +1 -1
  6. package/dist/src/components/MethodAccordion/MethodAccordion.js +1 -1
  7. package/dist/src/components/MethodAccordion/MethodAccordion.js.map +1 -1
  8. package/dist/src/helpers/docs.helper.js.map +1 -1
  9. package/dist/src/layout/docsComponents/DocsContent/DocsContent.js.map +1 -1
  10. package/dist/src/layout/docsComponents/DocsContent/EndpointPage/index.js.map +1 -1
  11. package/dist/src/layout/docsComponents/DocsContent/TagPage/index.js +1 -1
  12. package/dist/src/layout/docsComponents/DocsContent/TagPage/index.js.map +1 -1
  13. package/dist/src/layout/docsComponents/DocsSideMenuTree/DocsSideMenuTree.js +1 -1
  14. package/dist/src/layout/docsComponents/DocsSideMenuTree/DocsSideMenuTree.js.map +1 -1
  15. package/dist/src/layout/docsLayout.js +1 -1
  16. package/dist/src/layout/docsLayout.js.map +1 -1
  17. package/dist/styles.css +482 -482
  18. package/dist/types/layout/docsComponents/DocsContent/DocsContent.d.ts +5 -0
  19. package/dist/types/layout/docsComponents/DocsContent/EndpointPage/index.d.ts +2 -1
  20. package/dist/types/layout/docsComponents/DocsContent/TagPage/index.d.ts +6 -5
  21. package/dist/types/layout/docsComponents/DocsSideMenuTree/DocsSideMenuTree.d.ts +4 -2
  22. package/dist/types/layout/docsLayout.d.ts +4 -3
  23. package/package.json +3 -1
  24. package/rollup.config.js +2 -2
  25. package/src/components/MethodAccordion/MethodAccordion.tsx +5 -3
  26. package/src/helpers/docs.helper.ts +1 -0
  27. package/src/layout/docsComponents/DocsContent/DocsContent.tsx +6 -4
  28. package/src/layout/docsComponents/DocsContent/EndpointPage/index.tsx +13 -11
  29. package/src/layout/docsComponents/DocsContent/TagPage/index.tsx +58 -4
  30. package/src/layout/docsComponents/DocsSideMenuTree/DocsSideMenuTree.tsx +11 -33
  31. package/src/layout/docsLayout.tsx +99 -21
@@ -1,7 +1,12 @@
1
+ import React from 'react';
1
2
  import './style.scss';
2
3
  import { EndpointData, OverviewData } from 'src/layout/docsLayout';
3
4
  declare const DocsContent: ({ data, activeType, setActiveItemData, setActiveType, setExpandedSections, }: {
4
5
  data: OverviewData | EndpointData;
5
6
  activeType: "OVERVIEW" | "ENDPOINT";
7
+ setActiveItemData: React.Dispatch<React.SetStateAction<OverviewData | EndpointData>>;
8
+ setActiveType: React.Dispatch<React.SetStateAction<"OVERVIEW" | "ENDPOINT">>;
9
+ setExpandedSections: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
10
+ toggleSection: (apiId: string, sectionId: string, resetOthers?: boolean, key?: string[]) => void;
6
11
  }) => import("react/jsx-runtime").JSX.Element;
7
12
  export default DocsContent;
@@ -1,4 +1,5 @@
1
1
  import './style.scss';
2
+ import { EndpointData } from 'src/layout/docsLayout';
2
3
  export declare const EndpointPage: ({ data }: {
3
- data: any;
4
+ data: EndpointData;
4
5
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,8 @@
1
1
  import './style.scss';
2
- export declare const TagPage: ({ data, setActiveItemData, setActiveType, setExpandedSections }: {
3
- data: any;
4
- setActiveItemData: any;
5
- setActiveType: any;
6
- setExpandedSections: any;
2
+ import { EndpointData, OverviewData } from 'src/layout/docsLayout';
3
+ export declare const TagPage: ({ data, setActiveItemData, setActiveType, setExpandedSections, }: {
4
+ data: OverviewData;
5
+ setActiveItemData: React.Dispatch<React.SetStateAction<OverviewData | EndpointData>>;
6
+ setActiveType: React.Dispatch<React.SetStateAction<"OVERVIEW" | "ENDPOINT">>;
7
+ setExpandedSections: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
7
8
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,15 +1,17 @@
1
1
  import './style.scss';
2
2
  import React from 'react';
3
3
  import { EndpointData, OverviewData } from 'src/layout/docsLayout';
4
- declare const DocsSideMenuTree: ({ apis, setActiveItemData, activeItemData, activeType, expandedSections, setExpandedSections, isFirstApiExpanded, setIsFirstApiExpanded, setActiveType, }: {
4
+ declare const DocsSideMenuTree: ({ apis, setActiveItemData, activeItemData, activeType, expandedSections, setExpandedSections, isFirstApiExpanded, setIsFirstApiExpanded, setActiveType, toggleSection, canSelectFirstApi, }: {
5
5
  apis: OverviewData[];
6
6
  setActiveItemData: React.Dispatch<React.SetStateAction<OverviewData | EndpointData>>;
7
7
  activeItemData: OverviewData | EndpointData;
8
8
  expandedSections: Record<string, boolean>;
9
- setExpandedSections: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
9
+ setExpandedSections: (newSections: Record<string, boolean>) => void;
10
10
  isFirstApiExpanded: boolean;
11
11
  setIsFirstApiExpanded: React.Dispatch<React.SetStateAction<boolean>>;
12
12
  setActiveType: React.Dispatch<React.SetStateAction<"OVERVIEW" | "ENDPOINT">>;
13
13
  activeType: "OVERVIEW" | "ENDPOINT";
14
+ toggleSection: (apiId: string, sectionId: string, resetOthers?: boolean, key?: string[]) => void;
15
+ canSelectFirstApi?: boolean;
14
16
  }) => import("react/jsx-runtime").JSX.Element;
15
17
  export default DocsSideMenuTree;
@@ -1,8 +1,9 @@
1
- import { JSX } from 'react';
1
+ import React, { JSX } from 'react';
2
2
  import { HTTPMethod, OpenAPIFile, Parameter, RequestBody, Responses } from '@entities/openApi';
3
3
  import { ApiSpecModel } from '@entities/index';
4
4
  interface ILayoutProps {
5
5
  apis?: ApiSpecModel[];
6
+ activeApiId?: string;
6
7
  }
7
8
  export interface TagData {
8
9
  id: string;
@@ -30,5 +31,5 @@ export interface OverviewData extends Omit<ApiSpecModel, 'metaData'> {
30
31
  tags: Record<string, TagData[]>;
31
32
  servers: OpenAPIFile['servers'];
32
33
  }
33
- declare const DocsLayout: ({ apis }: ILayoutProps) => JSX.Element;
34
- export default DocsLayout;
34
+ declare const _default: React.MemoExoticComponent<({ apis, activeApiId }: ILayoutProps) => JSX.Element>;
35
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digi-frontend/dgate-api-documentation",
3
- "version": "1.0.53",
3
+ "version": "1.0.55",
4
4
  "main": "dist/src/index.js",
5
5
  "module": "dist/src/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -17,6 +17,7 @@
17
17
  "description": "",
18
18
  "dependencies": {
19
19
  "digitinary-ui": "1.0.166",
20
+ "fast-json-stable-stringify": "^2.1.0",
20
21
  "formik": "^2.4.6",
21
22
  "html-react-parser": "^5.2.2",
22
23
  "js-yaml": "^4.1.0",
@@ -29,6 +30,7 @@
29
30
  },
30
31
  "devDependencies": {
31
32
  "@rollup/plugin-commonjs": "^28.0.2",
33
+ "@rollup/plugin-json": "^6.1.0",
32
34
  "@rollup/plugin-node-resolve": "^16.0.0",
33
35
  "@rollup/plugin-typescript": "^12.1.2",
34
36
  "@rollup/plugin-url": "^8.0.2",
package/rollup.config.js CHANGED
@@ -5,7 +5,7 @@ import postcss from 'rollup-plugin-postcss'
5
5
  import { terser } from 'rollup-plugin-terser'
6
6
  import url from '@rollup/plugin-url'
7
7
  import sass from 'rollup-plugin-sass'
8
- import json from '@rollup/plugin-json';
8
+ import json from '@rollup/plugin-json'
9
9
 
10
10
  export default {
11
11
  input: 'src/index.ts',
@@ -31,7 +31,7 @@ export default {
31
31
  sass({
32
32
  output: 'dist/styles.css',
33
33
  }),
34
- json()
34
+ json(),
35
35
  ],
36
36
  external: ['react', 'react-dom'],
37
37
  }
@@ -690,8 +690,10 @@ const MethodsAccordion = ({
690
690
  headers: {},
691
691
  })
692
692
 
693
- setFieldValue('responses', clonedResponses)
694
- responseIndex = 0
693
+ if (setFieldValue) {
694
+ setFieldValue('responses', clonedResponses)
695
+ responseIndex = 0
696
+ }
695
697
  }
696
698
  setCurrentResponseIndex(responseIndex)
697
699
  indexRef.current = responseIndex
@@ -699,7 +701,7 @@ const MethodsAccordion = ({
699
701
  generateResponseTableData(method.responses[responseIndex].headers, responseIndex)
700
702
  )
701
703
  }
702
- }, [selectedStatusCode, method.responses])
704
+ }, [selectedStatusCode, method.responses, setFieldValue])
703
705
 
704
706
  useEffect(() => {
705
707
  if (indexRef.current && indexRef.current > -1) {
@@ -8,6 +8,7 @@ export const transformOpenApiToDocs = (api: ApiSpecModel): OverviewData => {
8
8
  typeof api.metaData.openApiJson === 'string'
9
9
  ? JSON.parse(api.metaData.openApiJson)
10
10
  : api.metaData.openApiJson
11
+
11
12
  const groupedPathsByTags: Record<string, TagData[]> = { default: [] }
12
13
  const validTags = new Set(parsedOpenApi.tags.map(({ name }) => name))
13
14
 
@@ -1,7 +1,5 @@
1
1
  import React from 'react'
2
2
  import './style.scss'
3
- import SVGLoader from '../../../components/SVGLoader/SVGLoader'
4
- import { CopySticker } from '../../../assets/icons/index'
5
3
  import { TagPage } from './TagPage'
6
4
  import { EndpointPage } from './EndpointPage'
7
5
  import { EndpointData, OverviewData } from 'src/layout/docsLayout'
@@ -15,18 +13,22 @@ const DocsContent = ({
15
13
  }: {
16
14
  data: OverviewData | EndpointData
17
15
  activeType: 'OVERVIEW' | 'ENDPOINT'
16
+ setActiveItemData: React.Dispatch<React.SetStateAction<OverviewData | EndpointData>>
17
+ setActiveType: React.Dispatch<React.SetStateAction<'OVERVIEW' | 'ENDPOINT'>>
18
+ setExpandedSections: React.Dispatch<React.SetStateAction<Record<string, boolean>>>
19
+ toggleSection: (apiId: string, sectionId: string, resetOthers?: boolean, key?: string[]) => void
18
20
  }) => {
19
21
  return (
20
22
  <main>
21
23
  {activeType === 'OVERVIEW' ? (
22
24
  <TagPage
23
- data={data}
25
+ data={data as OverviewData}
24
26
  setActiveItemData={setActiveItemData}
25
27
  setActiveType={setActiveType}
26
28
  setExpandedSections={setExpandedSections}
27
29
  />
28
30
  ) : (
29
- <EndpointPage data={data} />
31
+ <EndpointPage data={data as EndpointData} />
30
32
  )}
31
33
  </main>
32
34
  )
@@ -6,7 +6,7 @@ import {
6
6
  DownArrowIcon,
7
7
  RequestOption,
8
8
  } from '../../../../assets/icons/index'
9
- import { ArrowIcon, SelectGroup } from 'digitinary-ui'
9
+ import { SelectGroup } from 'digitinary-ui'
10
10
  import { useEffect, useState } from 'react'
11
11
  import { EndpointData } from 'src/layout/docsLayout'
12
12
  import { handleStatusColor } from '../../../../helpers/methodAccordion.helper'
@@ -14,7 +14,7 @@ import { httpStatusCodes } from '../../../../constants/index'
14
14
  import styles from '../../Codebox/style.module.scss'
15
15
  import Tooltip from '../../../../components/Tooltip/Tooltip'
16
16
 
17
- export const EndpointPage = ({ data }) => {
17
+ export const EndpointPage = ({ data }: { data: EndpointData }) => {
18
18
  const [activeTab, setActiveTab] = useState('header')
19
19
 
20
20
  const httpStatusCodeOptions = httpStatusCodes.map((code) => ({
@@ -177,15 +177,17 @@ export const EndpointPage = ({ data }) => {
177
177
  </tr>
178
178
  </thead>
179
179
  <tbody>
180
- {!!headersList && Object.keys(headersList) && 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
- ))}
180
+ {!!headersList &&
181
+ Object.keys(headersList) &&
182
+ Object.keys(headersList).map((key, index) => (
183
+ <tr>
184
+ <td>{key}</td>
185
+ <td>{headersList[key]?.required.toString()}</td>
186
+ <td>{headersList[key]?.schema?.type}</td>
187
+ <td>{headersList[key]?.schema?.enum?.join('/')}</td>
188
+ <td>{headersList[key]?.description}</td>
189
+ </tr>
190
+ ))}
189
191
  </tbody>
190
192
  </table>
191
193
  </div>
@@ -1,9 +1,57 @@
1
1
  import './style.scss'
2
2
  import SVGLoader from '../../../../components/SVGLoader/SVGLoader'
3
3
  import { arrowRightGray, CopySticker } from '../../../../assets/icons/index'
4
- import { OverviewData } from 'src/layout/docsLayout'
4
+ import { EndpointData, OverviewData } from 'src/layout/docsLayout'
5
+
6
+ export const TagPage = ({
7
+ data,
8
+ setActiveItemData,
9
+ setActiveType,
10
+ setExpandedSections,
11
+ }: {
12
+ data: OverviewData
13
+ setActiveItemData: React.Dispatch<React.SetStateAction<OverviewData | EndpointData>>
14
+ setActiveType: React.Dispatch<React.SetStateAction<'OVERVIEW' | 'ENDPOINT'>>
15
+ setExpandedSections: React.Dispatch<React.SetStateAction<Record<string, boolean>>>
16
+ }) => {
17
+ const handleVersionClick = (verObj) => {
18
+ if (verObj.apiSpecId === data.apiSpecId) {
19
+ setActiveType('OVERVIEW')
20
+ return
21
+ }
22
+
23
+ const matchedVersion = data.apiVersions.find((v) => v.apiSpecId === verObj.apiSpecId)
24
+
25
+ if (!matchedVersion) {
26
+ return
27
+ }
28
+
29
+ const newData = {
30
+ ...data,
31
+ ...matchedVersion,
32
+ version: matchedVersion.metaData?.version || '',
33
+ title: matchedVersion.name || '',
34
+ apiSpecId: matchedVersion.apiSpecId,
35
+ }
36
+
37
+ setActiveItemData({
38
+ ...newData,
39
+ api: {
40
+ id: newData.apiSpecId,
41
+ title: newData.title,
42
+ description: newData.description,
43
+ version: newData.version,
44
+ ...newData,
45
+ },
46
+ })
47
+
48
+ setActiveType('OVERVIEW')
49
+ setExpandedSections((prev) => ({
50
+ ...prev,
51
+ [`api-${newData.apiSpecId}-section`]: true,
52
+ }))
53
+ }
5
54
 
6
- export const TagPage = ({ data, setActiveItemData, setActiveType, setExpandedSections }) => {
7
55
  const handleClick = (endpoint) => {
8
56
  setActiveItemData({
9
57
  ...endpoint,
@@ -44,7 +92,9 @@ export const TagPage = ({ data, setActiveItemData, setActiveType, setExpandedSec
44
92
  className="icon"
45
93
  onClick={() =>
46
94
  navigator.clipboard.writeText(
47
- `${!!data && !!data.servers && data.servers.length > 0 ? data.servers[0]?.url : '-'}`
95
+ `${
96
+ !!data && !!data.servers && data.servers.length > 0 ? data.servers[0]?.url : '-'
97
+ }`
48
98
  )
49
99
  }
50
100
  >
@@ -102,7 +152,11 @@ export const TagPage = ({ data, setActiveItemData, setActiveType, setExpandedSec
102
152
  <h4>API Versions</h4>
103
153
  <div className="version-list">
104
154
  {data.apiVersions.map((verObj, index) => (
105
- <button key={index} className="version-btn">
155
+ <button
156
+ key={index}
157
+ className="version-btn"
158
+ onClick={() => handleVersionClick(verObj)}
159
+ >
106
160
  {verObj.metaData?.version || 'N/A'}
107
161
  </button>
108
162
  ))}
@@ -14,62 +14,38 @@ const DocsSideMenuTree = ({
14
14
  isFirstApiExpanded,
15
15
  setIsFirstApiExpanded,
16
16
  setActiveType,
17
+ toggleSection,
18
+ canSelectFirstApi,
17
19
  }: {
18
20
  apis: OverviewData[]
19
21
  setActiveItemData: React.Dispatch<React.SetStateAction<OverviewData | EndpointData>>
20
22
  activeItemData: OverviewData | EndpointData
21
23
  expandedSections: Record<string, boolean>
22
- setExpandedSections: React.Dispatch<React.SetStateAction<Record<string, boolean>>>
24
+ setExpandedSections: (newSections: Record<string, boolean>) => void
23
25
  isFirstApiExpanded: boolean
24
26
  setIsFirstApiExpanded: React.Dispatch<React.SetStateAction<boolean>>
25
27
  setActiveType: React.Dispatch<React.SetStateAction<'OVERVIEW' | 'ENDPOINT'>>
26
28
  activeType: 'OVERVIEW' | 'ENDPOINT'
29
+ toggleSection: (apiId: string, sectionId: string, resetOthers?: boolean, key?: string[]) => void
30
+ canSelectFirstApi?: boolean
27
31
  }) => {
28
32
  // Auto-expand first API only once
29
33
  useEffect(() => {
30
- if (!apis?.length || !isFirstApiExpanded) return
34
+ if (canSelectFirstApi || !apis?.length || !isFirstApiExpanded) return
31
35
 
32
36
  const firstApi = apis[0]
33
37
  const sectionKey = `api-${firstApi.apiSpecId}-section`
34
38
  const overviewKey = `api-${firstApi.apiSpecId}-overview`
35
39
 
36
- setExpandedSections((prev) => ({
37
- ...prev,
40
+ setExpandedSections({
38
41
  [sectionKey]: true,
39
42
  [overviewKey]: true,
40
- }))
41
-
43
+ })
42
44
  setActiveItemData(firstApi)
43
45
  setActiveType('OVERVIEW')
44
46
  setIsFirstApiExpanded(false)
45
47
  }, [apis, isFirstApiExpanded])
46
48
 
47
- const toggleSection = (apiId, sectionId: string, resetOthers?: boolean, key?: string[]) => {
48
- if (resetOthers && key) {
49
- const filteredExpandedSections = Object.fromEntries(
50
- Object.entries({ ...expandedSections }).filter(([expandKey]) => {
51
- // Close other APIs sections
52
- if (!expandKey.includes(apiId)) return false
53
- // always return the clicked on section
54
- if (expandKey === sectionId) return true
55
- // filter all sections containing the key
56
- if (key.some((k) => expandKey.includes(k))) return false
57
- return true
58
- })
59
- )
60
-
61
- setExpandedSections({
62
- ...filteredExpandedSections,
63
- [sectionId]: !expandedSections[sectionId],
64
- })
65
- } else {
66
- setExpandedSections((prev) => ({
67
- ...prev,
68
- [sectionId]: !prev[sectionId],
69
- }))
70
- }
71
- }
72
-
73
49
  const renderEndpoints = (endpoints: EndpointData[], api: OverviewData) =>
74
50
  endpoints.map((endpoint, index) => {
75
51
  const key = `api-${api.apiSpecId}-resource-${endpoint.id}`
@@ -200,7 +176,9 @@ const DocsSideMenuTree = ({
200
176
  .sort(([a], [b]) =>
201
177
  a === 'default' ? 1 : b === 'default' ? -1 : a.localeCompare(b)
202
178
  )
203
- .map(([tagName, data], i) => renderSubSection(tagName, data, api, i))}
179
+ .map(([tagName, data], i) =>
180
+ renderSubSection(tagName, data as EndpointData[], api, i)
181
+ )}
204
182
  </div>
205
183
  )}
206
184
  </>
@@ -3,9 +3,11 @@ import Layout from './docsComponents'
3
3
  import { HTTPMethod, OpenAPIFile, Parameter, RequestBody, Responses } from '@entities/openApi'
4
4
  import { transformOpenApiToDocs } from '../helpers/docs.helper'
5
5
  import { ApiSpecModel } from '@entities/index'
6
+ import stableStringify from 'fast-json-stable-stringify'
6
7
 
7
8
  interface ILayoutProps {
8
9
  apis?: ApiSpecModel[]
10
+ activeApiId?: string
9
11
  }
10
12
 
11
13
  export interface TagData {
@@ -37,16 +39,60 @@ export interface OverviewData extends Omit<ApiSpecModel, 'metaData'> {
37
39
  servers: OpenAPIFile['servers']
38
40
  }
39
41
 
40
- const DocsLayout = ({ apis }: ILayoutProps): JSX.Element => {
41
- const [transformedOpenApis, setTransformedOpenApis] = useState([])
42
+ function areEqual(prev: ILayoutProps, next: ILayoutProps): boolean {
43
+ return (
44
+ stableStringify(prev.apis ?? []) === stableStringify(next.apis ?? []) &&
45
+ prev.activeApiId === next.activeApiId
46
+ )
47
+ }
48
+
49
+ const DocsLayout = ({ apis, activeApiId }: ILayoutProps): JSX.Element => {
50
+ const [transformedOpenApis, setTransformedOpenApis] = useState<OverviewData[]>([])
42
51
  const [isFirstApiExpanded, setIsFirstApiExpanded] = useState(true)
43
- const [activeItemData, setActiveItemData] = useState<OverviewData | EndpointData | {}>({})
52
+ const [activeItemData, setActiveItemData] = useState<
53
+ OverviewData | EndpointData | Record<string, never>
54
+ >({})
44
55
  const [activeType, setActiveType] = useState<'OVERVIEW' | 'ENDPOINT'>('OVERVIEW')
45
- const [expandedSections, setExpandedSections] = useState({})
46
- const allData = useRef([]);
56
+ const [expandedSections, setExpandedSections] = useState<Record<string, boolean>>({})
57
+ const allData = useRef([])
47
58
  const [pending, setPending] = useState(true)
59
+ const [canSelectFirstApi, setCanSelectFirstApi] = useState(false)
60
+
61
+ const toggleSection = (
62
+ apiId: string,
63
+ sectionId: string,
64
+ resetOthers?: boolean,
65
+ key?: string[]
66
+ ) => {
67
+ setCanSelectFirstApi(false)
68
+ if (resetOthers && key) {
69
+ const filteredExpandedSections = Object.fromEntries(
70
+ Object.entries({ ...expandedSections }).filter(([expandKey]) => {
71
+ // Close other APIs sections
72
+ if (!expandKey.includes(apiId)) return false
73
+ // always return the clicked on section
74
+ if (expandKey === sectionId) return true
75
+ // filter all sections containing the key
76
+ if (key.some((k) => expandKey.includes(k))) return false
77
+ return true
78
+ })
79
+ )
80
+
81
+ setExpandedSections({
82
+ ...filteredExpandedSections,
83
+ [sectionId]: !expandedSections[sectionId],
84
+ })
85
+ } else {
86
+ setExpandedSections((prev) => ({
87
+ ...prev,
88
+ [sectionId]: !expandedSections[sectionId],
89
+ }))
90
+ }
91
+ }
92
+
48
93
  useEffect(() => {
49
94
  if (transformedOpenApis.length === 0) {
95
+ setCanSelectFirstApi(!!activeApiId)
50
96
  const t = structuredClone(apis)
51
97
  ?.map((o3) => transformOpenApiToDocs(o3))
52
98
  .sort((a, b) => a.title.toLowerCase().localeCompare(b.title.toLowerCase()))
@@ -58,35 +104,67 @@ const DocsLayout = ({ apis }: ILayoutProps): JSX.Element => {
58
104
  }
59
105
  }, [apis])
60
106
 
61
- const updateFilteredData = (filteredItems, isReset=false) => {
62
- if(isReset){
107
+ const updateFilteredData = (filteredItems, isReset = false) => {
108
+ if (isReset) {
63
109
  setTransformedOpenApis(allData.current)
64
- return;
110
+ return
65
111
  }
66
112
  setTransformedOpenApis(filteredItems)
67
113
  }
68
114
 
115
+ useEffect(() => {
116
+ if (activeApiId && transformedOpenApis.length > 0) {
117
+ const activeApi = transformedOpenApis.find((api) => api.apiSpecId === activeApiId)
118
+ const sectionKey = `api-${activeApi.apiSpecId}-section`
119
+ const overviewKey = `api-${activeApi.apiSpecId}-overview`
120
+
121
+ setExpandedSections((prev) => ({
122
+ ...prev,
123
+ [sectionKey]: true,
124
+ [overviewKey]: true,
125
+ }))
126
+ setActiveItemData(activeApi)
127
+ setActiveType('OVERVIEW')
128
+ setIsFirstApiExpanded(false)
129
+ setCanSelectFirstApi(true)
130
+ }
131
+ }, [activeApiId, transformedOpenApis])
132
+
69
133
  return (
70
134
  <Layout>
71
- <Layout.DocsHeader transformedOpenApis={transformedOpenApis} updateFilteredData={updateFilteredData}/>
72
- <Layout.DocsSideMenuTree
73
- apis={transformedOpenApis}
74
- setActiveItemData={setActiveItemData}
75
- activeItemData={activeItemData}
76
- expandedSections={expandedSections}
77
- setExpandedSections={setExpandedSections}
78
- isFirstApiExpanded={isFirstApiExpanded}
79
- activeType={activeType}
80
- setIsFirstApiExpanded={setIsFirstApiExpanded}
81
- setActiveType={setActiveType}
135
+ <Layout.DocsHeader
136
+ transformedOpenApis={transformedOpenApis}
137
+ updateFilteredData={updateFilteredData}
82
138
  />
139
+ {!pending && (
140
+ <Layout.DocsSideMenuTree
141
+ apis={transformedOpenApis}
142
+ setActiveItemData={setActiveItemData}
143
+ activeItemData={activeItemData as OverviewData | EndpointData}
144
+ expandedSections={expandedSections}
145
+ setExpandedSections={(newExpandedSections) =>
146
+ setExpandedSections((prev) => ({
147
+ ...prev,
148
+ ...newExpandedSections,
149
+ }))
150
+ }
151
+ isFirstApiExpanded={isFirstApiExpanded}
152
+ activeType={activeType}
153
+ setIsFirstApiExpanded={setIsFirstApiExpanded}
154
+ setActiveType={setActiveType}
155
+ toggleSection={toggleSection}
156
+ canSelectFirstApi={canSelectFirstApi}
157
+ />
158
+ )}
159
+
83
160
  {!pending && Object.keys(activeItemData).length > 0 && (
84
161
  <Layout.DocsContent
85
- data={activeItemData}
162
+ data={activeItemData as OverviewData | EndpointData}
86
163
  activeType={activeType}
87
164
  setActiveItemData={setActiveItemData}
88
165
  setActiveType={setActiveType}
89
166
  setExpandedSections={setExpandedSections}
167
+ toggleSection={toggleSection}
90
168
  />
91
169
  )}
92
170
  {activeType === 'ENDPOINT' && <Layout.DocsAside data={activeItemData as EndpointData} />}
@@ -94,4 +172,4 @@ const DocsLayout = ({ apis }: ILayoutProps): JSX.Element => {
94
172
  )
95
173
  }
96
174
 
97
- export default DocsLayout
175
+ export default React.memo(DocsLayout, areEqual)