@digi-frontend/dgate-api-documentation 1.0.6 → 1.0.8

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 (35) 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/digitinary-ui/dist/index.js +1 -1
  6. package/dist/node_modules/digitinary-ui/dist/index.js.map +1 -1
  7. package/dist/node_modules/toposort/index.js +1 -1
  8. package/dist/node_modules/yup/index.esm.js +1 -1
  9. package/dist/src/components/InfoForm/InfoForm.js +1 -1
  10. package/dist/src/components/InfoForm/InfoForm.js.map +1 -1
  11. package/dist/src/components/MethodAccordion/MethodAccordion.js +1 -1
  12. package/dist/src/components/MethodAccordion/MethodAccordion.js.map +1 -1
  13. package/dist/src/components/table/table.js +1 -1
  14. package/dist/src/components/table/table.js.map +1 -1
  15. package/dist/src/components/table/tags-table.js +2 -0
  16. package/dist/src/components/table/tags-table.js.map +1 -0
  17. package/dist/src/constants/index.js +1 -1
  18. package/dist/src/constants/index.js.map +1 -1
  19. package/dist/src/layout/layout.js.map +1 -1
  20. package/dist/styles.css +636 -558
  21. package/dist/types/components/InfoForm/InfoForm.d.ts +3 -1
  22. package/dist/types/components/table/tags-table.d.ts +11 -0
  23. package/dist/types/constants/index.d.ts +6 -0
  24. package/dist/types/layout/layout.d.ts +1 -0
  25. package/dist/types/types/index.d.ts +18 -0
  26. package/dist/types/types/openApi.d.ts +12 -0
  27. package/package.json +2 -2
  28. package/src/components/InfoForm/InfoForm.module.scss +114 -0
  29. package/src/components/InfoForm/InfoForm.tsx +271 -51
  30. package/src/components/MethodAccordion/MethodAccordion.tsx +2 -2
  31. package/src/components/table/table.tsx +3 -3
  32. package/src/components/table/tags-table.tsx +308 -0
  33. package/src/constants/index.ts +21 -0
  34. package/src/layout/layout.tsx +1 -0
  35. package/src/types/openApi.ts +13 -0
@@ -1,2 +1,4 @@
1
- declare const InfoForm: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const InfoForm: ({ readOnly }: {
2
+ readOnly?: boolean;
3
+ }) => import("react/jsx-runtime").JSX.Element;
2
4
  export default InfoForm;
@@ -0,0 +1,11 @@
1
+ import './style.scss';
2
+ declare const TagsTable: ({ id, headCells, data, isFormOpen, setIsFormOpen, saveNewRow, readOnly }: {
3
+ id: any;
4
+ headCells: any;
5
+ data: any;
6
+ isFormOpen: any;
7
+ setIsFormOpen: any;
8
+ saveNewRow: any;
9
+ readOnly: any;
10
+ }) => import("react/jsx-runtime").JSX.Element;
11
+ export default TagsTable;
@@ -40,6 +40,12 @@ export declare const methodColorMapping: {
40
40
  order: number;
41
41
  };
42
42
  };
