fix: simplified section spliting and added side menu top margin to side menu item if tag groups

This commit is contained in:
Roberto Fernández 2020-06-29 17:48:54 +02:00
parent 2996e947e9
commit 01910e0622
6 changed files with 33 additions and 21 deletions

View File

@ -40,7 +40,12 @@ export class MenuItem extends React.Component<MenuItemProps> {
render() {
const { item, withoutChildren } = this.props;
return (
<MenuItemLi onClick={this.activate} depth={item.depth} data-item-id={item.id}>
<MenuItemLi
onClick={this.activate}
depth={item.depth}
data-item-id={item.id}
topMargin={item.topMargin}
>
{item.type === 'operation' ? (
<OperationMenuItemContent {...this.props} item={item as OperationModel} />
) : (

View File

@ -83,12 +83,12 @@ export const MenuItemUl = styled.ul<{ expanded: boolean }>`
${props => (props.expanded ? '' : 'display: none;')};
`;
export const MenuItemLi = styled.li<{ depth: number }>`
export const MenuItemLi = styled.li<{ depth: number; topMargin?: boolean }>`
list-style: none inside none;
overflow: hidden;
text-overflow: ellipsis;
padding: 0;
${props => (props.depth === 0 ? 'margin-top: 15px' : '')};
${props => (props.depth === 0 || props.topMargin ? 'margin-top: 15px' : '')};
`;
export const menuItemDepth = {

View File

@ -12,7 +12,6 @@ import {
setSecuritySchemePrefix,
JsonPointer,
extractContent,
removeContent,
} from '../utils';
import { MarkdownRenderer } from './MarkdownRenderer';
import { GroupModel, OperationModel } from './models';
@ -55,14 +54,18 @@ export class MenuBuilder {
const items: ContentItemModel[] = [];
const tagsMap = MenuBuilder.getTagsWithOperations(spec);
let setionToTheEnd = '';
let sectionsBefore = '';
let sectionsAfter = '';
options.sectionsAtTheEnd.forEach(function(s) {
setionToTheEnd += extractContent(spec.info.description || '', s);
spec.info.description = removeContent(spec.info.description || '', s);
new MarkdownRenderer(options).extractHeadings(spec.info.description || '').forEach(function(h) {
if (options.sectionsAtTheEnd.includes(h.name)) {
sectionsAfter += extractContent(spec.info.description || '', h.name);
} else {
sectionsBefore += extractContent(spec.info.description || '', h.name);
}
});
items.push(...MenuBuilder.addMarkdownItems(spec.info.description || '', undefined, 1, options));
items.push(...MenuBuilder.addMarkdownItems(sectionsBefore, undefined, 1, options));
if (spec['x-tagGroups'] && spec['x-tagGroups'].length > 0) {
items.push(
...MenuBuilder.getTagGroupsItems(parser, undefined, spec['x-tagGroups'], tagsMap, options),
@ -71,7 +74,15 @@ export class MenuBuilder {
items.push(...MenuBuilder.getTagsItems(parser, tagsMap, undefined, undefined, options));
}
items.push(...MenuBuilder.addMarkdownItems(setionToTheEnd, undefined, 1, options));
items.push(
...MenuBuilder.addMarkdownItems(
sectionsAfter,
undefined,
1,
options,
spec['x-tagGroups'] && spec['x-tagGroups'].length > 0, // If tagGroups, add topMargin to side menu item
),
);
return items;
}
@ -85,6 +96,7 @@ export class MenuBuilder {
parent: GroupModel | undefined,
initialDepth: number,
options: RedocNormalizedOptions,
topMargin: boolean = false,
): ContentItemModel[] {
const renderer = new MarkdownRenderer(options);
const headings = renderer.extractHeadings(description || '');
@ -99,6 +111,10 @@ export class MenuBuilder {
const mapHeadingsDeep = (_parent, items, depth = 1) =>
items.map(heading => {
const group = new GroupModel('section', heading, _parent);
if (topMargin) {
group.topMargin = true;
topMargin = false;
}
group.depth = depth;
if (heading.items) {
group.items = mapHeadingsDeep(group, heading.items, depth + 1);

View File

@ -24,6 +24,7 @@ export interface IMenuItem {
parent?: IMenuItem;
deprecated?: boolean;
type: MenuItemType;
topMargin?: boolean;
deactivate(): void;
activate(): void;

View File

@ -28,6 +28,7 @@ export class GroupModel implements IMenuItem {
depth: number;
level: number;
topMargin: boolean;
//#endregion
constructor(

View File

@ -94,17 +94,6 @@ export function extractContent(md: string, heading: string): string {
return '';
}
export function removeContent(md: string, heading: string): string {
// remove the content of section with given heading
const testRegex = new RegExp(`(^|\\n)#\\s?${heading}\\s*\\n`, 'i');
const replaceRegex = new RegExp(`((\\n|^)#\\s*${heading}\\s*(\\n|$)(?:.|\\n)*?)(?=\\n#|$)`, 'i');
if (testRegex.test(md)) {
return md.replace(replaceRegex, '');
}
return md;
}
// credits https://stackoverflow.com/a/46973278/1749888
export const mergeObjects = (target: any, ...sources: any[]): any => {
if (!sources.length) {