22 changed files with 1076 additions and 186 deletions
@ -0,0 +1,46 @@ |
|||
/** |
|||
* Copyright © 2016-2019 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0 |
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
|
|||
@mixin rule-node-colors { |
|||
&.tb-filter-type { |
|||
background-color: #f1e861; |
|||
} |
|||
|
|||
&.tb-enrichment-type { |
|||
background-color: #cdf14e; |
|||
} |
|||
|
|||
&.tb-transformation-type { |
|||
background-color: #79cef1; |
|||
} |
|||
|
|||
&.tb-action-type { |
|||
background-color: #f1928f; |
|||
} |
|||
|
|||
&.tb-external-type { |
|||
background-color: #fbc766; |
|||
} |
|||
|
|||
&.tb-rule-chain-type { |
|||
background-color: #d6c4f1; |
|||
} |
|||
|
|||
&.tb-unknown-type { |
|||
background-color: #f16c29; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,165 @@ |
|||
///
|
|||
/// Copyright © 2016-2019 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Component, ElementRef, Input, OnDestroy, OnInit } from '@angular/core'; |
|||
import { Hotkey, HotkeysService } from 'angular2-hotkeys'; |
|||
|
|||
@Component({ |
|||
selector : 'tb-hotkeys-cheatsheet', |
|||
styles : [` |
|||
.tb-hotkeys-container { |
|||
display: table !important; |
|||
position: fixed; |
|||
width: 100%; |
|||
height: 100%; |
|||
top: 0; |
|||
left: 0; |
|||
color: #333; |
|||
font-size: 1em; |
|||
background-color: rgba(255,255,255,0.9); |
|||
outline: 0; |
|||
} |
|||
.tb-hotkeys-container.fade { |
|||
z-index: -1024; |
|||
visibility: hidden; |
|||
opacity: 0; |
|||
-webkit-transition: opacity 0.15s linear; |
|||
-moz-transition: opacity 0.15s linear; |
|||
-o-transition: opacity 0.15s linear; |
|||
transition: opacity 0.15s linear; |
|||
} |
|||
.tb-hotkeys-container.fade.in { |
|||
z-index: 10002; |
|||
visibility: visible; |
|||
opacity: 1; |
|||
} |
|||
.tb-hotkeys-title { |
|||
font-weight: bold; |
|||
text-align: center; |
|||
font-size: 1.2em; |
|||
} |
|||
.tb-hotkeys { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: table-cell; |
|||
vertical-align: middle; |
|||
} |
|||
.tb-hotkeys table { |
|||
margin: auto; |
|||
color: #333; |
|||
} |
|||
.tb-content { |
|||
display: table-cell; |
|||
vertical-align: middle; |
|||
} |
|||
.tb-hotkeys-keys { |
|||
padding: 5px; |
|||
text-align: right; |
|||
} |
|||
.tb-hotkeys-key { |
|||
display: inline-block; |
|||
color: #fff; |
|||
background-color: #333; |
|||
border: 1px solid #333; |
|||
border-radius: 5px; |
|||
text-align: center; |
|||
margin-right: 5px; |
|||
box-shadow: inset 0 1px 0 #666, 0 1px 0 #bbb; |
|||
padding: 5px 9px; |
|||
font-size: 1em; |
|||
} |
|||
.tb-hotkeys-text { |
|||
padding-left: 10px; |
|||
font-size: 1em; |
|||
} |
|||
.tb-hotkeys-close { |
|||
position: fixed; |
|||
top: 20px; |
|||
right: 20px; |
|||
font-size: 2em; |
|||
font-weight: bold; |
|||
padding: 5px 10px; |
|||
border: 1px solid #ddd; |
|||
border-radius: 5px; |
|||
min-height: 45px; |
|||
min-width: 45px; |
|||
text-align: center; |
|||
} |
|||
.tb-hotkeys-close:hover { |
|||
background-color: #fff; |
|||
cursor: pointer; |
|||
} |
|||
@media all and (max-width: 500px) { |
|||
.tb-hotkeys { |
|||
font-size: 0.8em; |
|||
} |
|||
} |
|||
@media all and (min-width: 750px) { |
|||
.tb-hotkeys { |
|||
font-size: 1.2em; |
|||
} |
|||
} `],
|
|||
template : `<div tabindex="-1" class="tb-hotkeys-container fade" [ngClass]="{'in': helpVisible}" style="display:none"><div class="tb-hotkeys">
|
|||
<h4 class="tb-hotkeys-title">{{ title }}</h4> |
|||
<table *ngIf="helpVisible"><tbody> |
|||
<tr *ngFor="let hotkey of hotkeysList"> |
|||
<td class="tb-hotkeys-keys"> |
|||
<span *ngFor="let key of hotkey.formatted" class="tb-hotkeys-key">{{ key }}</span> |
|||
</td> |
|||
<td class="tb-hotkeys-text">{{ hotkey.description }}</td> |
|||
</tr> |
|||
</tbody></table> |
|||
<div class="tb-hotkeys-close" (click)="toggleCheatSheet()">×</div> |
|||
</div></div>`,
|
|||
}) |
|||
export class TbCheatSheetComponent implements OnInit, OnDestroy { |
|||
|
|||
helpVisible = false; |
|||
@Input() title: string = 'Keyboard Shortcuts:'; |
|||
|
|||
@Input() |
|||
hotkeys: Hotkey[]; |
|||
|
|||
hotkeysList: Hotkey[]; |
|||
|
|||
private mousetrap: MousetrapInstance; |
|||
|
|||
constructor(private _elementRef: ElementRef, |
|||
private hotkeysService: HotkeysService) { |
|||
this.mousetrap = new Mousetrap(this._elementRef.nativeElement); |
|||
this.mousetrap.bind('?', (event: KeyboardEvent, combo: string) => { |
|||
this.toggleCheatSheet(); |
|||
}); |
|||
} |
|||
|
|||
public ngOnInit(): void { |
|||
if (this.hotkeys) { |
|||
this.hotkeysList = this.hotkeys.filter(hotkey => hotkey.description); |
|||
} |
|||
} |
|||
|
|||
public setHotKeys(hotkeys: Hotkey[]) { |
|||
this.hotkeysList = hotkeys.filter(hotkey => hotkey.description); |
|||
} |
|||
|
|||
public toggleCheatSheet(): void { |
|||
this.helpVisible = !this.helpVisible; |
|||
} |
|||
|
|||
ngOnDestroy() { |
|||
this.mousetrap.unbind('?'); |
|||
} |
|||
} |
|||
@ -0,0 +1,86 @@ |
|||
///
|
|||
/// Copyright © 2016-2019 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import {Directive, Input, OnInit, OnDestroy, ElementRef} from '@angular/core'; |
|||
import {Hotkey, ExtendedKeyboardEvent} from 'angular2-hotkeys'; |
|||
import 'mousetrap'; |
|||
import { TbCheatSheetComponent } from '@shared/components/cheatsheet.component'; |
|||
|
|||
@Directive({ |
|||
selector : '[tb-hotkeys]' |
|||
}) |
|||
export class TbHotkeysDirective implements OnInit, OnDestroy { |
|||
@Input() hotkeys: Hotkey[] = []; |
|||
@Input() cheatSheet: TbCheatSheetComponent; |
|||
|
|||
private mousetrap: MousetrapInstance; |
|||
private hotkeysList: Hotkey[] = []; |
|||
|
|||
private _preventIn = ['INPUT', 'SELECT', 'TEXTAREA']; |
|||
|
|||
constructor(private _elementRef: ElementRef) { |
|||
this.mousetrap = new Mousetrap(this._elementRef.nativeElement); |
|||
(this._elementRef.nativeElement as HTMLElement).tabIndex = -1; |
|||
(this._elementRef.nativeElement as HTMLElement).style.outline = '0'; |
|||
} |
|||
|
|||
ngOnInit() { |
|||
for (let hotkey of this.hotkeys) { |
|||
this.hotkeysList.push(hotkey); |
|||
this.bindEvent(hotkey); |
|||
} |
|||
if (this.cheatSheet) { |
|||
let hotkeyObj: Hotkey = new Hotkey( |
|||
'?', |
|||
(event: KeyboardEvent) => { |
|||
this.cheatSheet.toggleCheatSheet(); |
|||
return false; |
|||
}, |
|||
[], |
|||
'Show / hide this help menu', |
|||
); |
|||
this.hotkeysList.unshift(hotkeyObj); |
|||
this.bindEvent(hotkeyObj); |
|||
this.cheatSheet.setHotKeys(this.hotkeysList); |
|||
} |
|||
} |
|||
|
|||
private bindEvent(hotkey: Hotkey): void { |
|||
this.mousetrap.bind((<Hotkey>hotkey).combo, (event: KeyboardEvent, combo: string) => { |
|||
let shouldExecute = true; |
|||
if(event) { |
|||
let target: HTMLElement = <HTMLElement>(event.target || event.srcElement); |
|||
let nodeName: string = target.nodeName.toUpperCase(); |
|||
if((' ' + target.className + ' ').indexOf(' mousetrap ') > -1) { |
|||
shouldExecute = true; |
|||
} else if(this._preventIn.indexOf(nodeName) > -1 && (<Hotkey>hotkey).allowIn.map(allow => allow.toUpperCase()).indexOf(nodeName) === -1) { |
|||
shouldExecute = false; |
|||
} |
|||
} |
|||
|
|||
if(shouldExecute) { |
|||
return (<Hotkey>hotkey).callback.apply(this, [event, combo]); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
ngOnDestroy() { |
|||
for (let hotkey of this.hotkeysList) { |
|||
this.mousetrap.unbind(hotkey.combo); |
|||
} |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue