@digi-frontend/dgate-api-documentation 1.0.21 → 1.0.26

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/src/components/InfoForm/InfoForm.js +1 -1
  2. package/dist/src/components/InfoForm/InfoForm.js.map +1 -1
  3. package/dist/src/components/JsonInput/JsonInput.js +1 -1
  4. package/dist/src/components/JsonInput/JsonInput.js.map +1 -1
  5. package/dist/src/components/LivePreview/LivePreview.js +1 -1
  6. package/dist/src/components/LivePreview/LivePreview.js.map +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/components/Tooltip/Tooltip.js.map +1 -1
  10. package/dist/src/components/table/table.js +1 -1
  11. package/dist/src/components/table/table.js.map +1 -1
  12. package/dist/src/components/table/tags-table.js +1 -1
  13. package/dist/src/components/table/tags-table.js.map +1 -1
  14. package/dist/src/constants/regex.js +1 -1
  15. package/dist/src/constants/regex.js.map +1 -1
  16. package/dist/src/helpers/layout.helper.js +1 -1
  17. package/dist/src/helpers/layout.helper.js.map +1 -1
  18. package/dist/src/layout/layout.js +1 -1
  19. package/dist/src/layout/layout.js.map +1 -1
  20. package/dist/src/layout/layout.module.css.js +1 -1
  21. package/dist/src/validator/form.scheme.js +1 -1
  22. package/dist/src/validator/form.scheme.js.map +1 -1
  23. package/dist/styles.css +344 -311
  24. package/dist/types/components/MethodAccordion/MethodAccordion.d.ts +3 -1
  25. package/dist/types/components/Tooltip/Tooltip.d.ts +2 -2
  26. package/dist/types/constants/regex.d.ts +2 -0
  27. package/dist/types/validator/form.scheme.d.ts +1 -1
  28. package/package.json +2 -2
  29. package/src/components/InfoForm/InfoForm.module.scss +24 -1
  30. package/src/components/InfoForm/InfoForm.tsx +89 -47
  31. package/src/components/JsonInput/JsonInput.tsx +18 -7
  32. package/src/components/LivePreview/LivePreview.module.scss +18 -5
  33. package/src/components/LivePreview/LivePreview.tsx +47 -25
  34. package/src/components/MethodAccordion/MethodAccordion.tsx +103 -67
  35. package/src/components/Tooltip/Tooltip.scss +12 -9
  36. package/src/components/Tooltip/Tooltip.tsx +2 -3
  37. package/src/components/table/style.scss +1 -1
  38. package/src/components/table/table.tsx +11 -8
  39. package/src/components/table/tags-table.tsx +49 -14
  40. package/src/constants/regex.ts +2 -0
  41. package/src/helpers/layout.helper.ts +1 -1
  42. package/src/layout/layout.module.css +5 -0
  43. package/src/layout/layout.tsx +45 -7
  44. package/src/validator/form.scheme.ts +9 -9
@@ -1,10 +1,12 @@
1
1
  import { TransformedMethod } from '../../types/layout.type';
2
2
  import { Tags } from '@entities/openApi';
