mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
52 changed files with 621 additions and 241 deletions
@ -0,0 +1,19 @@ |
|||||
|
<div *sqxModalView="tooltipModal;onRoot:true" closeAlways="true" @fade> |
||||
|
|
||||
|
<div class="onboarding-rect" [sqxModalTarget]="for" [offset]="4" [autoPosition]="false" position="full"></div> |
||||
|
<div class="onboarding-help" [sqxModalTarget]="for" [offset]="4" [autoPosition]="false" [position]="position"> |
||||
|
<div class="onboarding-text"> |
||||
|
<ng-content></ng-content> |
||||
|
</div> |
||||
|
|
||||
|
<div class="onboarding-buttons clearfix"> |
||||
|
<button (click)="hideAll()" class="btn btn-link btn-primary btn-sm float-left"> |
||||
|
Stop Tour |
||||
|
</button> |
||||
|
|
||||
|
<button (click)="hideThis()" class="btn btn-link btn-success btn-sm float-right"> |
||||
|
Got It |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,28 @@ |
|||||
|
@import '_mixins'; |
||||
|
@import '_vars'; |
||||
|
|
||||
|
$color: #1a2129; |
||||
|
|
||||
|
.onboarding { |
||||
|
&-help { |
||||
|
@include border-radius; |
||||
|
background: $color; |
||||
|
border: 0; |
||||
|
max-width: 20rem; |
||||
|
padding: .75rem; |
||||
|
} |
||||
|
|
||||
|
&-text { |
||||
|
font-size: .9rem; |
||||
|
font-weight: normal; |
||||
|
color: $color-dark-foreground; |
||||
|
} |
||||
|
|
||||
|
&-buttons { |
||||
|
margin: .8rem -.5rem 0; |
||||
|
} |
||||
|
|
||||
|
&-rect { |
||||
|
@include box-shadow-raw(0 0 0 9999px rgba(0, 0, 0, .5)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,95 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import { Component, Input, OnDestroy, OnInit, Renderer } from '@angular/core'; |
||||
|
|
||||
|
import { ModalView } from './../utils/modal-view'; |
||||
|
|
||||
|
import { OnboardingService } from './../services/onboarding.service'; |
||||
|
|
||||
|
import { fadeAnimation } from './animations'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'sqx-onboarding-tooltip', |
||||
|
styleUrls: ['./onboarding-tooltip.component.scss'], |
||||
|
templateUrl: './onboarding-tooltip.component.html', |
||||
|
animations: [ |
||||
|
fadeAnimation |
||||
|
] |
||||
|
}) |
||||
|
export class OnboardingTooltipComponent implements OnDestroy, OnInit { |
||||
|
private showTimer: any; |
||||
|
private closeTimer: any; |
||||
|
private forMouseDownListener: Function; |
||||
|
|
||||
|
public tooltipModal = new ModalView(); |
||||
|
|
||||
|
@Input() |
||||
|
public for: any; |
||||
|
|
||||
|
@Input() |
||||
|
public id: string; |
||||
|
|
||||
|
@Input() |
||||
|
public after = 1000; |
||||
|
|
||||
|
@Input() |
||||
|
public position = 'left'; |
||||
|
|
||||
|
constructor( |
||||
|
private readonly onboardingService: OnboardingService, |
||||
|
private readonly renderer: Renderer |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
clearTimeout(this.showTimer); |
||||
|
clearTimeout(this.closeTimer); |
||||
|
|
||||
|
this.tooltipModal.hide(); |
||||
|
|
||||
|
if (this.forMouseDownListener) { |
||||
|
this.forMouseDownListener(); |
||||
|
this.forMouseDownListener = null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
if (this.for && this.id) { |
||||
|
this.showTimer = setTimeout(() => { |
||||
|
if (this.onboardingService.shouldShow(this.id)) { |
||||
|
this.tooltipModal.show(); |
||||
|
|
||||
|
this.closeTimer = setTimeout(() => { |
||||
|
this.hideThis(); |
||||
|
}, 10000); |
||||
|
|
||||
|
this.onboardingService.disable(this.id); |
||||
|
} |
||||
|
}, this.after); |
||||
|
|
||||
|
this.forMouseDownListener = |
||||
|
this.renderer.listen(this.for, 'mousedown', () => { |
||||
|
this.onboardingService.disable(this.id); |
||||
|
|
||||
|
this.hideThis(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public hideThis() { |
||||
|
this.onboardingService.disable(this.id); |
||||
|
|
||||
|
this.ngOnDestroy(); |
||||
|
} |
||||
|
|
||||
|
public hideAll() { |
||||
|
this.onboardingService.disableAll(); |
||||
|
|
||||
|
this.ngOnDestroy(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
|
||||
|
|
||||
|
|
||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import { Injectable } from '@angular/core'; |
||||
|
|
||||
|
import { LocalStoreService } from './local-store.service'; |
||||
|
|
||||
|
export const OnboardingServiceFactory = (localStore: LocalStoreService) => { |
||||
|
return new OnboardingService(localStore); |
||||
|
}; |
||||
|
|
||||
|
@Injectable() |
||||
|
export class OnboardingService { |
||||
|
constructor( |
||||
|
private readonly localStore: LocalStoreService |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public disableAll() { |
||||
|
this.disable('all'); |
||||
|
} |
||||
|
|
||||
|
public disable(key: string) { |
||||
|
this.localStore.set(`squidex.onboarding.disable.${key}`, '1'); |
||||
|
} |
||||
|
|
||||
|
public shouldShow(key: string) { |
||||
|
return this.shouldShowKey(key) && this.shouldShowKey('all'); |
||||
|
} |
||||
|
|
||||
|
private shouldShowKey(key: string) { |
||||
|
return this.localStore.get(`squidex.onboarding.disable.${key}`) !== '1'; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue