mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-22 08:36:33 +03:00
Refactor menu
This commit is contained in:
parent
08a46846bc
commit
a5959bdf55
|
@ -19,5 +19,6 @@ a.openapi-button {
|
|||
}
|
||||
|
||||
:host [section] {
|
||||
padding-top: 80px;
|
||||
padding-top: 60px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
border-bottom: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: $secondary-color;
|
||||
}
|
||||
|
||||
responses-list, params-list {
|
||||
display: block;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ export class Method extends BaseComponent {
|
|||
if (this.componentSchema.operationId) {
|
||||
this.method.anchor = 'operation/' + encodeURIComponent(this.componentSchema.operationId);
|
||||
} else {
|
||||
this.method.anchor = 'tag/' + encodeURIComponent(this.tag + this.pointer);
|
||||
this.method.anchor = this.tag + encodeURIComponent(this.pointer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="methods">
|
||||
<div class="tag" *ngFor="let tag of tags;trackBy:trackByTagName">
|
||||
<div class="tag-info" [attr.section]="tag.name" *ngIf="!tag.virtual">
|
||||
<h1 class="sharable-header"> <a class="share-link" href="#section/{{tag.name | encodeURIComponent}}"></a>{{tag.name}} </h1>
|
||||
<div class="tag-info" [attr.section]="tag.id" *ngIf="!tag.virtual">
|
||||
<h1 class="sharable-header"> <a class="share-link" href="#tag/{{tag.name | encodeURIComponent}}"></a>{{tag.name}} </h1>
|
||||
<p *ngIf="tag.description" [innerHtml]="tag.description | marked"> </p>
|
||||
</div>
|
||||
<method *ngFor="let method of tag.methods;trackBy:trackByPointer" [pointer]="method.pointer" [attr.pointer]="method.pointer"
|
||||
|
|
|
@ -27,7 +27,7 @@ export class MethodsList extends BaseComponent {
|
|||
// inject tag name into method info
|
||||
tagInfo.methods = tagInfo.methods || [];
|
||||
tagInfo.methods.forEach(method => {
|
||||
method.tag = tagInfo.name;
|
||||
method.tag = tagInfo.id;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</span>
|
||||
</div>
|
||||
<div #desktop id="resources-nav">
|
||||
<h5 class="menu-header" (click)="onclk()"> API reference </h5>
|
||||
<h5 class="menu-header"> API reference </h5>
|
||||
<div *ngFor="let cat of categories; let idx = index" class="menu-cat">
|
||||
|
||||
<label class="menu-cat-header" (click)="activateAndScroll(idx, -1)" [hidden]="cat.headless"
|
||||
|
|
|
@ -79,7 +79,7 @@ export function RedocComponent(options) {
|
|||
*/
|
||||
export class BaseComponent implements OnInit, OnDestroy {
|
||||
componentSchema: any = null;
|
||||
pointer: String;
|
||||
pointer: string;
|
||||
dereferencedCache = {};
|
||||
|
||||
constructor(public specMgr: SpecManager) {
|
||||
|
|
|
@ -43,7 +43,7 @@ describe('Menu service', () => {
|
|||
});
|
||||
|
||||
it('should scroll to method when location hash is present [jp]', (done) => {
|
||||
let hash = '#section/pet/paths/~1pet~1findByStatus/get';
|
||||
let hash = '#tag/pet/paths/~1pet~1findByStatus/get';
|
||||
spyOn(menu, 'hashScroll').and.callThrough();
|
||||
spyOn(window, 'scrollTo').and.stub();
|
||||
hashService.changed.subscribe(() => {
|
||||
|
|
|
@ -55,7 +55,7 @@ export class MenuService {
|
|||
|
||||
getCurrentMethodEl() {
|
||||
return this.getMethodElByPtr(this.activeMethodPtr,
|
||||
this.categories[this.activeCatIdx].name);
|
||||
this.categories[this.activeCatIdx].id);
|
||||
}
|
||||
|
||||
getMethodElByPtr(ptr, section) {
|
||||
|
@ -141,10 +141,11 @@ export class MenuService {
|
|||
let ptr = decodeURIComponent(hash.substr(namespace.length + 1));
|
||||
if (namespace === 'operation') {
|
||||
$el = this.getMethodElByOperId(ptr);
|
||||
} else if (namespace === 'section') {
|
||||
let tag = ptr.split('/')[0];
|
||||
ptr = ptr.substr(tag.length);
|
||||
$el = this.getMethodElByPtr(ptr, tag);
|
||||
} else {
|
||||
let sectionId = ptr.split('/')[0];
|
||||
ptr = ptr.substr(sectionId.length) || null;
|
||||
sectionId = namespace + (sectionId ? '/' + sectionId : '');
|
||||
$el = this.getMethodElByPtr(ptr, sectionId);
|
||||
}
|
||||
|
||||
if ($el) this.scrollService.scrollTo($el);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { JsonPointer } from '../utils/JsonPointer';
|
||||
import { SpecManager } from '../utils/SpecManager';
|
||||
import {methods as swaggerMethods} from '../utils/swagger-defs';
|
||||
import slugify from 'slugify';
|
||||
|
||||
interface PropertyPreprocessOptions {
|
||||
childFor: string;
|
||||
|
@ -16,6 +17,7 @@ export interface MenuMethod {
|
|||
|
||||
export interface MenuCategory {
|
||||
name: string;
|
||||
id: string;
|
||||
|
||||
active?: boolean;
|
||||
methods?: Array<MenuMethod>;
|
||||
|
@ -245,14 +247,17 @@ export class SchemaHelper {
|
|||
let tag2MethodMapping = {};
|
||||
|
||||
for (let header of (<Array<string>>(schema.info && schema.info['x-redoc-markdown-headers'] || []))) {
|
||||
tag2MethodMapping[header] = {
|
||||
name: header, virtual: true, methods: []
|
||||
let id = 'section/' + slugify(header);
|
||||
tag2MethodMapping[id] = {
|
||||
name: header, id: id, virtual: true, methods: []
|
||||
};
|
||||
}
|
||||
|
||||
for (let tag of schema.tags || []) {
|
||||
tag2MethodMapping[tag.name] = {
|
||||
let id = 'tag/' + slugify(tag.name);
|
||||
tag2MethodMapping[id] = {
|
||||
name: tag.name,
|
||||
id: id,
|
||||
description: tag.description,
|
||||
headless: tag.name === '',
|
||||
empty: !!tag['x-traitTag'],
|
||||
|
@ -273,13 +278,15 @@ export class SchemaHelper {
|
|||
let methodPointer = JsonPointer.compile(['paths', path, method]);
|
||||
let methodSummary = SchemaHelper.methodSummary(methodInfo);
|
||||
for (let tag of tags) {
|
||||
let tagDetails = tag2MethodMapping[tag];
|
||||
if (!tag2MethodMapping[tag]) {
|
||||
let id = 'tag/' + slugify(tag);
|
||||
let tagDetails = tag2MethodMapping[id];
|
||||
if (!tagDetails) {
|
||||
tagDetails = {
|
||||
name: tag,
|
||||
id: id,
|
||||
headless: tag === ''
|
||||
};
|
||||
tag2MethodMapping[tag] = tagDetails;
|
||||
tag2MethodMapping[id] = tagDetails;
|
||||
}
|
||||
if (tagDetails.empty) continue;
|
||||
if (!tagDetails.methods) tagDetails.methods = [];
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.sharable-header {
|
||||
color: $secondary-color;
|
||||
}
|
||||
|
||||
.sharable-header:hover .share-link:before, .share-link:hover:before {
|
||||
visibility: visible;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import JsonSchemaRefParser from 'json-schema-ref-parser';
|
||||
import JsonPointer from './JsonPointer';
|
||||
import { renderMd, safePush } from './helpers';
|
||||
import slugify from 'slugify';
|
||||
|
||||
export class SpecManager {
|
||||
public _schema:any = {};
|
||||
|
@ -52,7 +53,8 @@ export class SpecManager {
|
|||
open: (tokens, idx) => {
|
||||
let content = tokens[idx + 1].content;
|
||||
safePush(this._schema.info, 'x-redoc-markdown-headers', content);
|
||||
return `<h${tokens[idx].hLevel} section="${content}">` +
|
||||
content = slugify(content);
|
||||
return `<h${tokens[idx].hLevel} section="section/${content}">` +
|
||||
`<a class="share-link" href="#section/${content}"></a>`;
|
||||
},
|
||||
close: (tokens, idx) => {
|
||||
|
|
|
@ -43,7 +43,7 @@ describe('Scroll sync', () => {
|
|||
});
|
||||
|
||||
it('should update active menu entries on page scroll forwards', () => {
|
||||
scrollToEl('[tag="store"]').then(() => {
|
||||
scrollToEl('[section="tag/store"]').then(() => {
|
||||
expect($('.menu-cat-header.active').getInnerHtml()).toContain('store');
|
||||
expect($('.selected-tag').getInnerHtml()).toContain('store');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user