Disable menu items until corresponding content is rendered

This commit is contained in:
Roman Hotsiy 2016-11-24 18:12:43 +02:00
parent 4f79d4950a
commit c0e33bff61
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
7 changed files with 57 additions and 13 deletions

View File

@ -16,7 +16,7 @@ import { BaseComponent } from '../base';
import * as detectScollParent from 'scrollparent';
import { SpecManager } from '../../utils/spec-manager';
import { OptionsService, Hash, MenuService, AppStateService, SchemaHelper } from '../../services/index';
import { OptionsService, Hash, AppStateService, SchemaHelper } from '../../services/index';
import { LazyTasksService } from '../../shared/components/LazyFor/lazy-for';
import { CustomErrorHandler } from '../../utils/';

View File

@ -10,7 +10,7 @@
<div *ngFor="let cat of categories; let idx = index" class="menu-cat">
<label class="menu-cat-header" (click)="activateAndScroll(idx, -1)" [hidden]="cat.headless"
[ngClass]="{active: cat.active, disabled: !cat.ready}"> {{cat.name}}</label>
[ngClass]="{active: cat.active, disabled: !cat.ready && cat.methods.length}"> {{cat.name}}</label>
<ul class="menu-subitems" [@itemAnimation]="cat.active ? 'expanded' : 'collapsed'">
<li *ngFor="let method of cat.methods; trackBy:summary; let methIdx = index"
[ngClass]="{active: method.active, disabled: !method.ready}"

View File

@ -38,6 +38,11 @@ $mobile-menu-compact-breakpoint: 550px;
&[hidden] {
display: none;
}
&.disabled, &.disabled:hover {
cursor: default;
color: lighten($text-color, 60%);
}
}
.menu-subitems {
@ -72,6 +77,11 @@ $mobile-menu-compact-breakpoint: 550px;
& li.active {
background: darken($side-menu-active-bg-color, 6%);
}
&.disabled, &.disabled:hover {
cursor: default;
color: lighten($text-color, 60%);
}
}

View File

@ -38,6 +38,8 @@ export class SideMenu extends BaseComponent implements OnInit {
private $resourcesNav: any;
private $scrollParent: any;
private firstChange = true;
constructor(specMgr:SpecManager, elementRef:ElementRef,
private scrollService:ScrollService, private menuService:MenuService, private hash:Hash,
optionsService:OptionsService, private detectorRef:ChangeDetectorRef) {
@ -52,20 +54,37 @@ export class SideMenu extends BaseComponent implements OnInit {
this.menuService.changed.subscribe((evt) => this.changed(evt));
}
changed({cat, item}) {
this.activeCatCaption = cat.name || '';
this.activeItemCaption = item && item.summary || '';
changed(newItem) {
if (newItem) {
let {cat, item} = newItem;
this.activeCatCaption = cat.name || '';
this.activeItemCaption = item && item.summary || '';
}
//safari doesn't update bindings if not run changeDetector manually :(
this.detectorRef.detectChanges();
if (this.firstChange) {
this.scrollActiveIntoView();
this.firstChange = false;
}
}
activateAndScroll(idx, methodIdx) {
scrollActiveIntoView() {
let $item = this.$element.querySelector('li.active, label.active');
if ($item) $item.scrollIntoView();
}
activateAndScroll(catIdx, methodIdx) {
if (this.mobileMode()) {
this.toggleMobileNav();
}
this.menuService.activate(idx, methodIdx);
let menu = this.categories;
if (!menu[catIdx].ready) return;
if (menu[catIdx].methods && menu[catIdx].methods.length && (methodIdx >= 0) &&
!menu[catIdx].methods[methodIdx].ready) return;
this.menuService.activate(catIdx, methodIdx);
this.menuService.scrollToActive();
}

View File

@ -37,13 +37,13 @@ export class MenuService {
this.scrollUpdate(evt.isScrolledDown);
});
this.changeActive(CHANGE.INITIAL);
//this.changeActive(CHANGE.INITIAL);
this.hash.value.subscribe((hash) => {
if (hash == undefined) return;
this.setActiveByHash(hash);
if (!this.tasks.empty) {
this.tasks.start(this.activeCatIdx, this.activeMethodIdx);
this.tasks.start(this.activeCatIdx, this.activeMethodIdx, this);
this.scrollService.setStickElement(this.getCurrentMethodEl());
if (hash) this.scrollToActive();
this.appState.stopLoading();
@ -53,6 +53,14 @@ export class MenuService {
});
}
enableItem(catIdx, methodIdx) {
let cat = this.categories[catIdx];
cat.ready = true;
cat.methods[methodIdx].ready = true;
this.changed.next();
}
get activeMethodPtr() {
let cat = this.categories[this.activeCatIdx];
let ptr = null;

View File

@ -15,6 +15,7 @@ export interface MenuMethod {
tag: string;
pointer: string;
operationId: string;
ready: boolean
}
export interface MenuCategory {
@ -26,6 +27,7 @@ export interface MenuCategory {
description?: string;
empty?: string;
virtual?: boolean;
ready: boolean;
}
// global var for this module
@ -304,7 +306,7 @@ export class SchemaHelper {
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
name: header, id: id, virtual: true, ready: true, methods: [], idx: catIdx
};
catIdx++;
}
@ -317,6 +319,7 @@ export class SchemaHelper {
description: tag.description,
headless: tag.name === '',
empty: !!tag['x-traitTag'],
ready: !!tag['x-traitTag'],
methods: [],
idx: catIdx
};

View File

@ -32,6 +32,8 @@ export class LazyTasksService {
private _tasks = [];
private _current: number = 0;
private _syncCount: number = 0;
private menuService;
public loadProgress = new BehaviorSubject<number>(0);
public allSync = false;
constructor(public optionsService: OptionsService, private zone: NgZone) {
@ -61,6 +63,7 @@ export class LazyTasksService {
if (!task) return;
task._callback(task.idx, true);
this._current++;
this.menuService.enableItem(task.catIdx, task.idx);
this.loadProgress.next(this._current / this._tasks.length * 100);
}
@ -70,7 +73,7 @@ export class LazyTasksService {
if (!task) return;
task._callback(task.idx, false).then(() => {
this._current++;
this.menuService.enableItem(task.catIdx, task.idx);
setTimeout(()=> this.nextTask());
this.loadProgress.next(this._current / this._tasks.length * 100);
}).catch(err => console.error(err));
@ -91,7 +94,8 @@ export class LazyTasksService {
})
}
start(catIdx, metIdx) {
start(catIdx, metIdx, menuService) {
this.menuService = menuService;
let syncCount = 5;
// I know this is bad practice to detect browsers but there is an issue on Safari only
// http://stackoverflow.com/questions/40692365/maintaining-scroll-position-while-inserting-elements-above-glitching-only-in-sa