1import MDX from '@mdx-js/runtime';
2import * as React from 'react';
3
4import * as components from '~/common/translate-markdown';
5import { Cell, HeaderCell, Row, Table, TableHead } from '~/ui/components/Table';
6
7export type Property = {
8  description?: string[];
9  name: string;
10  type?: string | string[];
11  enum?: string[];
12  properties?: Property[];
13};
14
15type FormattedProperty = {
16  name: string;
17  description: string;
18  nestingLevel: number;
19};
20
21export function formatSchema(rawSchema: Property[]) {
22  const formattedSchema: FormattedProperty[] = [];
23
24  rawSchema.map(property => {
25    appendProperty(formattedSchema, property, 0);
26  });
27
28  return formattedSchema;
29}
30
31//appends a property and recursively appends sub-properties
32function appendProperty(
33  formattedSchema: FormattedProperty[],
34  property: Property,
35  _nestingLevel: number
36) {
37  let nestingLevel = _nestingLevel;
38
39  formattedSchema.push({
40    name: nestingLevel
41      ? `<subpropertyAnchor level={${nestingLevel}}><inlineCode>${property.name}</inlineCode></subpropertyAnchor>`
42      : `<propertyAnchor level={0}><inlineCode>${property.name}</inlineCode></propertyAnchor>`,
43    description: createDescription(property),
44    nestingLevel,
45  });
46
47  nestingLevel++;
48
49  if (property.properties) {
50    (property.properties ?? []).forEach(subproperty => {
51      appendProperty(formattedSchema, subproperty, nestingLevel);
52    });
53  }
54}
55
56export function _getType(property: Property) {
57  if (property.enum) {
58    return `enum: ${property.enum.join(', ')}`;
59  } else {
60    return property.type?.toString().replace(/,/g, ' || ');
61  }
62}
63
64export function createDescription(property: Property) {
65  let propertyDescription = `**(${_getType(property)})**`;
66  if (property.description) {
67    propertyDescription += ` - ` + property.description.join('\n');
68  }
69
70  return propertyDescription;
71}
72
73export default class EasJsonPropertiesTable extends React.Component<{
74  schema: Property[];
75}> {
76  render() {
77    const formattedSchema = formatSchema(this.props.schema);
78
79    return (
80      <Table>
81        <TableHead>
82          <Row>
83            <HeaderCell>Property</HeaderCell>
84            <HeaderCell>Description</HeaderCell>
85          </Row>
86        </TableHead>
87        <tbody>
88          {formattedSchema.map((property, index) => {
89            return (
90              <Row key={index}>
91                <Cell fitContent>
92                  <div
93                    data-testid={property.name}
94                    style={{
95                      marginLeft: `${property.nestingLevel * 32}px`,
96                      display: property.nestingLevel ? 'list-item' : 'block',
97                      listStyleType: property.nestingLevel % 2 ? 'default' : 'circle',
98                      overflowX: 'visible',
99                    }}>
100                    <MDX components={components}>{property.name}</MDX>
101                  </div>
102                </Cell>
103                <Cell>
104                  <MDX components={components}>{property.description}</MDX>
105                </Cell>
106              </Row>
107            );
108          })}
109        </tbody>
110      </Table>
111    );
112  }
113}
114