mirror of https://github.com/Squidex/squidex.git
24 changed files with 331 additions and 64 deletions
@ -0,0 +1,16 @@ |
|||
<div *sqxModalView="tooltipModal;onRoot:true" closeAlways="true" [sqxModalTarget]="for" [position]="position" [offset]="4" [auto]="false"> |
|||
<div class="onboarding-tooltip" [ngClass]="position"> |
|||
<div class="arrow1"></div> |
|||
<div class="arrow2"></div> |
|||
|
|||
<div class="content">{{text}}</div> |
|||
|
|||
<a (click)="hideThis()" class="hide-this btn-link btn-default btn-sm"> |
|||
<i class="icon-close"></i> |
|||
</a> |
|||
|
|||
<button (click)="hideAll()" class="hide-all btn-link btn-primary btn-sm"> |
|||
Hide all Tooltips |
|||
</button> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,46 @@ |
|||
@import '_mixins'; |
|||
@import '_vars'; |
|||
|
|||
$color: $color-theme-blue; |
|||
|
|||
$size-arrow: 10px; |
|||
|
|||
// sass-lint:disable class-name-format |
|||
|
|||
.onboarding-tooltip { |
|||
& { |
|||
@include box-shadow(0, 2px, 20px, .3); |
|||
max-width: 20rem; |
|||
background: $color-dark-foreground; |
|||
border: 1px solid $color; |
|||
position: relative; |
|||
} |
|||
|
|||
.content { |
|||
padding: 1.6rem 1.6rem 2.5rem; |
|||
} |
|||
|
|||
.hide-this { |
|||
@include absolute(.1rem, .1rem, auto, auto); |
|||
} |
|||
|
|||
.hide-all { |
|||
@include absolute(auto, .1rem, .1rem, auto); |
|||
} |
|||
|
|||
&.topRight { |
|||
& { |
|||
margin-right: -$size-arrow - 1; |
|||
} |
|||
|
|||
.arrow1 { |
|||
@include caret-top($color, $size-arrow); |
|||
@include absolute(-$size-arrow * 2, $size-arrow * .5, auto, auto); |
|||
} |
|||
|
|||
.arrow2 { |
|||
@include caret-top($color-dark-foreground, $size-arrow); |
|||
@include absolute(-$size-arrow * 2 + 1, $size-arrow * .5, auto, auto); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,98 @@ |
|||
/* |
|||
* 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'; |
|||
|
|||
@Component({ |
|||
selector: 'sqx-onboarding-tooltip', |
|||
styleUrls: ['./onboarding-tooltip.component.scss'], |
|||
templateUrl: './onboarding-tooltip.component.html' |
|||
}) |
|||
export class OnboardingTooltipComponent implements OnDestroy, OnInit { |
|||
private showTimer: any; |
|||
private closeTimer: any; |
|||
private forClickListener: Function; |
|||
|
|||
public tooltipModal = new ModalView(); |
|||
|
|||
@Input() |
|||
public for: any; |
|||
|
|||
@Input() |
|||
public id: string; |
|||
|
|||
@Input() |
|||
public position = 'left'; |
|||
|
|||
@Input() |
|||
public after = 1000; |
|||
|
|||
@Input() |
|||
public text: string; |
|||
|
|||
constructor( |
|||
private readonly onboardingService: OnboardingService, |
|||
private readonly renderer: Renderer |
|||
) { |
|||
} |
|||
|
|||
public ngOnDestroy() { |
|||
if (this.showTimer) { |
|||
clearTimeout(this.showTimer); |
|||
this.showTimer = null; |
|||
} |
|||
|
|||
if (this.closeTimer) { |
|||
clearTimeout(this.closeTimer); |
|||
this.closeTimer = null; |
|||
} |
|||
|
|||
if (this.forClickListener) { |
|||
this.forClickListener(); |
|||
this.forClickListener = 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.after); |
|||
|
|||
this.forClickListener = |
|||
this.renderer.listen(this.for, 'mousedown', () => { |
|||
this.onboardingService.disable(this.id); |
|||
|
|||
this.hideThis(); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
public hideThis() { |
|||
this.onboardingService.disable(this.id); |
|||
this.tooltipModal.hide(); |
|||
|
|||
this.ngOnDestroy(); |
|||
} |
|||
|
|||
public hideAll() { |
|||
this.onboardingService.disableAll(); |
|||
this.tooltipModal.hide(); |
|||
|
|||
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