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

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 (44) 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/digitinary-ui/dist/index.js +1 -1
  5. package/dist/node_modules/digitinary-ui/dist/index.js.map +1 -1
  6. package/dist/node_modules/js-yaml/dist/js-yaml.mjs.js +3 -0
  7. package/dist/node_modules/js-yaml/dist/js-yaml.mjs.js.map +1 -0
  8. package/dist/node_modules/toposort/index.js +1 -1
  9. package/dist/node_modules/yup/index.esm.js +1 -1
  10. package/dist/src/components/InfoForm/InfoForm.js +1 -1
  11. package/dist/src/components/InfoForm/InfoForm.js.map +1 -1
  12. package/dist/src/components/JsonInput/JsonInput.js +2 -0
  13. package/dist/src/components/JsonInput/JsonInput.js.map +1 -0
  14. package/dist/src/components/JsonInput/style.module.scss.js +2 -0
  15. package/dist/src/components/JsonInput/style.module.scss.js.map +1 -0
  16. package/dist/src/components/MethodAccordion/MethodAccordion.js +1 -1
  17. package/dist/src/components/MethodAccordion/MethodAccordion.js.map +1 -1
  18. package/dist/src/constants/index.js +1 -1
  19. package/dist/src/constants/index.js.map +1 -1
  20. package/dist/src/helpers/layout.helper.js +1 -1
  21. package/dist/src/helpers/layout.helper.js.map +1 -1
  22. package/dist/src/layout/layout.js +1 -1
  23. package/dist/src/layout/layout.js.map +1 -1
  24. package/dist/src/layout/layout.module.css.js +1 -1
  25. package/dist/styles.css +323 -220
  26. package/dist/types/components/JsonInput/JsonInput.d.ts +13 -0
  27. package/dist/types/components/MethodAccordion/MethodAccordion.d.ts +1 -2
  28. package/dist/types/constants/index.d.ts +12 -4
  29. package/dist/types/types/layout.type.d.ts +9 -1
  30. package/dist/types/types/openApi.d.ts +1 -1
  31. package/package.json +2 -1
  32. package/src/components/InfoForm/InfoForm.module.scss +0 -5
  33. package/src/components/InfoForm/InfoForm.tsx +3 -17
  34. package/src/components/JsonInput/JsonInput.tsx +130 -0
  35. package/src/components/JsonInput/style.module.scss +123 -0
  36. package/src/components/MethodAccordion/MethodAccordion.module.scss +10 -5
  37. package/src/components/MethodAccordion/MethodAccordion.tsx +49 -50
  38. package/src/constants/index.ts +16 -8
  39. package/src/helpers/layout.helper.ts +60 -33
  40. package/src/layout/layout.module.css +18 -0
  41. package/src/layout/layout.tsx +40 -16
  42. package/src/types/layout.type.ts +9 -1
  43. package/src/types/openApi.ts +1 -1
  44. package/dist/types/types/index.d.ts +0 -18
@@ -12,9 +12,4 @@
12
12
  .apiInfoForm_tagsChips {
13
13
  margin-top: -1.25rem;
14
14
  }
15
-
16
- .apiInfoForm_submitBtn {
17
- height: 1.25rem !important;
18
- width: 4.25rem;
19
- }
20
15
  }
@@ -1,19 +1,17 @@
1
1
  import { useEffect, useState } from 'react'
2
2
  // @ts-ignore
3
3
  import { useFormikContext } from 'formik'
4
- import * as Yup from 'yup'
5
- import { Button, Input, SelectGroup, TextArea } from 'digitinary-ui'
4
+ import { Input, SelectGroup, TextArea } from 'digitinary-ui'
6
5
  import styles from './InfoForm.module.scss'
7
6
  import Chips from '../../components/Chips/Chips'
8
- import { CheckMarkSquare } from '../../assets/icons'
9
- import SVGLoader from '../../components/SVGLoader/SVGLoader'
10
7
  import regex from '../../constants/regex'
11
8
  import { TransformedOpenApi } from '../../types/transformedOpenApi'
12
9
 
