Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New possibility to add enums with labels through oneof #928

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 43 additions & 19 deletions src/components/schema-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,27 @@ export default class SchemaTable extends LitElement {
let keyLabel = '';
let keyDescr = '';
let isOneOfLabel = false;
let isOneOfEnum = false;
let isOneOfEnumOption = false;
if (key.startsWith('::ONE~OF') || key.startsWith('::ANY~OF')) {
keyLabel = key.replace('::', '').replace('~', ' ');
isOneOfLabel = true;
if (key.startsWith('::ONE~OF~ENUM')) {
isOneOfEnum = true;
keyLabel = 'ENUM';
} else {
keyLabel = key.replace('::', '').replace('~', ' ');
isOneOfLabel = true;
}
} else if (key.startsWith('::OPTION')) {
const parts = key.split('~');
keyLabel = parts[1]; // eslint-disable-line prefer-destructuring
keyDescr = parts[2]; // eslint-disable-line prefer-destructuring
if (parts[1] === 'ONEOFENUM') {
isOneOfEnumOption = true;
keyLabel = parts[2]; // eslint-disable-line prefer-destructuring
keyDescr = parts[3]; // eslint-disable-line prefer-destructuring
description = parts[4]; // eslint-disable-line prefer-destructuring
} else {
keyLabel = parts[1]; // eslint-disable-line prefer-destructuring
keyDescr = parts[2]; // eslint-disable-line prefer-destructuring
}
} else {
keyLabel = key;
}
Expand All @@ -198,9 +212,9 @@ export default class SchemaTable extends LitElement {
return html`
${newSchemaLevel >= 0 && key
? html`
<div class='tr ${newSchemaLevel <= this.schemaExpandLevel ? 'expanded' : 'collapsed'} ${data['::type']}' data-obj='${keyLabel}' title="${data['::deprecated'] ? 'Deprecated' : ''}">
<div class='tr ${isOneOfEnum || newSchemaLevel <= this.schemaExpandLevel ? 'expanded' : 'collapsed'} ${data['::type']}' data-obj='${keyLabel}' title="${data['::deprecated'] ? 'Deprecated' : ''}">
<div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style='padding-left:${leftPadding}px'>
${(keyLabel || keyDescr)
${!isOneOfEnum && (keyLabel || keyDescr)
? html`
<span class='obj-toggle ${newSchemaLevel < this.schemaExpandLevel ? 'expanded' : 'collapsed'}' data-obj='${keyLabel}'>
${schemaLevel < this.schemaExpandLevel ? '-' : '+'}
Expand Down Expand Up @@ -287,6 +301,11 @@ export default class SchemaTable extends LitElement {
<div class='td key-type ${dataTypeCss}' title="${readOrWrite === 'readonly' ? 'Read-Only' : readOrWriteOnly === 'writeonly' ? 'Write-Only' : ''}">
[${type}] ${readOrWrite === 'readonly' ? '🆁' : readOrWrite === 'writeonly' ? '🆆' : ''}
</div>`;
} else if (isOneOfEnumOption) {
dataTypeHtml = html`
<div class='td key-type ${dataTypeCss}' title="${readOrWriteOnly === '🆁' ? 'Read-Only' : readOrWriteOnly === '🆆' ? 'Write-Only' : ''}">
<span class='xxx-of-key'>${allowedValues}</span> ${readOrWriteOnly}
</div>`;
} else {
dataTypeHtml = html`
<div class='td key-type ${dataTypeCss}' title="${readOrWriteOnly === '🆁' ? 'Read-Only' : readOrWriteOnly === '🆆' ? 'Write-Only' : ''}">
Expand All @@ -302,24 +321,29 @@ export default class SchemaTable extends LitElement {
<span class="key-label">${keyLabel.substring(0, keyLabel.length - 1)}</span>
<span style='color:var(--red);'>*</span>`
: key.startsWith('::OPTION')
? html`<span class='xxx-of-key'>${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>`
? html` ${isOneOfEnumOption ? '' : html`<span class='xxx-of-key'>${keyLabel}</span>`}
<span class="xxx-of-descr">${keyDescr}</span>`
: html`${keyLabel ? html`<span class="key-label"> ${keyLabel}</span>` : html`<span class="xxx-of-descr">${schemaTitle}</span>`}`
}
</div>
${dataTypeHtml}
<div class='td key-descr' style='font-size: var(--font-size-small)'>
${html`<span class="m-markdown-small">
${unsafeHTML(marked(dataType === 'array'
? `${descrExpander} ${description}`
: schemaTitle
? `${descrExpander} <b>${schemaTitle}:</b> ${schemaDescription}`
: `${descrExpander} ${schemaDescription}`))}
</span>`
}
${constraint ? html`<div class='' style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>Constraints: </span> ${constraint}</div>` : ''}
${defaultValue ? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>Default: </span>${defaultValue}</div>` : ''}
${allowedValues ? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>${type === 'const' ? 'Value' : 'Allowed'}: </span>${allowedValues}</div>` : ''}
${pattern ? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>Pattern: </span>${pattern}</div>` : ''}
${isOneOfEnumOption
? html`<span class="m-markdown-small">${description}</span>`
: html`
${html`<span class="m-markdown-small">
${unsafeHTML(marked(dataType === 'array'
? `${descrExpander} ${description}`
: schemaTitle
? `${descrExpander} <b>${schemaTitle}:</b> ${schemaDescription}`
: `${descrExpander} ${schemaDescription}`))}
</span>`
}
${constraint ? html`<div class='' style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>Constraints: </span> ${constraint}</div>` : ''}
${defaultValue ? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>Default: </span>${defaultValue}</div>` : ''}
${allowedValues ? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>${type === 'const' ? 'Value' : 'Allowed'}: </span>${allowedValues}</div>` : ''}
${pattern ? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>Pattern: </span>${pattern}</div>` : ''}
`}
</div>
</div>
`;
Expand Down
22 changes: 17 additions & 5 deletions src/utils/schema-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function getTypeInfo(schema) {
info.description = info.description || '';
}
// Set Allowed Values
info.allowedValues = schema.const
info.allowedValues = schema.const !== undefined
? schema.const
: Array.isArray(schema.enum)
? schema.enum.map((v) => (getPrintableVal(v))).join('┃')
Expand Down Expand Up @@ -699,6 +699,8 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') {
// 2. Then show allof/anyof objects
const objWithAnyOfProps = {};
const xxxOf = schema.anyOf ? 'anyOf' : 'oneOf';
// if it is a oneOf with only constants, it can be interpreted as an enum with labels
const xxxOfEnum = schema.oneOf && schema.oneOf.every((v) => (v.type === 'const' && v.const !== undefined));
schema[xxxOf].forEach((v, index) => {
if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf) {
const partialObj = schemaInObjectNotation(v, {});
Expand All @@ -712,14 +714,24 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') {
objWithAnyOfProps[`::OPTION~${index + 1}${v.title ? `~${v.title}` : ''}`]['::readwrite'] = ''; // xxx-options cannot be read or write only
objWithAnyOfProps['::type'] = 'xxx-of-array';
} else {
const prop = `::OPTION~${index + 1}${v.title ? `~${v.title}` : ''}`;
let prop = `::OPTION~${index + 1}${v.title ? `~${v.title}` : ''}`;
if (xxxOfEnum) {
prop = `::OPTION~ONEOFENUM~${index + 1}${v.title ? `~${v.title}` : ''}${v.description ? `~${v.description}` : ''}`;
}
objWithAnyOfProps[prop] = `${getTypeInfo(v).html}`;
objWithAnyOfProps['::type'] = 'xxx-of-option';
}
});
obj[(schema.anyOf ? `::ANY~OF ${suffix}` : `::ONE~OF ${suffix}`)] = objWithAnyOfProps;
// obj['::type'] = 'object';
obj['::type'] = 'object';
let objKey = schema.anyOf ? `::ANY~OF ${suffix}` : `::ONE~OF ${suffix}`;

if (xxxOfEnum) {
obj['::type'] = 'object';
obj['::dataTypeLabel'] = 'enum';
objKey = `::ONE~OF~ENUM ${suffix}`;
} else {
obj['::type'] = 'object';
}
obj[objKey] = objWithAnyOfProps;
} else if (Array.isArray(schema.type)) {
// When a property has multiple types, then check further if any of the types are array or object, if yes then modify the schema using one-of
// Clone the schema - as it will be modified to replace multi-data-types with one-of;
Expand Down