3
- declare const MethodsAccordion: ({ method, path, setFieldValue, readOnly, tags, }: {
3
+ declare const MethodsAccordion: ({ method, path, setFieldValue, readOnly, tags, isOpen, setIsOpen, }: {
4
4
  method: TransformedMethod;
5
5
  path: string;
6
6
  setFieldValue?: (key: string, value: string | string[]) => void;
7
7
  readOnly?: boolean;
8
8
  tags: Tags[];
9
+ isOpen: boolean;
10
+ setIsOpen: (open: boolean) => void;
9
11
  }) => import("react/jsx-runtime").JSX.Element;
10
12
  export default MethodsAccordion;
@@ -1,8 +1,8 @@
1
1
  import React, { ReactNode } from 'react';
2
+ import { TippyProps } from '@tippyjs/react';
2
3
  import 'tippy.js/dist/tippy.css';
3
4
  import './Tooltip.scss';
4
- interface TooltipProps {
5
- children: ReactNode;
5
+ interface TooltipProps extends TippyProps {
6
6
  content: ReactNode;
7
7
  success?: boolean;
8
8
  onMouseEnter?: (event: React.MouseEvent<HTMLDivElement>) => void;
@@ -1,5 +1,7 @@
1
1
  declare const regex: {
2
2
  basic: RegExp;
3
3
  restrictNone: RegExp;
4
+ ASCII: RegExp;
5
+ urlRegex: RegExp;
4
6
  };
5
7
  export default regex;
@@ -1,4 +1,4 @@
1
- import * as yup from "yup";
1
+ import * as yup from 'yup';
2
2
  export declare const schemaValidation: yup.ObjectSchema<{
3
3
  openapi: string;
4
4
  info: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "name": "@digi-frontend/dgate-api-documentation",
3
- "version": "1.0.21",
2
+ "name": "@digi-frontend/dgate-api-documentation",
3
+ "version": "1.0.26",
4
4
  "main": "dist/src/index.js",
5
5
  "module": "dist/src/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  display: flex;
29
29
  align-items: center;
30
30
  padding: 0;
31
- color: #12131a;
31
+ font-size: 0.875rem;
32
32
 
33
33
  :global(.endBtnIcon) {
34
34
  margin-block: auto;
@@ -44,6 +44,7 @@
44
44
 
45
45
  &.deleteParamBtn {
46
46
  padding: 0;
47
+ border-width: 0 !important;
47
48
 
48
49
  :global(.btnContentWrapper) {
49
50
  :global(.endBtnIcon) {
@@ -71,6 +72,28 @@
71
72
  }
72
73
  }
73
74
 
75
+ .externalDocsLink {
76
+ font-size: 0.875rem;
77
+ line-height: 1.25rem;
78
+ cursor: pointer;
79
+ align-self: center;
80
+ margin-right: 2rem;
81
+ }
82
+
83
+ .editExternalDocs {
84
+ display: flex;
85
+ align-items: center;
86
+ padding-right: 0.625rem;
87
+
88
+ svg {
89
+ cursor: pointer;
90
+
91
+ path {
92
+ fill: #12131a;
93
+ }
94
+ }
95
+ }
96
+
74
97
  .editDescTooltipContent {
75
98
  display: flex;
76
99
  flex-direction: column;
@@ -44,7 +44,6 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
44
44
 
45
45
  useEffect(() => {
46
46
  if (values.tags && values.tags.length) {
47
- setTableRecords(generateTableRecords(values.tags))
48
47
  setTableData(values.tags)
49
48
  }
50
49
  }, [values.tags])
@@ -97,6 +96,26 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
97
96
  tagName: item.name,
98
97
  description: (
99
98
  <div className={styles.paramDescContainer}>
99
+ <Tooltip
100
+ key={`${index}-description`}
101
+ allowHTML
102
+ disabled={values.tags[index].description?.length <= 12}
103
+ content={<div style={{ padding: '0.625rem' }}>{values.tags[index].description}</div>}
104
+ arrowWithBorder
105
+ placement="bottom-end"
106
+ type="function"
107
+ delay={[0, 0]}
108
+ onShow={() => tooltipRefs[index]?.hide()}
109
+ >
110
+ <p style={{ alignSelf: 'center', fontWeight: 600, fontSize: '1rem' }}>
111
+ {values.tags[index].description
112
+ ? values.tags[index].description.substring(0, 12)
113
+ : readOnly && '-'}
114
+ {values.tags[index].description && values.tags[index].description.length > 12
115
+ ? '...'
116
+ : ''}
117
+ </p>
118
+ </Tooltip>
100
119
  <Tooltip
101
120
  arrowWithBorder
102
121
  placement="bottom-end"
@@ -113,10 +132,14 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
113
132
  <div className={styles.editDescTooltipContent}>
114
133
  <p className={styles.editDescTooltipContent_header}>Description</p>
115
134
  <TextArea
116
- placeholder="Describe parameter..."
135
+ placeholder="Describe tag..."
117
136
  value={item.description}
118
137
  disabled={readOnly}
119
- onChange={(value) => onTableChange('description', value, index)}
138
+ onChange={(value) => {
139
+ if (value === '' || regex.ASCII.test(value))
140
+ onTableChange('description', value, index)
141
+ }}
142
+ maxLength={25}
120
143
  />
121
144
  {!readOnly && (
122
145
  <Button
@@ -124,9 +147,10 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
124
147
  variant="outlined"
125
148
  size="small"
126
149
  onClick={() => {
127
- setFieldValue(`tags[${index}].description`, item.description)
150
+ setFieldValue(`tags[${index}].description`, item.description?.trim())
128
151
  tooltipRefs[index]?.hide()
129
152
  }}
153
+ disabled={!item.description?.trim()}
130
154
  >
131
155
  Apply
132
156
  </Button>
@@ -140,14 +164,7 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
140
164
  variant="link"
141
165
  color="action"
142
166
  endIcon={<SVGLoader src={EditIcon} width="1.5rem" height="1.5rem" />}
143
- >
144
- {values.tags[index].description
145
- ? values.tags[index].description.substring(0, 12)
146
- : '-'}
147
- {values.tags[index].description && values.tags[index].description.length > 12
148
- ? '...'
149
- : ''}
150
- </Button>
167
+ ></Button>
151
168
  ) : (
152
169
  <Button
153
170
  className={styles.editDescBtn}
@@ -165,6 +182,24 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
165
182
  ),
166
183
  externalDocs: (
167
184
  <div className={styles.paramDescContainer}>
185
+ <a
186
+ className={styles.externalDocsLink}
187
+ href={values.tags[index].externalDocs?.url}
188
+ target="_blank"
189
+ style={
190
+ !values.tags[index].externalDocs?.description
191
+ ? { textDecoration: 'none', pointerEvents: 'none' }
192
+ : {}
193
+ }
194
+ >
195
+ {values.tags[index].externalDocs?.description
196
+ ? values.tags[index].externalDocs?.description?.substring(0, 12)
197
+ : '-'}
198
+ {values.tags[index].externalDocs?.description &&
199
+ values.tags[index].externalDocs?.description?.length > 12
200
+ ? '...'
201
+ : ''}
202
+ </a>
168
203
  <Tooltip
169
204
  arrowWithBorder
170
205
  placement="bottom-end"
@@ -184,13 +219,16 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
184
219
  placeholder="Describe External Doc..."
185
220
  value={item.externalDocs?.description}
186
221
  disabled={readOnly}
222
+ maxLength={25}
187
223
  onChange={(value) => {
188
- onTableChange(
189
- 'externalDocs',
190
- { ...item.externalDocs, description: value },
191
- index
192
- )
193
- setDescription(value)
224
+ if (value === '' || regex.ASCII.test(value)) {
225
+ onTableChange(
226
+ 'externalDocs',
227
+ { ...item.externalDocs, description: value },
228
+ index
229
+ )
230
+ setDescription(value)
231
+ }
194
232
  }}
195
233
  />
196
234
  <p className={styles.editDescTooltipContent_header}>External Docs Link</p>
@@ -198,9 +236,12 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
198
236
  placeholder="External Docs Link..."
199
237
  value={item.externalDocs?.url}
200
238
  disabled={readOnly}
239
+ maxLength={200}
201
240
  onChange={(value) => {
202
- onTableChange('externalDocs', { ...item.externalDocs, url: value }, index)
203
- setURL(value)
241
+ if (value === '' || regex.ASCII.test(value)) {
242
+ onTableChange('externalDocs', { ...item.externalDocs, url: value }, index)
243
+ setURL(value)
244
+ }
204
245
  }}
205
246
  />
206
247
  {!readOnly && (
@@ -210,13 +251,14 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
210
251
  size="small"
211
252
  onClick={() => {
212
253
  setFieldValue(`tags[${index}].externalDocs`, {
213
- description: description,
214
- url: url,
254
+ description: description?.trim(),
255
+ url: url?.trim(),
215
256
  })
216
257
  setDescription('')
217
258
  setURL('')
218
259
  externalTooltipRefs[index]?.hide()
219
260
  }}
261
+ disabled={!description?.trim() || !url?.trim() || !regex.urlRegex.test(url)}
220
262
  >
221
263
  Apply
222
264
  </Button>
@@ -225,24 +267,18 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
225
267
  }
226
268
  >
227
269
  {readOnly || values.tags[index].externalDocs?.description ? (
228
- <Button
229
- className={styles.editDescBtn}
230
- variant="link"
231
- color="action"
232
- endIcon={<SVGLoader src={EditIcon} width="1.5rem" height="1.5rem" />}
233
- onClick={() => {
234
- setDescription(item.externalDocs?.description)
235
- setURL(item.externalDocs?.url)
236
- }}
237
- >
238
- {values.tags[index].externalDocs?.description
239
- ? values.tags[index].externalDocs?.description?.substring(0, 12)
240
- : '-'}
241
- {values.tags[index].externalDocs?.description &&
242
- values.tags[index].externalDocs?.description?.length > 12
243
- ? '...'
244
- : ''}
245
- </Button>
270
+ <div className={styles.editExternalDocs}>
271
+ <SVGLoader
272
+ src={EditIcon}
273
+ width="1.5rem"
274
+ height="1.5rem"
275
+ onClick={(e) => {
276
+ e?.stopPropagation()
277
+ setDescription(item.externalDocs?.description)
278
+ setURL(item.externalDocs?.url)
279
+ }}
280
+ />
281
+ </div>
246
282
  ) : (
247
283
  <Button
248
284
  className={styles.editDescBtn}
@@ -287,7 +323,7 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
287
323
  label="API Name"
288
324
  required
289
325
  value={values?.info?.title}
290
- maxLength={25}
326
+ maxLength={35}
291
327
  onChange={(value) => {
292
328
  setFieldValue('info.title', value)
293
329
  }}
@@ -295,7 +331,7 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
295
331
  setFieldValue('info.title', '')
296
332
  }}
297
333
  errorMsg={errors?.info?.title}
298
- restrictedCharsRegex={regex.basic}
334
+ restrictedCharactersRegex={regex.basic}
299
335
  />
300
336
  <div className={styles.apiDocRow}>
301
337
  <Input
@@ -313,14 +349,16 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
313
349
  label="Description"
314
350
  value={values?.info?.description}
315
351
  maxLength={120}
352
+ required
316
353
  onChange={(value: string) => {
317
- setFieldValue('info.description', value)
354
+ if (value === '' || regex.ASCII.test(value)) {
355
+ setFieldValue('info.description', value)
356
+ }
318
357
  }}
319
358
  onClear={() => {
320
359
  setFieldValue('info.description', '')
321
360
  }}
322
361
  errorMessage={errors?.info?.description}
323
- restrictedCharsRegex={regex.restrictNone}
324
362
  />
325
363
  <div className={styles.paramsTable}>
326
364
  <TagsTable
@@ -346,17 +384,21 @@ const InfoForm = ({ readOnly }: { readOnly?: boolean }) => {
346
384
  className="delete-msg-container"
347
385
  >
348
386
  Are you sure you want to delete
349
- <span className="plan-name">{` Tag ${selectedTagName} `}</span>?
387
+ <span className="plan-name">
388
+ {' '}
389
+ Tag <strong>{selectedTagName}</strong>
390
+ </span>
391
+ ?
350
392
  </p>
351
393
  }
352
394
  onSubmit={{
353
395
  onClick: confirmDeleteTag,
354
- text: 'Yes',
396
+ text: 'Delete',
355
397
  color: 'error',
356
398
  fullWidth: true,
357
399
  }}
358
400
  onCancel={{
359
- text: 'No',
401
+ text: 'Cancel',
360
402
  color: 'normal',
361
403
  fullWidth: true,
362
404
  }}
@@ -1,6 +1,13 @@
1
1
  import React, { useEffect, useState } from 'react'
2
2
  import yaml from 'js-yaml'
3
3
  import styles from './style.module.scss'
4
+ import regex from '../../constants/regex'
5
+
6
+ const errorMapping = {
7
+ BOTH: 'Invalid JSON or YAML format',
8
+ JSON: 'Invalid JSON format',
9
+ YML: 'Invalid YAML format',
10
+ }
4
11
 
5
12
  const JsonInput = ({
6
13
  placeholder,
@@ -87,15 +94,19 @@ const JsonInput = ({
87
94
  value={value}
88
95
  onChange={(e) => {
89
96
  if (fieldIsDisabled) return
90
- setIsValid(undefined)
91
- setDisabledBeautify(true)
92
- onChange(e.target.value)
97
+ if (regex.ASCII.test(e.target.value)) {
98
+ setIsValid(undefined)
99
+ setDisabledBeautify(true)
100
+ onChange(e.target.value)
101
+ }
93
102
  }}
94
103
  onPaste={(e) => {
95
104
  if (fieldIsDisabled) return
96
- setIsValid(undefined)
97
- setDisabledBeautify(true)
98
- onChange(e.target.value)
105
+ if (regex.ASCII.test(e.target.value)) {
106
+ setIsValid(undefined)
107
+ setDisabledBeautify(true)
108
+ onChange(e.target.value)
109
+ }
99
110
  }}
100
111
  min="1"
101
112
  placeholder={placeholder}
@@ -129,7 +140,7 @@ const JsonInput = ({
129
140
  )}
130
141
  </div>
131
142
  {(errorMessage || (value !== '' && isValid === false)) && (
132
- <p className={styles['error-message']}>{errorMessage || 'Invalid JSON or YAML format'}</p>
143
+ <p className={styles['error-message']}>{errorMessage || errorMapping[acceptType]}</p>
133
144
  )}
134
145
  </div>
135
146
  )
@@ -1,5 +1,18 @@
1
- p.apiName {
2
- font-size: 40px;
3
- line-height: 30px;
4
- font-weight: 500;
5
- }
1
+ .livePreviewContainer {
2
+ .titleContainer {
3
+ display: flex;
4
+ justify-content: space-between;
5
+ align-items: center;
6
+
7
+ p.apiName {
8
+ font-size: 40px;
9
+ line-height: 30px;
10
+ font-weight: 500;
11
+ }
12
+
13
+ .livePreviewChip {
14
+ background-color: #ebecf2;
15
+ color: #12131a;
16
+ }
17
+ }
18
+ }
@@ -6,7 +6,8 @@ import { TransformedOpenApi } from '../../types/transformedOpenApi'
6
6
  import { useFormikContext } from 'formik'
7
7
  import { methodColorMapping, tagsTableHeaders } from '../../constants/index'
8
8
  import TagsTable from '../table/tags-table'
9
- import { Button } from 'digitinary-ui'
9
+ import { Button, Chip } from 'digitinary-ui'
10
+ import Tooltip from '../../components/Tooltip/Tooltip'
10
11
 
11
12
  interface LivePreviewProps {
12
13
  transformedData?: TransformedOpenApi
@@ -37,12 +38,23 @@ const LivePreview: React.FC<LivePreviewProps> = ({ transformedData }) => {
37
38
  id: index,
38
39
  tagName: item.name,
39
40
  description: (
40
- <div className={styles.paramDescContainer}>
41
- <Button className={styles.editDescBtn} variant="link" color="action">
42
- {item.description ? item.description.substring(0, 12) : '-'}
43
- {item.description && item.description.length > 12 ? '...' : ''}
44
- </Button>
45
- </div>
41
+ <Tooltip
42
+ key={`${index}-description`}
43
+ allowHTML
44
+ disabled={item.description?.length <= 12}
45
+ content={<div style={{ padding: '0.625rem' }}>{item.description}</div>}
46
+ arrowWithBorder
47
+ placement="bottom-end"
48
+ type="function"
49
+ delay={[0, 0]}
50
+ >
51
+ <div className={styles.paramDescContainer}>
52
+ <p className={styles.editDescBtn}>
53
+ {item.description ? item.description.substring(0, 12) : '-'}
54
+ {item.description && item.description.length > 12 ? '...' : ''}
55
+ </p>
56
+ </div>
57
+ </Tooltip>
46
58
  ),
47
59
  externalDocs: (
48
60
  <div className={styles.paramDescContainer}>
@@ -91,21 +103,29 @@ const LivePreview: React.FC<LivePreviewProps> = ({ transformedData }) => {
91
103
  ),
92
104
  }))
93
105
  }
106
+
94
107
  return (
95
- <div>
108
+ <div className={styles.livePreviewContainer}>
96
109
  <div className="row">
97
110
  <div className="col-md-12">
98
- <p className={styles.apiName}>{info?.title}</p>
111
+ <div className={styles.titleContainer}>
112
+ <p className={styles.apiName}>{info?.title?.trim() || '-'}</p>
113
+ <Chip className={styles.livePreviewChip}>Live Preview</Chip>
114
+ </div>
99
115
  <SimpleLabelValue
100
116
  key={'APIAuthenticationType'}
101
117
  label={'API authentication type: '}
102
- value={!!securityKey ? securitySchemes[securityKey].scheme : '-'}
118
+ value={
119
+ !!securityKey
120
+ ? securitySchemes[securityKey].scheme || securitySchemes[securityKey].type
121
+ : '-'
122
+ }
103
123
  />
104
124
  <SimpleLabelValue key={'version'} label={'Version: '} value={info?.version || '-'} />
105
125
  <SimpleLabelValue
106
126
  key={'description'}
107
127
  label={'Description: '}
108
- value={info?.description || '-'}
128
+ value={info?.description?.trim() || '-'}
109
129
  />
110
130
 
111
131
  <SimpleLabelValue key={'tags'} label={'Tags: '} />
@@ -124,20 +144,22 @@ const LivePreview: React.FC<LivePreviewProps> = ({ transformedData }) => {
124
144
  <div className={styles.methodsContainer} key={path.path}>
125
145
  {Object.entries(
126
146
  path.methods
127
- .sort((a, b) => methodColorMapping[a.type].order + methodColorMapping[b.type].order)
128
- .reduce((groupedMethods, method) => {
129
- // Handle methods without tags
130
- const tags = method.tags?.length ? method?.tags : ['default'];
131
-
132
- tags.forEach((tag) => {
133
- if (!groupedMethods[tag]) {
134
- groupedMethods[tag] = [];
135
- }
136
- groupedMethods[tag].push(method);
137
- });
138
-
139
- return groupedMethods;
140
- }, {})
147
+ .sort(
148
+ (a, b) => methodColorMapping[a.type].order + methodColorMapping[b.type].order
149
+ )
150
+ .reduce((groupedMethods, method) => {
151
+ // Handle methods without tags
152
+ const tags = method.tags?.length ? method?.tags : ['default']
153
+
154
+ tags.forEach((tag) => {
155
+ if (!groupedMethods[tag]) {
156
+ groupedMethods[tag] = []
157
+ }
158
+ groupedMethods[tag].push(method)
159
+ })
160
+
161
+ return groupedMethods
162
+ }, {})
141
163
  ).map(([tag, methods]) => (
142
164
  <div key={tag}>
143
165
  <h3>{tag}</h3>