13
10
  const InfoForm = () => {
14
11
  const [tagsList, setTagsList] = useState([])
15
12
  const [authType, setAuthType] = useState('')
16
- const { values, setFieldValue, errors, submitForm } = useFormikContext<TransformedOpenApi>()
13
+ const { values, setFieldValue, errors } = useFormikContext<TransformedOpenApi>()
14
+
17
15
  useEffect(() => {
18
16
  if (values && values.tags) {
19
17
  setTagsList(values.tags)
@@ -119,18 +117,6 @@ const InfoForm = () => {
119
117
  }
120
118
  />
121
119
  )}
122
- <Button
123
- className={styles.apiInfoForm_submitBtn}
124
- size="small"
125
- fullWidth={false}
126
- onClick={submitForm}
127
- type="submit"
128
- variant="link"
129
- color="success"
130
- startIcon={<SVGLoader src={CheckMarkSquare} width="1.5rem" height="1.5rem" />}
131
- >
132
- Save
133
- </Button>
134
120
  </form>
135
121
  )
136
122
  }
@@ -0,0 +1,130 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import yaml from 'js-yaml'
3
+ import styles from './style.module.scss'
4
+
5
+ const JsonInput = ({
6
+ placeholder,
7
+ label,
8
+ value,
9
+ onValidation,
10
+ onChange,
11
+ dataId,
12
+ className = '',
13
+ errorMessage,
14
+ acceptType = 'BOTH',
15
+ fieldIsDisabled,
16
+ }) => {
17
+ const [isValid, setIsValid] = useState()
18
+ const [disabledBeautify, setDisabledBeautify] = useState(true)
19
+
20
+ const handlePrettify = (e) => {
21
+ if (value === '') return
22
+ e.preventDefault()
23
+ try {
24
+ let prettifiedData
25
+ if ((acceptType === 'BOTH' || acceptType === 'JSON') && isValidJson(value)) {
26
+ // If it's valid JSON, prettify JSON
27
+ prettifiedData = JSON.stringify(JSON.parse(value), null, 2)
28
+ } else if (acceptType === 'BOTH' || acceptType === 'YML') {
29
+ // If it's not valid JSON, prettify YAML
30
+ prettifiedData = yaml.dump(yaml.load(value), { indent: 0 })
31
+ }
32
+ onChange(prettifiedData)
33
+ setIsValid(true) // Reset validity status
34
+ } catch (error) {
35
+ console.error(error)
36
+ setIsValid(false)
37
+ }
38
+ }
39
+
40
+ // Function to check if input is valid JSON
41
+ const isValidJson = (str) => {
42
+ try {
43
+ JSON.parse(str)
44
+ return true
45
+ } catch (error) {
46
+ return false
47
+ }
48
+ }
49
+
50
+ const checkIsValid = () => {
51
+ if (acceptType === 'BOTH' || acceptType === 'JSON') {
52
+ return isValidJson(value)
53
+ } else if (acceptType === 'BOTH' || acceptType === 'YML') {
54
+ try {
55
+ // Try parsing as YAML
56
+ yaml.load(value)
57
+ return true
58
+ } catch (error) {
59
+ console.error(error)
60
+ return false
61
+ }
62
+ }
63
+ }
64
+
65
+ useEffect(() => {
66
+ try {
67
+ handlePrettify(value)
68
+ } catch {}
69
+ }, [])
70
+
71
+ return (
72
+ <div className={`${styles['json-editor-container']} ${className}`}>
73
+ {label && <p className={`${styles['json-editor-label']}`}>{label}</p>}
74
+ <div
75
+ className={`${styles['json-editor']} ${
76
+ value !== '' && isValid === false ? styles.invalid : ''
77
+ }`}
78
+ >
79
+ <textarea
80
+ data-id={dataId}
81
+ value={value}
82
+ onChange={(e) => {
83
+ if (fieldIsDisabled) return
84
+ setIsValid(undefined)
85
+ setDisabledBeautify(true)
86
+ onChange(e.target.value)
87
+ }}
88
+ onPaste={(e) => {
89
+ if (fieldIsDisabled) return
90
+ setIsValid(undefined)
91
+ setDisabledBeautify(true)
92
+ onChange(e.target.value)
93
+ }}
94
+ min="1"
95
+ placeholder={placeholder}
96
+ />
97
+ <div className={`${styles['actions-container']}`}>
98
+ <button
99
+ type="button"
100
+ className={styles.validate}
101
+ onClick={() => {
102
+ const valid = checkIsValid()
103
+ setIsValid(valid)
104
+ onValidation(valid)
105
+ setDisabledBeautify(!checkIsValid())
106
+ }}
107
+ data-id={`${dataId}-VALIDATE-BUTTON`}
108
+ disabled={value === ''}
109
+ >
110
+ Validate
111
+ </button>
112
+ <button
113
+ type="button"
114
+ disabled={value === '' || disabledBeautify}
115
+ data-id={`${dataId}-BEAUTIFY-BUTTON`}
116
+ className={styles.beautify}
117
+ onClick={handlePrettify}
118
+ >
119
+ Beautify
120
+ </button>
121
+ </div>
122
+ </div>
123
+ {(errorMessage || (value !== '' && isValid === false)) && (
124
+ <p className={styles['error-message']}>{errorMessage || 'Invalid JSON or YAML format'}</p>
125
+ )}
126
+ </div>
127
+ )
128
+ }
129
+
130
+ export default JsonInput
@@ -0,0 +1,123 @@
1
+ .json-editor-container {
2
+ .json-editor-label {
3
+ font-size: 0.875rem;
4
+ font-weight: 600;
5
+ line-height: 1.25rem;
6
+ margin-bottom: 0.3125rem;
7
+ }
8
+
9
+ .json-editor {
10
+ display: flex;
11
+ flex-direction: column;
12
+ background-color: #142452;
13
+ width: 100%;
14
+ border-radius: 0.3125rem;
15
+ margin-bottom: -0.5rem;
16
+ outline: 1px solid transparent;
17
+ position: relative;
18
+
19
+ .actions-container {
20
+ width: 100%;
21
+ height: 5rem;
22
+ padding: 1.25rem;
23
+ border-radius: 0 0 0.3125rem 0.3125rem;
24
+ background: #101e47;
25
+ display: flex;
26
+ flex-direction: row;
27
+ gap: 1.25rem;
28
+ align-items: center;
29
+
30
+ .validate {
31
+ color: #fff;
32
+ text-align: center;
33
+ font-size: 1rem;
34
+ font-style: normal;
35
+ font-weight: 600;
36
+ line-height: 1.25rem;
37
+ width: 8.75rem;
38
+ padding: 0.625rem 2.25rem;
39
+ background-color: rgba(240, 248, 255, 0);
40
+ border-radius: 0.3125rem;
41
+ border: 0.0625rem solid #4d75d8;
42
+ cursor: pointer;
43
+
44
+ &:disabled {
45
+ color: #babdcc;
46
+ border-color: #a2a5b6;
47
+ }
48
+ }
49
+
50
+ .beautify {
51
+ color: #fff;
52
+ text-align: center;
53
+ font-size: 1rem;
54
+ font-style: normal;
55
+ font-weight: 600;
56
+ line-height: 1.25rem;
57
+ width: 8.75rem;
58
+ padding: 0.625rem 2.25rem;
59
+ background-color: rgba(240, 248, 255, 0);
60
+ border-radius: 0.3125rem;
61
+ border: 1px solid #babdcc;
62
+ cursor: pointer;
63
+
64
+ &:disabled {
65
+ color: #a2a5b6;
66
+ border-color: #a2a5b6;
67
+ }
68
+ }
69
+ }
70
+
71
+ textarea {
72
+ width: 100%;
73
+ padding: 1.25rem;
74
+ font-size: 0.875rem;
75
+ font-style: normal;
76
+ font-weight: 400;
77
+ line-height: 1.25rem;
78
+ color: white;
79
+ height: 25rem;
80
+ background-color: #142452;
81
+ border: none;
82
+ resize: none;
83
+ border-radius: 0.3125rem;
84
+
85
+ &:focus,
86
+ &:focus-within,
87
+ &:focus-visible &:active {
88
+ outline: none;
89
+ border: none;
90
+ }
91
+
92
+ &::-webkit-scrollbar {
93
+ width: 0.5rem;
94
+ }
95
+
96
+ &::-webkit-scrollbar-track {
97
+ background-color: #828699;
98
+ border: none;
99
+ border-color: transparent;
100
+ border-top-right-radius: 0.25rem;
101
+ border-top-left-radius: 0;
102
+ }
103
+
104
+ &::-webkit-scrollbar-thumb {
105
+ background-color: #d8dae5;
106
+ border: none;
107
+ border-color: transparent;
108
+ border-radius: 0;
109
+ }
110
+ }
111
+
112
+ &.invalid {
113
+ outline: 1px solid #ce2828 !important;
114
+ }
115
+ }
116
+
117
+ .error-message {
118
+ color: #ce2828;
119
+ font-size: 0.75rem;
120
+ line-height: 1.25rem;
121
+ margin-top: 0.625rem;
122
+ }
123
+ }
@@ -187,6 +187,16 @@
187
187
  border-top: 1px solid #babdcc !important;