43
+ export declare const tagsTableHeaders: {
44
+ id: string;
45
+ label: string;
46
+ sortable: boolean;
47
+ classes: string;
48
+ }[];
43
49
  export declare const paramsTableHeaders: ({
44
50
  id: string;
45
51
  label: string;
@@ -2,6 +2,7 @@ import { JSX } from 'react';
2
2
  import { OpenAPIFile } from '../types/openApi';
3
3
  interface ILayoutProps {
4
4
  openApiJson?: OpenAPIFile;
5
+ handleSave?: (values: unknown) => unknown;
5
6
  }
6
7
  declare const Layout: ({ openApiJson, handleSave }: ILayoutProps) => JSX.Element;
7
8
  export default Layout;
@@ -0,0 +1,18 @@
1
+ export type MethodTypes = 'GET' | 'POST' | 'PUT' | 'DELETE';
2
+ export interface ParameterType {
3
+ name: string;
4
+ in: string;
5
+ schemaType: string;
6
+ required: boolean;
7
+ }
8
+ export interface MethodAccordionProps {
9
+ method: MethodTypes;
10
+ path: string;
11
+ desc: string;
12
+ parameters: ParameterType[];
13
+ request: string;
14
+ response: {
15
+ content: string;
16
+ statusCode: number;
17
+ };
18
+ }
@@ -33,6 +33,18 @@ export interface OpenAPIFile {
33
33
  tags?: {
34
34
  name: string;
35
35
  description?: string;
36
+ externalDocs?: {
37
+ url: string;
38
+ description: string;
39
+ }[];
40
+ }[];
41
+ }
42
+ export interface Tags {
43
+ name: string;
44
+ description?: string;
45
+ externalDocs?: {
46
+ url: string;
47
+ description: string;
36
48
  }[];
37
49
  }
38
50
  interface Parameter {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digi-frontend/dgate-api-documentation",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "main": "dist/src/index.js",
5
5
  "module": "dist/src/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -16,7 +16,7 @@
16
16
  "license": "ISC",
17
17
  "description": "",
18
18
  "dependencies": {
19
- "digitinary-ui": "^1.0.156",
19
+ "digitinary-ui": "^1.0.166",
20
20
  "formik": "^2.4.6",
21
21
  "html-react-parser": "^5.2.2",
22
22
  "js-yaml": "^4.1.0",
@@ -3,6 +3,91 @@
3
3
  padding: 1.25rem 1.875rem;
4
4
  gap: 1.25rem;
5
5
 
6
+ .paramsTable {
7
+ .paramDescContainer {
8
+ display: flex;
9
+
10
+ .paramDescContainer_separator {
11
+ height: inherit;
12
+ width: 1px;
13
+ background-color: #d8dae5;
14
+ }
15
+
16
+ :global(.customBtn) {
17
+ svg {
18
+ path {
19
+ stroke-width: 0.1;
20
+ }
21
+ }
22
+
23
+ &.editDescBtn {
24
+ padding: 0;
25
+ margin-right: 1.25rem;
26
+
27
+ :global(.btnContentWrapper) {
28
+ display: flex;
29
+ align-items: center;
30
+ padding: 0;
31
+ color: #12131a;
32
+
33
+ :global(.endBtnIcon) {
34
+ margin-block: auto;
35
+
36
+ svg {
37
+ path {
38
+ fill: #12131a;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ &.deleteParamBtn {
46
+ padding: 0;
47
+
48
+ :global(.btnContentWrapper) {
49
+ :global(.endBtnIcon) {
50
+ margin-block: auto;
51
+
52
+ svg {
53
+ width: 1.125rem;
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ .editDescTooltipContent {
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 0.625rem;
65
+ padding-bottom: 0.625rem;
66
+
67
+ > *:not(.editDescTooltipContent_header) {
68
+ margin-inline: 0.625rem;
69
+ }
70
+
71
+ .editDescTooltipContent_header {
72
+ font-weight: 600;
73
+ font-size: 0.875rem;
74
+ line-height: 1.25rem;
75
+ padding: 0.75rem 1.25rem;
76
+ border-bottom: 1px solid #d8dae5;
77
+ }
78
+ }
79
+
80
+ :global(.requiredParam) {
81
+ :global(.headContainer) {
82
+ &::after {
83
+ content: '*';
84
+ color: red;
85
+ transform: translateX(0.125rem);
86
+ }
87
+ }
88
+ }
89
+ }
90
+
6
91
  .apiDocRow {
7
92
  display: grid;
8
93
  grid-template-columns: 1fr 1fr;
@@ -12,4 +97,33 @@
12
97
  .apiInfoForm_tagsChips {
13
98
  margin-top: -1.25rem;
14
99
  }
100
+
101
+ .editDescTooltipContent {
102
+ display: flex;
103
+ flex-direction: column;
104
+ gap: 0.625rem;
105
+ padding-bottom: 0.625rem;
106
+
107
+ > *:not(.editDescTooltipContent_header) {
108
+ margin-inline: 0.625rem;
109
+ }
110
+
111
+ .editDescTooltipContent_header {
112
+ font-weight: 600;
113
+ font-size: 0.875rem;
114
+ line-height: 1.25rem;
115
+ padding: 0.75rem 1.25rem;
116
+ border-bottom: 1px solid #d8dae5;
117
+ }
118
+ }
119
+
120
+ :global(.requiredParam) {
121
+ :global(.headContainer) {
122
+ &::after {
123
+ content: '*';
124
+ color: red;
125
+ transform: translateX(0.125rem);
126
+ }
127
+ }
128
+ }
15
129
  }
@@ -1,21 +1,29 @@
1
1
  import { useEffect, useState } from 'react'
2
2
  // @ts-ignore
3
3
  import { useFormikContext } from 'formik'
4
- import { Input, SelectGroup, TextArea } from 'digitinary-ui'
4
+ import { Button, Input, TextArea } from 'digitinary-ui'
5
5
  import styles from './InfoForm.module.scss'
6
- import Chips from '../../components/Chips/Chips'
7
6
  import regex from '../../constants/regex'
8
7
  import { TransformedOpenApi } from '../../types/transformedOpenApi'
9
-
10
- const InfoForm = () => {
11
- const [tagsList, setTagsList] = useState([])
8
+ import Tooltip from '../../components/Tooltip/Tooltip'
9
+ import { DeleteIcon, deleteOutlinedIcon, EditIcon } from '../../assets/icons'
10
+ import SVGLoader from '../../components/SVGLoader/SVGLoader'
11
+ import CommonDialog from '../../components/dialog'
12
+ import { tagsTableHeaders } from '../../constants/index'
13
+ import TagsTable from '../../components/table/tags-table'
14
+ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
15
+ const [tableData, setTableData] = useState([])
16
+ const [tableRecords, setTableRecords] = useState()
12
17
  const [authType, setAuthType] = useState('')
13
18
  const { values, setFieldValue, errors } = useFormikContext<TransformedOpenApi>()
19
+ const [externalTooltipRefs, setExternalTooltipRefs] = useState<{ [key: number]: any }>({})
20
+ const [tooltipRefs, setTooltipRefs] = useState<{ [key: number]: any }>({})
21
+ const [selectedTagIndex, setSelectedTagIndex] = useState<number | null>(null)
22
+ const [selectedTagName, setSelectedTagName] = useState<string | null>(null)
23
+ const [openDeleteDialog, setOpenDeleteDialog] = useState(false)
24
+ const [isFormOpen, setIsFormOpen] = useState(false)
14
25
 
15
26
  useEffect(() => {
16
- if (values && values.tags) {
17
- setTagsList(values.tags)
18
- }
19
27
  if (values && values.components && values.components.securitySchemes) {
20
28
  const authenticatorKeys = Object.keys(values.components.securitySchemes)
21
29
  if (authenticatorKeys.length) {
@@ -24,11 +32,226 @@ const InfoForm = () => {
24
32
  }
25
33
  }, [])
26
34
 
35
+ useEffect(() => {
36
+ setTableRecords(generateTableData(tableData))
37
+ }, [tableData])
38
+
39
+ useEffect(() => {
40
+ if (values.tags && values.tags.length) {
41
+ setTableRecords(generateTableData(values.tags))
42
+ setTableData(values.tags)
43
+ }
44
+ }, [])
45
+
46
+ const confirmDeleteTag = () => {
47
+ if (selectedTagIndex !== null) {
48
+ setTableData((prev) => prev.filter((_, i) => i !== selectedTagIndex))
49
+ }
50
+ setOpenDeleteDialog(false)
51
+ setSelectedTagIndex(null)
52
+ }
53
+
27
54
  const capitalize = (str) => {
28
55
  if (!str) return ''
29
56
  return str.charAt(0).toUpperCase() + str.slice(1)
30
57
  }
31
58
 
59
+ const onTableChange = (key, value, index) => {
60
+ const newTableData = tableData.map((item, tIndex) => {
61
+ if (tIndex === index) {
62
+ return { ...item, [key]: value }
63
+ } else {
64
+ return item
65
+ }
66
+ })
67
+
68
+ setTableData(newTableData)
69
+ }
70
+
71
+ const saveNewRow = (tag) => {
72
+ setTableData([...tableData, tag])
73
+ setFieldValue(`tags`, [...values.tags, tag])
74
+ }
75
+
76
+ const handleDeleteClick = (id: number, name: string) => {
77
+ setSelectedTagIndex(id)
78
+ setSelectedTagName(name)
79
+
80
+ setOpenDeleteDialog(true)
81
+ }
82
+
83
+ const generateTableData = (items) => {
84
+ return items.map((item, index) => ({
85
+ id: index,
86
+ tagName: item.name,
87
+ description: (
88
+ <div className={styles.paramDescContainer}>
89
+ <Tooltip
90
+ arrowWithBorder
91
+ placement="bottom-end"
92
+ type="function"
93
+ trigger="click"
94
+ delay={[0, 0]}
95
+ onCreate={(instance) =>
96
+ setTooltipRefs((prev) => ({
97
+ ...prev,
98
+ [index]: instance,
99
+ }))
100
+ }
101
+ content={
102
+ <div className={styles.editDescTooltipContent}>
103
+ <p className={styles.editDescTooltipContent_header}>Description</p>
104
+ <TextArea
105
+ placeholder="Describe parameter..."
106
+ value={item.description}
107
+ disabled={readOnly}
108
+ onChange={(value) => onTableChange('description', value, index)}
109
+ />
110
+ {!readOnly && (
111
+ <Button
112
+ className={styles.editDescTooltipContent_btn}
113
+ variant="outlined"
114
+ size="small"
115
+ onClick={() => {
116
+ setFieldValue(`tags[${index}].description`, item.description)
117
+ tooltipRefs[index]?.hide()
118
+ }}
119
+ >
120
+ Apply
121
+ </Button>
122
+ )}
123
+ </div>
124
+ }
125
+ >
126
+ {readOnly ? (
127
+ <Button className={styles.editDescBtn} variant="link" color="action">
128
+ {item.description ? item.description.substring(0, 12) : '-'}
129
+ {item.description && item.description.length > 12 ? '...' : ''}
130
+ </Button>
131
+ ) : (
132
+ <Button
133
+ className={styles.editDescBtn}
134
+ variant="link"
135
+ color="action"
136
+ endIcon={<SVGLoader src={EditIcon} width="1.5rem" height="1.5rem" />}
137
+ >
138
+ {readOnly || item.description ? 'View Description' : 'Add Description'}
139
+ </Button>
140
+ )}
141
+ </Tooltip>
142
+ </div>
143
+ ),
144
+ externalDocs: (
145
+ <div className={styles.paramDescContainer}>
146
+ <Tooltip
147
+ arrowWithBorder
148
+ placement="bottom-end"
149
+ type="function"
150
+ trigger="click"
151
+ delay={[0, 0]}
152
+ onCreate={(instance) =>
153
+ setExternalTooltipRefs((prev) => ({
154
+ ...prev,
155
+ [index]: instance,
156
+ }))
157
+ }
158
+ content={
159
+ <div className={styles.editDescTooltipContent}>
160
+ <p className={styles.editDescTooltipContent_header}>External Docs Description</p>
161
+ <TextArea
162
+ placeholder="Describe External Doc..."
163
+ value={item.externalDocs?.description}
164
+ disabled={readOnly}
165
+ onChange={(value) =>
166
+ onTableChange(
167
+ 'externalDocs',
168
+ { ...item.externalDocs, description: value },
169
+ index
170
+ )
171
+ }
172
+ />
173
+ <p className={styles.editDescTooltipContent_header}>External Docs Link</p>
174
+ <TextArea
175
+ placeholder="External Docs Link..."
176
+ value={item.externalDocs?.url}
177
+ disabled={readOnly}
178
+ onChange={(value) =>
179
+ onTableChange('externalDocs', { ...item.externalDocs, url: value }, index)
180
+ }
181
+ />
182
+ {!readOnly && (
183
+ <Button
184
+ className={styles.editDescTooltipContent_btn}
185
+ variant="outlined"
186
+ size="small"
187
+ onClick={() => {
188
+ setFieldValue(`tags[${index}].externalDocs`, {
189
+ description: item.externalDocDesc,
190
+ url: item.externalDocLink,
191
+ })
192
+ console.log({ tags: values.tags })
193
+ externalTooltipRefs[index]?.hide()
194
+ }}
195
+ >
196
+ Apply
197
+ </Button>
198
+ )}
199
+ </div>
200
+ }
201
+ >
202
+ {readOnly ? (
203
+ <Button
204
+ className={styles.editDescBtn}
205
+ variant="link"
206
+ color="action"
207
+ onClick={() => {
208
+ const a = document.createElement('a')
209
+ a.href = item.externalDocs?.url
210
+ a.click()
211
+ }}
212
+ >
213
+ {item?.externalDocs?.description
214
+ ? item?.externalDocs?.description?.substring(0, 12)
215
+ : '-'}
216
+ {item?.externalDocs?.description && item?.externalDocs?.description?.length > 12
217
+ ? '...'
218
+ : ''}
219
+ </Button>
220
+ ) : (
221
+ <Button
222
+ className={styles.editDescBtn}
223
+ variant="link"
224
+ color="action"
225
+ endIcon={<SVGLoader src={EditIcon} width="1.5rem" height="1.5rem" />}
226
+ onClick={() => {
227
+ console.log('Move to url')
228
+ }}
229
+ >
230
+ {readOnly ||
231
+ (item.externalDocs && (item.externalDocs?.url || item.externalDocs?.description))
232
+ ? 'View '
233
+ : 'Add '}{' '}
234
+ External Docs Link
235
+ </Button>
236
+ )}
237
+ </Tooltip>
238
+
239
+ {!readOnly && <div className={styles.paramDescContainer_separator}></div>}
240
+
241
+ {!readOnly && (
242
+ <Button
243
+ className={styles.deleteParamBtn}
244
+ variant="link"
245
+ color="error"
246
+ endIcon={<SVGLoader src={DeleteIcon} width="1.125rem" height="1.125rem" />}
247
+ onClick={() => handleDeleteClick(index, item.name)}
248
+ ></Button>
249
+ )}
250
+ </div>
251
+ ),
252
+ }))
253
+ }
254
+
32
255
  return (
33
256
  <form className={styles.apiInfoForm} onSubmit={(e) => e.preventDefault()}>
34
257
  <Input
@@ -72,51 +295,48 @@ const InfoForm = () => {
72
295
  errorMessage={errors?.info?.description}
73
296
  restrictedCharsRegex={regex.restrictNone}
74
297
  />
75
- <SelectGroup
76
- value={values.tags.map((item) => ({
77
- label: item.name,
78
- value: item.name,
79
- description: item.description || '',
80
- }))}
81
- onChange={(items) =>
82
- setFieldValue(
83
- 'tags',
84
- items.map((item) => ({
85
- name: item.label,
86
- description: item.description || '',
87
- }))
88
- )
298
+ <div className={styles.paramsTable}>
299
+ <TagsTable
300
+ id="paramter-table"
301
+ data={tableRecords}
302
+ headCells={tagsTableHeaders}
303
+ isFormOpen={isFormOpen}
304
+ setIsFormOpen={setIsFormOpen}
305
+ saveNewRow={saveNewRow}
306
+ readOnly={readOnly}
307
+ />
308
+ </div>
309
+ <CommonDialog
310
+ status="error"
311
+ content={
312
+ <p
313
+ style={{
314
+ textAlign: 'center',
315
+ fontWeight: 400,
316
+ fontSize: '1rem',
317
+ lineHeight: '1.4375rem',
318
+ }}
319
+ className="delete-msg-container"
320
+ >
321
+ Are you sure you want to delete
322
+ <span className="plan-name">{` Tag ${selectedTagName} `}</span>?
323
+ </p>
89
324
  }
90
- label="Tags"
91
- options={[
92
- {
93
- list: tagsList?.map((item) => ({
94
- label: item.name,
95
- value: item.name,
96
- description: item.description || '',
97
- })),
98
- },
99
- ]}
325
+ onSubmit={{
326
+ onClick: confirmDeleteTag,
327
+ text: 'Yes',
328
+ color: 'error',
329
+ fullWidth: true,
330
+ }}
331
+ onCancel={{
332
+ text: 'No',
333
+ color: 'normal',
334
+ fullWidth: true,
335
+ }}
336
+ onClose={() => setOpenDeleteDialog(false)}
337
+ open={openDeleteDialog}
338
+ icon={<SVGLoader src={deleteOutlinedIcon} width="4.0625rem" height="4.0625rem" />}
100
339
  />
101
- {values.tags.length > 0 && (
102
- <Chips
103
- className={styles.apiInfoForm_tagsChips}
104
- items={values.tags.map((t) => ({
105
- id: t.name,
106
- label: t.name,
107
- description: t.description || '',
108
- }))}
109
- onDelete={(items) =>
110
- setFieldValue(
111
- 'tags',
112
- items.map((item) => ({
113
- name: item.label,
114
- description: item.description || '',
115
- }))
116
- )
117
- }
118
- />
119
- )}
120
340
  </form>
121
341
  )
122
342
  }
@@ -53,6 +53,8 @@ const MethodsAccordion = ({
53
53
  const [openDeleteDialog, setOpenDeleteDialog] = useState(false)
54
54
  const [selectedParamIndex, setSelectedParamIndex] = useState<number | null>(null)
55
55
  const [selectedParamName, setSelectedParamName] = useState<string | null>(null)
56
+ const [tableRecords, setTableRecords] = useState()
57
+
56
58
  const [selectedStatusCode, setSelectedStatusCode] = useState(httpStatusCodeOptions[4])
57
59
  const currentResponse =
58
60
  method.responses.find((res) => Number(res.code) === selectedStatusCode.value) || '{}'
@@ -176,8 +178,6 @@ const MethodsAccordion = ({
176
178
  })
177
179
  }
178
180
 
179
- const [tableRecords, setTableRecords] = useState()
180
-
181
181
  const confirmDeleteParameter = () => {
182
182
  if (selectedParamIndex !== null) {
183
183
  setTableData((prev) => prev.filter((_, i) => i !== selectedParamIndex))
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from 'react'
2
2
  import './style.scss'
3
- import { Button, Input, SelectGroup, Switch, TextArea } from 'digitinary-ui'
3
+ import { Button, Input, SelectGroupV2, Switch, TextArea } from 'digitinary-ui'
4
4
  import Tooltip from '../Tooltip/Tooltip'
5
5
  import SVGLoader from '../SVGLoader/SVGLoader'
6
6
  import { AddRow, EditIcon, DeleteIcon } from '../../assets/icons'
@@ -125,7 +125,7 @@ const ParamterTable = ({
125
125
 
126
126
  <td key={'parameter in'}>
127
127
  <div data-id="TEXT_DESCRIPTION" className="tableData">
128
- <SelectGroup
128
+ <SelectGroupV2
129
129
  disabled={readOnly}
130
130
  value={{
131
131
  label: capitalize(values.in),
@@ -152,7 +152,7 @@ const ParamterTable = ({
152
152
 
153
153
  <td key={'parameter schema type'}>
154
154
  <div data-id="TEXT_DESCRIPTION" className="tableData">
155
- <SelectGroup
155
+ <SelectGroupV2
156
156
  disabled={readOnly}
157
157
  value={{
158
158
  label: capitalize(values.schema.type),