mirror of
https://github.com/Redocly/redoc.git
synced 2025-05-31 03:03:06 +03:00
Warnings on the top of page (fixes #48)
This commit is contained in:
parent
2872ffbcf9
commit
4b61357be0
|
@ -87,6 +87,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica
|
||||||
* **number**: A fixed number of pixels to be used as offset
|
* **number**: A fixed number of pixels to be used as offset
|
||||||
* **selector**: selector of the element to be used for specifying the offset. The distance from the top of the page to the element's bottom will be used as offset.
|
* **selector**: selector of the element to be used for specifying the offset. The distance from the top of the page to the element's bottom will be used as offset.
|
||||||
* **function**: A getter function. Must return a number representing the offset (in pixels).
|
* **function**: A getter function. Must return a number representing the offset (in pixels).
|
||||||
|
* `suppress-warnings` - if set, warnings are not rendered at the top of page (they still are logged to the console)
|
||||||
|
|
||||||
## Advanced usage
|
## Advanced usage
|
||||||
Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object:
|
Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object:
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
<side-menu> </side-menu>
|
<side-menu> </side-menu>
|
||||||
</div>
|
</div>
|
||||||
<div id="api-content">
|
<div id="api-content">
|
||||||
<api-info> </api-info>
|
<warnings></warnings>
|
||||||
|
<api-info></api-info>
|
||||||
<methods-list> </methods-list>
|
<methods-list> </methods-list>
|
||||||
<footer>
|
<footer>
|
||||||
<div class="powered-by-badge">
|
<div class="powered-by-badge">
|
||||||
|
|
|
@ -12,11 +12,12 @@ import { ApiInfo } from '../ApiInfo/api-info';
|
||||||
import { ApiLogo } from '../ApiLogo/api-logo';
|
import { ApiLogo } from '../ApiLogo/api-logo';
|
||||||
import { MethodsList } from '../MethodsList/methods-list';
|
import { MethodsList } from '../MethodsList/methods-list';
|
||||||
import { SideMenu } from '../SideMenu/side-menu';
|
import { SideMenu } from '../SideMenu/side-menu';
|
||||||
|
import { Warnings } from '../Warnings/warnings';
|
||||||
|
|
||||||
import { StickySidebar } from '../../shared/components/index';
|
import { StickySidebar } from '../../shared/components/index';
|
||||||
import {SpecManager} from '../../utils/SpecManager';
|
import {SpecManager} from '../../utils/SpecManager';
|
||||||
import { OptionsService, RedocEventsService, MenuService,
|
import { OptionsService, RedocEventsService, MenuService,
|
||||||
ScrollService, Hash } from '../../services/index';
|
ScrollService, Hash, WarningsService } from '../../services/index';
|
||||||
|
|
||||||
var dom = new BrowserDomAdapter();
|
var dom = new BrowserDomAdapter();
|
||||||
var _modeLocked = false;
|
var _modeLocked = false;
|
||||||
|
@ -30,10 +31,11 @@ var _modeLocked = false;
|
||||||
ScrollService,
|
ScrollService,
|
||||||
Hash,
|
Hash,
|
||||||
MenuService,
|
MenuService,
|
||||||
|
WarningsService
|
||||||
],
|
],
|
||||||
templateUrl: './redoc.html',
|
templateUrl: './redoc.html',
|
||||||
styleUrls: ['./redoc.css'],
|
styleUrls: ['./redoc.css'],
|
||||||
directives: [ ApiInfo, ApiLogo, MethodsList, SideMenu, StickySidebar ],
|
directives: [ ApiInfo, ApiLogo, MethodsList, SideMenu, StickySidebar, Warnings ],
|
||||||
detect: true,
|
detect: true,
|
||||||
onPushOnly: false
|
onPushOnly: false
|
||||||
})
|
})
|
||||||
|
|
4
lib/components/Warnings/warnings.html
Normal file
4
lib/components/Warnings/warnings.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<div *ngIf="shown">
|
||||||
|
<a class="warnings-close" (click)="close()">×</a>
|
||||||
|
<div class="message" *ngFor="let message of warnings">{{message}}</div>
|
||||||
|
</div>
|
33
lib/components/Warnings/warnings.scss
Normal file
33
lib/components/Warnings/warnings.scss
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
:host {
|
||||||
|
width: 60%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
padding: 5px 40px;
|
||||||
|
background-color: #fcf8e3;
|
||||||
|
color: #8a6d3b;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "Warning: ";
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warnings-close {
|
||||||
|
font-size: 150%;
|
||||||
|
color: black;
|
||||||
|
opacity: 0.4;
|
||||||
|
float: right;
|
||||||
|
margin: 5px 20px 0 0;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: inline;
|
||||||
|
}
|
31
lib/components/Warnings/warnings.ts
Normal file
31
lib/components/Warnings/warnings.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { SpecManager, RedocComponent, BaseComponent } from '../base';
|
||||||
|
import { WarningsService, OptionsService } from '../../services/index';
|
||||||
|
|
||||||
|
@RedocComponent({
|
||||||
|
selector: 'warnings',
|
||||||
|
styleUrls: ['./warnings.css'],
|
||||||
|
templateUrl: './warnings.html',
|
||||||
|
detect: true,
|
||||||
|
onPushOnly: false
|
||||||
|
})
|
||||||
|
export class Warnings extends BaseComponent {
|
||||||
|
warnings: Array<string>;
|
||||||
|
shown: boolean;
|
||||||
|
constructor(specMgr:SpecManager, optionsMgr: OptionsService) {
|
||||||
|
super(specMgr);
|
||||||
|
this.shown = !optionsMgr.options.suppressWarnings;
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
WarningsService.warnings.subscribe((warns) => {
|
||||||
|
console.log(warns);
|
||||||
|
this.warnings = warns;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.shown = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,3 +7,4 @@ export * from './scroll.service';
|
||||||
export * from './hash.service';
|
export * from './hash.service';
|
||||||
export * from './schema-normalizer.service';
|
export * from './schema-normalizer.service';
|
||||||
export * from './schema-helper.service';
|
export * from './schema-helper.service';
|
||||||
|
export * from './warnings.service';
|
||||||
|
|
|
@ -9,7 +9,7 @@ const defaults = {
|
||||||
debugMode: false//global && global.redocDebugMode
|
debugMode: false//global && global.redocDebugMode
|
||||||
};
|
};
|
||||||
|
|
||||||
const OPTION_NAMES = new Set(['scrollYOffset', 'disableLazySchemas', 'specUrl']);
|
const OPTION_NAMES = new Set(['scrollYOffset', 'disableLazySchemas', 'specUrl', 'suppressWarnings']);
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OptionsService {
|
export class OptionsService {
|
||||||
|
@ -70,5 +70,6 @@ export class OptionsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isString(this._options.disableLazySchemas)) this._options.disableLazySchemas = true;
|
if (isString(this._options.disableLazySchemas)) this._options.disableLazySchemas = true;
|
||||||
|
if (isString(this._options.suppressWarnings)) this._options.suppressWarnings = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { JsonPointer } from '../utils/JsonPointer';
|
import { JsonPointer } from '../utils/JsonPointer';
|
||||||
import { SpecManager } from '../utils/SpecManager';
|
import { SpecManager } from '../utils/SpecManager';
|
||||||
import {methods as swaggerMethods, keywordTypes} from '../utils/swagger-defs';
|
import {methods as swaggerMethods, keywordTypes} from '../utils/swagger-defs';
|
||||||
|
import { WarningsService } from './warnings.service';
|
||||||
import slugify from 'slugify';
|
import slugify from 'slugify';
|
||||||
|
|
||||||
interface PropertyPreprocessOptions {
|
interface PropertyPreprocessOptions {
|
||||||
|
@ -32,10 +33,10 @@ const injectors = {
|
||||||
inject: (injectTo, propertySchema, pointer) => {
|
inject: (injectTo, propertySchema, pointer) => {
|
||||||
injectTo.type = SchemaHelper.detectType(propertySchema);
|
injectTo.type = SchemaHelper.detectType(propertySchema);
|
||||||
propertySchema.type = injectTo.type;
|
propertySchema.type = injectTo.type;
|
||||||
let message = `No "type" specified at ${pointer}. `;
|
if (injectTo.type) {
|
||||||
message += injectTo.type ? `Automatically detected: "${injectTo.type}"` :
|
let message = `No "type" specified at "${pointer}". Automatically detected: "${injectTo.type}"`;
|
||||||
`Can't detect automatically`;
|
WarningsService.warn(message);
|
||||||
console.warn(message);
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
general: {
|
general: {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
|
||||||
import { SpecManager } from '../utils/SpecManager';
|
import { SpecManager } from '../utils/SpecManager';
|
||||||
import { JsonPointer } from '../utils/JsonPointer';
|
import { JsonPointer } from '../utils/JsonPointer';
|
||||||
import { defaults } from '../utils/helpers';
|
import { defaults } from '../utils/helpers';
|
||||||
|
import { WarningsService } from './warnings.service';
|
||||||
|
|
||||||
interface Reference {
|
interface Reference {
|
||||||
$ref: string;
|
$ref: string;
|
||||||
|
@ -127,20 +128,22 @@ class AllOfMerger {
|
||||||
private static checkCanMerge(subSchema, into) {
|
private static checkCanMerge(subSchema, into) {
|
||||||
// TODO: add support for merge array schemas
|
// TODO: add support for merge array schemas
|
||||||
if (typeof subSchema !== 'object') {
|
if (typeof subSchema !== 'object') {
|
||||||
let errMessage = `Items of allOf should be Object: ${typeof subSchema} found
|
let errMessage = `Items of allOf should be Object: ${typeof subSchema} found ` +
|
||||||
${subSchema}`;
|
`${subSchema} at "#${into._pointer}"`;
|
||||||
throw new Error(errMessage);
|
throw new Error(errMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (into.type && subSchema.type && into.type !== subSchema.type) {
|
if (into.type && subSchema.type && into.type !== subSchema.type) {
|
||||||
let errMessage = `allOf merging error: schemas with different types can't be merged`;
|
let errMessage = `allOf merging error: schemas with different types can't be merged: ` +
|
||||||
|
`"${into.type}" and "${subSchema.type}" at "#${into._pointer}"`;
|
||||||
throw new Error(errMessage);
|
throw new Error(errMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (into.type === 'array') {
|
if (into.type === 'array') {
|
||||||
console.warn('allOf: subschemas with type array are not supported yet');
|
WarningsService.warn('allOf: subschemas with type "array" are not supported yet');
|
||||||
}
|
}
|
||||||
// TODO: add check if can be merged correctly (no different properties with the same name)
|
// TODO: add check if can be merged correctly (no different properties with the same name)
|
||||||
|
// TODO: merge properties
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,8 +194,8 @@ class SchemaDereferencer {
|
||||||
|
|
||||||
let keysCount = Object.keys(schema).length;
|
let keysCount = Object.keys(schema).length;
|
||||||
if ( keysCount > 2 || (keysCount === 2 && !schema.description) ) {
|
if ( keysCount > 2 || (keysCount === 2 && !schema.description) ) {
|
||||||
console.warn(`other properties defined at the same level as $ref at '${pointer}'.
|
WarningsService.warn(`Other properties are defined at the same level as $ref at "#${pointer}". ` +
|
||||||
They are IGNORRED according to JsonSchema spec`);
|
'They are IGNORRED according to the JsonSchema spec');
|
||||||
resolved.description = resolved.description || schema.description;
|
resolved.description = resolved.description || schema.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
lib/services/warnings.service.ts
Normal file
23
lib/services/warnings.service.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
'use strict';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class WarningsService {
|
||||||
|
private static _warnings: Array<string> = [];
|
||||||
|
private static _warningsObs = new Subject<Array<string>>();
|
||||||
|
|
||||||
|
static get warnings() {
|
||||||
|
return WarningsService._warningsObs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hasWarnings() {
|
||||||
|
return !!WarningsService._warnings.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static warn(message:string) {
|
||||||
|
WarningsService._warnings.push(message);
|
||||||
|
WarningsService._warningsObs.next(WarningsService._warnings);
|
||||||
|
console.warn(message);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user