feat: basic UI labels configuration

This can be used for translations later
This commit is contained in:
Roman Hotsiy 2019-05-12 21:19:36 +03:00
parent fdcac30829
commit b0e660eca0
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
6 changed files with 62 additions and 12 deletions

View File

@ -1,6 +1,8 @@
import * as React from 'react';
import { ExampleValue, FieldLabel } from '../../common-elements/fields';
import { l } from '../../services/Labels';
export interface EnumValuesProps {
values: string[];
type: string;
@ -16,12 +18,11 @@ export class EnumValues extends React.PureComponent<EnumValuesProps> {
return (
<div>
<FieldLabel>
{type === 'array' ? 'Items' : ''} {values.length === 1 ? 'Value' : 'Enum'}:
</FieldLabel>{' '}
{type === 'array' ? l('enumArray') : ''}{' '}
{values.length === 1 ? l('enumSingleValue') : l('enum')}:
</FieldLabel>
{values.map((value, idx) => (
<ExampleValue key={idx}>
{JSON.stringify(value)}
</ExampleValue>
<ExampleValue key={idx}>{JSON.stringify(value)}</ExampleValue>
))}
</div>
);

View File

@ -19,6 +19,8 @@ import { FieldDetail } from './FieldDetail';
import { Badge } from '../../common-elements/';
import { l } from '../../services/Labels';
export class FieldDetails extends React.PureComponent<FieldProps> {
render() {
const { showExamples, field, renderDiscriminatorSwitch } = this.props;
@ -40,18 +42,18 @@ export class FieldDetails extends React.PureComponent<FieldProps> {
)}
{schema.title && <TypeTitle> ({schema.title}) </TypeTitle>}
<ConstraintsView constraints={schema.constraints} />
{schema.nullable && <NullableLabel> Nullable </NullableLabel>}
{schema.nullable && <NullableLabel> {l('nullable')} </NullableLabel>}
{schema.pattern && <PatternLabel>{schema.pattern}</PatternLabel>}
{schema.isCircular && <RecursiveLabel> Recursive </RecursiveLabel>}
{schema.isCircular && <RecursiveLabel> {l('recursive')} </RecursiveLabel>}
</div>
{deprecated && (
<div>
<Badge type="warning"> Deprecated </Badge>
<Badge type="warning"> {l('deprecated')} </Badge>
</div>
)}
<FieldDetail label={'Default:'} value={schema.default} />
<FieldDetail label={l('default') + ':'} value={schema.default} />
{!renderDiscriminatorSwitch && <EnumValues type={schema.type} values={schema.enum} />}{' '}
{showExamples && <FieldDetail label={'Example:'} value={example} />}
{showExamples && <FieldDetail label={l('example') + ':'} value={example} />}
{<Extensions extensions={{ ...field.extensions, ...schema.extensions }} />}
<div>
<Markdown compact={true} source={description} />

View File

@ -10,6 +10,8 @@ import { ArraySchema } from './ArraySchema';
import { ObjectSchema } from './ObjectSchema';
import { OneOfSchema } from './OneOfSchema';
import { l } from '../../services/Labels';
export interface SchemaOptions {
showTitle?: boolean;
skipReadOnly?: boolean;
@ -34,7 +36,7 @@ export class Schema extends React.Component<Partial<SchemaProps>> {
<div>
<TypeName>{schema.displayType}</TypeName>
{schema.title && <TypeTitle> {schema.title} </TypeTitle>}
<RecursiveLabel> Recursive </RecursiveLabel>
<RecursiveLabel> {l('recursive')} </RecursiveLabel>
</div>
);
}

37
src/services/Labels.ts Normal file
View File

@ -0,0 +1,37 @@
export interface LabelsConfig {
enum: string;
enumSingleValue: string;
enumArray: string;
default: string;
deprecated: string;
example: string;
nullable: string;
recursive: string;
arrayOf: string;
}
export type LabelsConfigRaw = Partial<LabelsConfig>;
const labels: LabelsConfig = {
enum: 'Enum',
enumSingleValue: 'Value',
enumArray: 'Items',
default: 'Default',
deprecated: 'Deprecated',
example: 'Example',
nullable: 'Nullable',
recursive: 'Recursive',
arrayOf: 'Array of ',
};
export function setRedocLabels(_labels?: LabelsConfigRaw) {
Object.assign(labels, _labels);
}
export function l(key: keyof LabelsConfig, idx?: number): string {
const label = labels[key];
if (idx !== undefined) {
return label[idx];
}
return label;
}

View File

@ -2,6 +2,7 @@ import defaultTheme, { ResolvedThemeInterface, resolveTheme, ThemeInterface } fr
import { querySelector } from '../utils/dom';
import { isNumeric, mergeObjects } from '../utils/helpers';
import { LabelsConfigRaw, setRedocLabels } from './Labels';
import { MDXComponentMeta } from './MarkdownRenderer';
export interface RedocRawOptions {
@ -25,6 +26,8 @@ export interface RedocRawOptions {
unstable_ignoreMimeParameters?: boolean;
allowedMdComponents?: Dict<MDXComponentMeta>;
labels?: LabelsConfigRaw;
}
function argValueToBoolean(val?: string | boolean): boolean {
@ -136,6 +139,9 @@ export class RedocNormalizedOptions {
this.theme.extensionsHook = hook as any;
// do not support dynamic labels changes. Labels should be configured before
setRedocLabels(raw.labels);
this.scrollYOffset = RedocNormalizedOptions.normalizeScrollYOffset(raw.scrollYOffset);
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses);

View File

@ -19,6 +19,8 @@ import {
sortByRequired,
} from '../../utils/';
import { l } from '../Labels';
// TODO: refactor this model, maybe use getters instead of copying all the values
export class SchemaModel {
pointer: string;
@ -148,7 +150,7 @@ export class SchemaModel {
this.items = new SchemaModel(parser, schema.items, this.pointer + '/items', this.options);
this.displayType = pluralizeType(this.items.displayType);
this.displayFormat = this.items.format;
this.typePrefix = this.items.typePrefix + 'Array of ';
this.typePrefix = this.items.typePrefix + l('arrayOf');
this.title = this.title || this.items.title;
this.isPrimitive = this.items.isPrimitive;
if (this.example === undefined && this.items.example !== undefined) {