Split menu generation in two stages

This commit is contained in:
Roman Hotsiy 2016-12-23 00:41:36 +02:00
parent d3af2e6867
commit de00c7868a
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0

View File

@ -18,17 +18,22 @@ export interface MenuMethod {
ready: boolean; ready: boolean;
} }
export interface MenuCategory { export interface MenuItem {
name: string;
id: string; id: string;
active?: boolean; name: string;
methods?: Array<MenuMethod>;
description?: string; description?: string;
empty?: string;
virtual?: boolean; items?: Array<MenuItem>;
ready: boolean; parent?: MenuItem;
headless: boolean;
active?: boolean;
ready?: boolean;
level?: number;
flatIdx?: number;
metadata?: any;
} }
// global var for this module // global var for this module
@ -300,30 +305,11 @@ export class SchemaHelper {
} }
} }
static buildMenuTree(schema):Array<MenuCategory> { static getTags(schema) {
var catIdx = 0; let tags = {};
let tag2MethodMapping = {};
for (let header of (<Array<string>>(schema.info && schema.info['x-redoc-markdown-headers'] || []))) {
let id = 'section/' + slugify(header);
tag2MethodMapping[id] = {
name: header, id: id, virtual: true, methods: [], idx: catIdx
};
catIdx++;
}
for (let tag of schema.tags || []) { for (let tag of schema.tags || []) {
let id = 'tag/' + slugify(tag.name); tags[tag.name] = tag;
tag2MethodMapping[id] = { tag.methods = [];
name: tag['x-displayName'] || tag.name,
id: id,
description: tag.description,
headless: tag.name === '',
empty: !!tag['x-traitTag'],
methods: [],
idx: catIdx
};
catIdx++;
} }
let paths = schema.paths; let paths = schema.paths;
@ -331,39 +317,108 @@ export class SchemaHelper {
let methods = Object.keys(paths[path]).filter((k) => swaggerMethods.has(k)); let methods = Object.keys(paths[path]).filter((k) => swaggerMethods.has(k));
for (let method of methods) { for (let method of methods) {
let methodInfo = paths[path][method]; let methodInfo = paths[path][method];
let tags = methodInfo.tags; let methodTags = methodInfo.tags;
if (!tags || !tags.length) { if (!(methodTags && methodTags.length)) {
tags = ['']; methodTags = [''];
} }
let methodPointer = JsonPointer.compile(['paths', path, method]); let methodPointer = JsonPointer.compile([path, method]);
let methodSummary = SchemaHelper.methodSummary(methodInfo); for (let tagName of methodTags) {
for (let tag of tags) { let tag = tags[tagName];
let id = 'tag/' + slugify(tag); if (!tag) {
let tagDetails = tag2MethodMapping[id]; tag = {
if (!tagDetails) { name: tagName,
tagDetails = {
name: tag,
id: id,
headless: tag === '',
idx: catIdx
}; };
tag2MethodMapping[id] = tagDetails; tags[tagName] = tag;
catIdx++;
} }
if (tagDetails.empty) continue; if (tag['x-traitTag']) continue;
if (!tagDetails.methods) tagDetails.methods = []; if (!tag.methods) tag.methods = [];
tagDetails.methods.push({ tag.methods.push(methodInfo);
pointer: methodPointer, methodInfo._pointer = methodPointer;
summary: methodSummary,
operationId: methodInfo.operationId,
tag: tag,
idx: tagDetails.methods.length,
catIdx: tagDetails.idx
});
} }
} }
} }
return Object.keys(tag2MethodMapping).map(tag => tag2MethodMapping[tag]);
return Object.keys(tags).map(k => tags[k]);
}
static buildMenuTree(schema):MenuItem[] {
let tags = SchemaHelper.getTags(schema);
let menu = [];
// markdown menu items
for (let header of (<Array<string>>(schema.info && schema.info['x-redoc-markdown-headers'] || []))) {
let id = 'section/' + slugify(header);
let item = {
name: header,
id: id
}
menu.push(item);
}
// tag menu items
for (let tag of tags || []) {
let id = 'tag/' + slugify(tag.name);
let item:MenuItem;
let items:MenuItem[];
// don't put empty tag into menu, instead put all methods
if (tag.name !== '') {
item = {
name: tag['x-displayName'] || tag.name,
id: id,
description: tag.description,
metadata: { type: 'tag' }
};
if (tag.methods && tag.methods.length) {
item.items = items = [];
}
} else {
item = null;
items = menu;
}
if (items) {
for (let method of tag.methods) {
let subItem = {
name: SchemaHelper.methodSummary(method),
id: method._pointer,
description: method.description,
metadata: {
type: 'method',
pointer: '/paths' + method._pointer,
operationId: method.operationId
},
parent: item
}
items.push(subItem);
}
}
if (item) menu.push(item);
}
return menu;
}
static flatMenu(menu: MenuItem[]):MenuItem[] {
let res = [];
let level = 0;
let recursive = function(items) {
for (let item of items) {
res.push(item);
item.level = item.level || level;
item.flatIdx = res.length - 1;
if (item.items) {
level++;
recursive(item.items);
level--;
}
}
}
recursive(menu);
return res;
} }
} }