188
188
  padding: 1.25rem !important;
189
189
  padding: 0 !important;
190
+
191
+ :global(.jsonField) {
192
+ div {
193
+ textarea {
194
+ border-top-right-radius: 0;
195
+ border-top-left-radius: 0;
196
+ height: 10rem;
197
+ }
198
+ }
199
+ }
190
200
  }
191
201
 
192
202
  :global(.details.show .textArea .containerTextArea) {
@@ -280,10 +290,5 @@
280
290
  }
281
291
  }
282
292
  }
283
-
284
- .methodForm_submitBtn {
285
- height: 1.25rem !important;
286
- width: 4.25rem;
287
- }
288
293
  }
289
294
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useState } from 'react'
2
- import { Accordion, Button, Input, SelectGroup, Switch, TextArea } from 'digitinary-ui'
2
+ import { Accordion, Button, SelectGroup, Switch, TextArea } from 'digitinary-ui'
3
3
  import SVGLoader from '../../components/SVGLoader/SVGLoader'
4
4
  import {
5
5
  CheckMarkSquare,
@@ -11,11 +11,12 @@ import {
11
11
  import { httpStatusCodes, methodColorMapping, paramsTableHeaders } from '../../constants/index'
12
12
  import Tooltip from '../../components/Tooltip/Tooltip'
13
13
  import { TransformedMethod } from '../../types/layout.type'
14
- import styles from './MethodAccordion.module.scss'
15
14
  import SimpleLabelValue from '../../components/SimpleLabelValue'
16
15
  import { capitalize, handleStatusColor } from '../../helpers/methodAccordion.helper'
17
16
  import ParamterTable from '../table/table'
18
17
  import CommonDialog from '../../components/dialog'
18
+ import JsonInput from '../../components/JsonInput/JsonInput'
19
+ import styles from './MethodAccordion.module.scss'
19
20
 
20
21
  const httpStatusCodeOptions = httpStatusCodes.map((code) => ({
21
22
  label: (
@@ -35,13 +36,11 @@ const MethodsAccordion = ({
35
36
  path,
36
37
  setFieldValue,
37
38
  readOnly,
38
- handleSave,
39
39
  }: {
40
40
  method: TransformedMethod
41
41
  path: string
42
42
  setFieldValue: (key: string, value: string) => void
43
43
  readOnly?: boolean
44
- handleSave: (data: any) => unknown
45
44
  }) => {
46
45
  const [isExpanded, setIsExpanded] = useState({
47
46
  request: false,
@@ -54,6 +53,9 @@ const MethodsAccordion = ({
54
53
  const [openDeleteDialog, setOpenDeleteDialog] = useState(false)
55
54
  const [selectedParamIndex, setSelectedParamIndex] = useState<number | null>(null)
56
55
  const [selectedParamName, setSelectedParamName] = useState<string | null>(null)
56
+ const [selectedStatusCode, setSelectedStatusCode] = useState(httpStatusCodeOptions[4])
57
+ const currentResponse =
58
+ method.responses.find((res) => Number(res.code) === selectedStatusCode.value) || '{}'
57
59
 
58
60
  const onTableChange = (key, value, index) => {
59
61
  const newTableData = tableData.map((item, tIndex) => {
@@ -157,10 +159,7 @@ const MethodsAccordion = ({
157
159
  )}
158
160
  </Tooltip>
159
161
 
160
- {
161
- !readOnly&&
162
- <div className={styles.paramDescContainer_separator}></div>
163
- }
162
+ {!readOnly && <div className={styles.paramDescContainer_separator}></div>}
164
163
 
165
164
  {!readOnly && (
166
165
  <Button
@@ -299,19 +298,15 @@ const MethodsAccordion = ({
299
298
  </span>
300
299
  }
301
300
  children={
302
- <TextArea
303
- disabled={readOnly}
304
- value={(() => {
305
- const requestBody = method?.requestBody?.at(0)?.content?.schema?.properties
306
-
307
- if (typeof requestBody !== 'string') {
308
- return JSON.stringify(requestBody)
309
- } else return requestBody
310
- })()}
311
- onChange={(value) => {
312
- setFieldValue('requestBody[0].content.schema.properties', value)
301
+ <JsonInput
302
+ className={'jsonField'}
303
+ placeholder="Enter your request body as a JSON object...."
304
+ fieldIsDisabled={readOnly}
305
+ value={method?.requestBody?.content?.schema?.properties || '{}'}
306
+ onChange={(value: string) => {
307
+ setFieldValue('requestBody.content.schema.properties', value)
313
308
  }}
314
- placeholder="Enter your request body as a JSON object..."
309
+ onValidation={() => null}
315
310
  />
316
311
  }
317
312
  />
@@ -345,51 +340,55 @@ const MethodsAccordion = ({
345
340
  withSearch={false}
346
341
  isMultiple={false}
347
342
  placeholder="200"
348
- disabled={true}
349
343
  options={[
350
344
  {
351
345
  list: httpStatusCodeOptions,
352
346
  },
353
347
  ]}
354
- value={httpStatusCodeOptions[4]}
348
+ value={selectedStatusCode}
349
+ onChange={(value) => {
350
+ setSelectedStatusCode(value)
351
+ }}
355
352
  />
356
353
  </span>
357
354
  }
358
355
  children={
359
- <TextArea
360
- disabled={readOnly}
361
- value={
362
- typeof method.responses?.at(0)?.content.schema.properties !== 'string'
363
- ? JSON.stringify(method.responses?.at(0)?.content.schema.properties)
364
- : method.responses?.at(0)?.content.schema.properties
365
- }
356
+ <JsonInput
357
+ className={'jsonField'}
358
+ placeholder="Enter your response as a JSON object..."
359
+ fieldIsDisabled={readOnly}
360
+ value={currentResponse?.content?.schema?.properties || '{}'}
366
361
  onChange={(value) => {
367
- let parsedValue = { content: '' }
368
- try {
369
- parsedValue = JSON.parse(value)
370
- } catch (err) {
371
- console.log(err)
362
+ const currentResIndex = method.responses.findIndex(
363
+ (res) => res.code === currentResponse.code
364
+ )
365
+
366
+ if (currentResIndex !== -1) {
367
+ setFieldValue(
368
+ `responses[${currentResIndex}].content.schema.properties`,
369
+ value
370
+ )
371
+ } else {
372
+ const clonedResponses = structuredClone(method.responses)
373
+
374
+ clonedResponses.push({
375
+ code: selectedStatusCode.value.toString(),
376
+ content: {
377
+ contentType: 'application/json',
378
+ schema: {
379
+ type: 'object',
380
+ properties: value,
381
+ },
382
+ },
383
+ })
384
+
385
+ setFieldValue('responses', clonedResponses)
372
386
  }
373
- setFieldValue('responses[0].content.schema.properties', parsedValue as any)
374
387
  }}
375
- placeholder="Enter your response as a JSON object..."
388
+ onValidation={() => null}
376
389
  />
377
390
  }
378
391
  />
379
- {!readOnly && (
380
- <Button
381
- className={styles.methodForm_submitBtn}
382
- size="small"
383
- fullWidth={false}
384
- type="submit"
385
- variant="link"
386
- color="success"
387
- onClick={handleSave}
388
- startIcon={<SVGLoader src={CheckMarkSquare} width="1.5rem" height="1.5rem" />}
389
- >
390
- Save
391
- </Button>
392
- )}
393
392
  </div>
394
393
  }
395
394
  />
@@ -2,34 +2,42 @@ export const methodColorMapping = {
2
2
  get: {
3
3
  label: 'Get',
4
4
  color: '#3A6CD1',
5
+ order: 1,
5
6
  },
6
7
  post: {
7
8
  label: 'Post',
8
9
  color: '#3AAA35',
10
+ order: 2,
9
11
  },
10
12
  put: {
11
13
  label: 'Put',
12
14
  color: '#FAAD14',
15
+ order: 3,
13
16
  },
14
17
  delete: {
15
18
  label: 'Delete',
16
19
  color: '#DA3F3F',
20
+ order: 4,
17
21
  },
18
- PATCH: {
22
+ patch: {
19
23
  label: 'Patch',
20
- color: '#FAAD14',
24
+ color: '#58E2C2',
25
+ order: 5,
21
26
  },
22
- OPTIONS: {
27
+ options: {
23
28
  label: 'Options',
24
- color: '#FAAD14',
29
+ color: '#495D97',
30
+ order: 6,
25
31
  },
26
- TRACE: {
32
+ trace: {
27
33
  label: 'Trace',
28
- color: '#FAAD14',
34
+ color: '#FFA28F',
35
+ order: 7,
29
36
  },
30
- HEAD: {
37
+ head: {
31
38
  label: 'Head',
32
- color: '#FAAD14',
39
+ color: '#9461C9',
40
+ order: 8,
33
41
  },
34
42
  }
35
43