2019-07-16 08:38:11 +03:00
|
|
|
/**
|
|
|
|
|
* @license
|
|
|
|
|
* Copyright Akveo. All Rights Reserved.
|
|
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { Inject, Injectable } from '@angular/core';
|
2021-09-24 15:56:10 +03:00
|
|
|
import { map } from 'rxjs/operators';
|
|
|
|
|
import { combineLatest, Observable, of } from 'rxjs';
|
2019-07-16 08:38:11 +03:00
|
|
|
|
|
|
|
|
import { NgxTabbedService } from './tabbed.service';
|
|
|
|
|
import { NgxTextService } from './text.service';
|
|
|
|
|
import { DOCS, STRUCTURE } from '../../app.options';
|
2021-09-24 15:56:10 +03:00
|
|
|
import { NgxArticleService } from './article.service';
|
2019-07-16 08:38:11 +03:00
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
|
export class NgxStructureService {
|
|
|
|
|
|
|
|
|
|
protected prepared;
|
|
|
|
|
|
|
|
|
|
constructor(private textService: NgxTextService,
|
|
|
|
|
private tabbedService: NgxTabbedService,
|
2021-09-24 15:56:10 +03:00
|
|
|
private articleService: NgxArticleService,
|
2019-07-16 08:38:11 +03:00
|
|
|
@Inject(STRUCTURE) structure,
|
|
|
|
|
@Inject(DOCS) docs) {
|
|
|
|
|
this.prepared = this.prepareStructure(structure, docs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getPreparedStructure(): any {
|
|
|
|
|
return this.prepared;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
findPageBySlag(structure: any, slag: string): any {
|
|
|
|
|
for (const item of structure) {
|
|
|
|
|
if (item.slag === slag) {
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
if (item.type === 'section' && item.children) {
|
|
|
|
|
const deep = this.findPageBySlag(item.children, slag);
|
|
|
|
|
if (deep) {
|
|
|
|
|
return deep;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected prepareStructure(structure: any, preparedDocs: any, parentSlag?: string): any {
|
|
|
|
|
return structure.map((item: any) => {
|
|
|
|
|
const slag = item.name ? this.textService.createSlag(item.name) : null;
|
|
|
|
|
|
|
|
|
|
if (item.type === 'block' && typeof item.source === 'string') {
|
|
|
|
|
|
|
|
|
|
if (item.block === 'theme') {
|
|
|
|
|
item.source = preparedDocs.themes[item.source];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.block === 'component') {
|
|
|
|
|
item.source = this.prepareComponent(preparedDocs.classes.find((data) => data.name === item.source));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.block === 'markdown') {
|
2021-09-24 15:56:10 +03:00
|
|
|
item.sections = this.articleService.getArticle(item.source).pipe(
|
|
|
|
|
map((article) => this.textService.mdToSectionsHTML(article)),
|
|
|
|
|
);
|
2019-07-16 08:38:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.children) {
|
|
|
|
|
item.children = this.prepareStructure(item.children, preparedDocs, slag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.type === 'tabs') {
|
|
|
|
|
item.source = this.getComponents(item, preparedDocs);
|
|
|
|
|
item.tabs = this.tabbedService.determineTabs(item);
|
|
|
|
|
|
|
|
|
|
// we emulate a block here
|
|
|
|
|
item.children = [
|
|
|
|
|
{
|
|
|
|
|
type: 'block',
|
|
|
|
|
block: 'tabbed',
|
|
|
|
|
children: item.source,
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.type === 'page' || item.type === 'tabs') {
|
|
|
|
|
item.toc = this.prepareToc(item);
|
|
|
|
|
item.slag = parentSlag ? `${parentSlag}_${slag}` : slag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return item;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected getComponents(item: any, preparedDocs) {
|
|
|
|
|
return item.source
|
|
|
|
|
.map(source => preparedDocs.classes.find((data) => data.name === source))
|
|
|
|
|
.map(component => this.prepareComponent(component));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected prepareComponent(component: any) {
|
|
|
|
|
const textNodes = component.overview.filter(node => node.type === 'text');
|
|
|
|
|
if (textNodes && textNodes.length) {
|
|
|
|
|
textNodes[0].content = `## ${component.name}\n\n${textNodes[0].content}`; // TODO: this is bad
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
... component,
|
|
|
|
|
slag: this.textService.createSlag(component.name),
|
|
|
|
|
overview: component.overview.map((node: any) => {
|
|
|
|
|
if (node.type === 'text') {
|
|
|
|
|
return {
|
|
|
|
|
type: node.type,
|
|
|
|
|
content: this.textService.mdToSectionsHTML(node.content),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return node;
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-24 15:56:10 +03:00
|
|
|
protected prepareToc(item: any): Observable<any[]> {
|
|
|
|
|
const tocList = item.children.reduce((acc: Observable<any>[], child: any) => {
|
2019-07-16 08:38:11 +03:00
|
|
|
if (child.block === 'markdown') {
|
2021-09-24 15:56:10 +03:00
|
|
|
return [...acc, this.getTocForMd(child)];
|
|
|
|
|
}
|
|
|
|
|
if (child.block === 'tabbed') {
|
|
|
|
|
return [...acc, this.getTocForTabbed(child)];
|
|
|
|
|
}
|
|
|
|
|
if (child.block === 'component') {
|
|
|
|
|
return [...acc, this.getTocForComponent(child)];
|
2019-07-16 08:38:11 +03:00
|
|
|
}
|
|
|
|
|
return acc;
|
|
|
|
|
}, []);
|
2021-09-24 15:56:10 +03:00
|
|
|
|
|
|
|
|
return combineLatest([...tocList]).pipe(map((toc) => [].concat(...toc)));
|
2019-07-16 08:38:11 +03:00
|
|
|
}
|
|
|
|
|
|
2021-09-24 15:56:10 +03:00
|
|
|
protected getTocForMd(block: any): Observable<any[]> {
|
|
|
|
|
return (block.sections as Observable<any[]>).pipe(
|
|
|
|
|
map((item) => item.map((val) => ({
|
|
|
|
|
title: val.title,
|
|
|
|
|
fragment: val.fragment,
|
|
|
|
|
}))),
|
|
|
|
|
);
|
2019-07-16 08:38:11 +03:00
|
|
|
}
|
|
|
|
|
|
2021-09-24 15:56:10 +03:00
|
|
|
protected getTocForComponent(block: any): Observable<any[]> {
|
|
|
|
|
return of([{
|
2019-07-16 08:38:11 +03:00
|
|
|
title: block.source.name,
|
|
|
|
|
fragment: block.source.slag,
|
2021-09-24 15:56:10 +03:00
|
|
|
}]);
|
2019-07-16 08:38:11 +03:00
|
|
|
}
|
|
|
|
|
|
2021-09-24 15:56:10 +03:00
|
|
|
protected getTocForTabbed(block: any): Observable<any[]> {
|
|
|
|
|
return of(block.children.map((component: any) => ({
|
|
|
|
|
title: component.name,
|
|
|
|
|
fragment: this.textService.createSlag(component.name),
|
|
|
|
|
})));
|
2019-07-16 08:38:11 +03:00
|
|
|
}
|
|
|
|
|
}
|