btv-base-controls 0.1.22 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.browserslistrc +16 -0
- package/karma.conf.js +44 -0
- package/ng-package.json +7 -0
- package/package.json +10 -30
- package/src/assets/icon/state-icons.png +0 -0
- package/src/assets/theme/wmGlobals.scss +181 -0
- package/src/lib/basic.module.ts +48 -0
- package/src/lib/blink-message/blink-message.component.html +1 -0
- package/src/lib/blink-message/blink-message.component.scss +4 -0
- package/src/lib/blink-message/blink-message.component.ts +54 -0
- package/src/lib/btv-icon-button/btv-counter-button.html +18 -0
- package/src/lib/btv-icon-button/btv-counter-button.ts +34 -0
- package/src/lib/btv-icon-button/btv-icon-button.component.ts +62 -0
- package/src/lib/btv-icon-button/btv-icon-button.html +14 -0
- package/src/lib/btv-icon-button/btv-icon-button.scss +125 -0
- package/src/lib/btv-icon-button/index.ts +1 -0
- package/src/lib/btv-progress/btv-progress.component.ts +65 -0
- package/src/lib/btv-progress/btv-progress.html +11 -0
- package/src/lib/btv-progress/btv-progress.scss +24 -0
- package/src/lib/btv-search/btv-search.component.ts +78 -0
- package/src/lib/btv-search/btv-search.html +15 -0
- package/src/lib/btv-search/btv-search.scss +97 -0
- package/src/lib/btv-search/index.ts +1 -0
- package/src/lib/busy-indicator/busy-indicator.component.ts +13 -0
- package/src/lib/busy-indicator/busy-indicator.html +6 -0
- package/src/lib/busy-indicator/busy-indicator.scss +86 -0
- package/src/lib/custom-tool-tip/custom-tool-tip.component.html +9 -0
- package/src/lib/custom-tool-tip/custom-tool-tip.component.scss +47 -0
- package/src/lib/custom-tool-tip/custom-tool-tip.component.ts +44 -0
- package/src/lib/custom-tool-tip/tool-tip-renderer.directive.ts +111 -0
- package/src/lib/illustration/illustration.component.html +412 -0
- package/src/lib/illustration/illustration.component.scss +48 -0
- package/src/lib/illustration/illustration.component.ts +21 -0
- package/src/lib/wm-avatar/avatar.component.ts +179 -0
- package/src/lib/wm-avatar/avatar.html +13 -0
- package/src/lib/wm-avatar/avatar.scss +3 -0
- package/src/lib/wm-back-btn/wm-back-btn.component.ts +19 -0
- package/src/lib/wm-back-btn/wm-back-btn.html +7 -0
- package/src/lib/wm-back-btn/wm-back-btn.scss +51 -0
- package/src/lib/wm-beta-text/wm-beta-text.component.html +1 -0
- package/src/lib/wm-beta-text/wm-beta-text.component.scss +44 -0
- package/src/lib/wm-beta-text/wm-beta-text.component.ts +14 -0
- package/src/lib/wm-info/info-models.ts +22 -0
- package/src/lib/wm-info/wm-info.component.ts +238 -0
- package/src/lib/wm-info/wm-info.html +19 -0
- package/src/lib/wm-info/wm-info.scss +64 -0
- package/src/lib/wm-info-card/wm-info-card.component.ts +14 -0
- package/src/lib/wm-info-card/wm-info-card.html +13 -0
- package/src/lib/wm-info-card/wm-info-card.scss +56 -0
- package/src/lib/wm-no-content/wm-no-content.component.ts +17 -0
- package/src/lib/wm-no-content/wm-no-content.html +13 -0
- package/src/lib/wm-no-content/wm-no-content.scss +60 -0
- package/src/lib/wm-panel-bar/wm-panel-bar.component.ts +59 -0
- package/src/lib/wm-panel-bar/wm-panel-bar.html +37 -0
- package/src/lib/wm-panel-bar/wm-panel-bar.scss +114 -0
- package/src/lib/wm-scalable-div/scalable-div.component.ts +106 -0
- package/src/lib/wm-scalable-div/scalable-div.html +1 -0
- package/src/lib/wm-scalable-div/scalable-div.scss +11 -0
- package/src/lib/wm-spinner/wm-spinner.component.ts +129 -0
- package/src/lib/wm-spinner/wm-spinner.html +37 -0
- package/src/lib/wm-spinner/wm-spinner.scss +72 -0
- package/src/lib/wm-state-icon/wm-state-icon.component.html +4 -0
- package/src/lib/wm-state-icon/wm-state-icon.component.scss +26 -0
- package/src/lib/wm-state-icon/wm-state-icon.component.ts +18 -0
- package/src/lib/wm-tag/wm-tag.component.html +8 -0
- package/src/lib/wm-tag/wm-tag.component.scss +48 -0
- package/src/lib/wm-tag/wm-tag.component.ts +17 -0
- package/src/lib/wm-tamplate-image/wm-template-image.component.ts +56 -0
- package/src/lib/wm-tamplate-image/wm-template-image.html +3 -0
- package/src/lib/wm-tamplate-image/wm-template-image.scss +31 -0
- package/src/lib/wm-toggle/wm-toggle.component.ts +20 -0
- package/src/lib/wm-toggle/wm-toggle.html +5 -0
- package/src/lib/wm-toggle/wm-toggle.scss +33 -0
- package/src/models/guidExtension.ts +16 -0
- package/src/public-api.ts +29 -0
- package/src/test.ts +15 -0
- package/tsconfig.lib.json +15 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +17 -0
- package/esm2020/btv-base-controls.mjs +0 -5
- package/esm2020/lib/basic.module.mjs +0 -64
- package/esm2020/lib/blink-message/blink-message.component.mjs +0 -54
- package/esm2020/lib/btv-icon-button/btv-counter-button.mjs +0 -47
- package/esm2020/lib/btv-icon-button/btv-icon-button.component.mjs +0 -89
- package/esm2020/lib/btv-progress/btv-progress.component.mjs +0 -71
- package/esm2020/lib/btv-search/btv-search.component.mjs +0 -82
- package/esm2020/lib/busy-indicator/busy-indicator.component.mjs +0 -16
- package/esm2020/lib/custom-tool-tip/custom-tool-tip.component.mjs +0 -34
- package/esm2020/lib/custom-tool-tip/tool-tip-renderer.directive.mjs +0 -113
- package/esm2020/lib/illustration/illustration.component.mjs +0 -17
- package/esm2020/lib/wm-avatar/avatar.component.mjs +0 -175
- package/esm2020/lib/wm-back-btn/wm-back-btn.component.mjs +0 -26
- package/esm2020/lib/wm-beta-text/wm-beta-text.component.mjs +0 -19
- package/esm2020/lib/wm-info/info-models.mjs +0 -13
- package/esm2020/lib/wm-info/wm-info.component.mjs +0 -237
- package/esm2020/lib/wm-info-card/wm-info-card.component.mjs +0 -23
- package/esm2020/lib/wm-no-content/wm-no-content.component.mjs +0 -30
- package/esm2020/lib/wm-panel-bar/wm-panel-bar.component.mjs +0 -78
- package/esm2020/lib/wm-scalable-div/scalable-div.component.mjs +0 -105
- package/esm2020/lib/wm-spinner/wm-spinner.component.mjs +0 -135
- package/esm2020/lib/wm-state-icon/wm-state-icon.component.mjs +0 -18
- package/esm2020/lib/wm-tag/wm-tag.component.mjs +0 -28
- package/esm2020/lib/wm-tamplate-image/wm-template-image.component.mjs +0 -71
- package/esm2020/lib/wm-toggle/wm-toggle.component.mjs +0 -31
- package/esm2020/models/guidExtension.mjs +0 -15
- package/esm2020/public-api.mjs +0 -28
- package/fesm2015/btv-base-controls.mjs +0 -1479
- package/fesm2015/btv-base-controls.mjs.map +0 -1
- package/fesm2020/btv-base-controls.mjs +0 -1496
- package/fesm2020/btv-base-controls.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/lib/basic.module.d.ts +0 -33
- package/lib/blink-message/blink-message.component.d.ts +0 -20
- package/lib/btv-icon-button/btv-counter-button.d.ts +0 -12
- package/lib/btv-icon-button/btv-icon-button.component.d.ts +0 -30
- package/lib/btv-progress/btv-progress.component.d.ts +0 -20
- package/lib/btv-search/btv-search.component.d.ts +0 -31
- package/lib/busy-indicator/busy-indicator.component.d.ts +0 -7
- package/lib/custom-tool-tip/custom-tool-tip.component.d.ts +0 -35
- package/lib/custom-tool-tip/tool-tip-renderer.directive.d.ts +0 -49
- package/lib/illustration/illustration.component.d.ts +0 -10
- package/lib/wm-avatar/avatar.component.d.ts +0 -63
- package/lib/wm-back-btn/wm-back-btn.component.d.ts +0 -10
- package/lib/wm-beta-text/wm-beta-text.component.d.ts +0 -7
- package/lib/wm-info/info-models.d.ts +0 -20
- package/lib/wm-info/wm-info.component.d.ts +0 -34
- package/lib/wm-info-card/wm-info-card.component.d.ts +0 -9
- package/lib/wm-no-content/wm-no-content.component.d.ts +0 -11
- package/lib/wm-panel-bar/wm-panel-bar.component.d.ts +0 -25
- package/lib/wm-scalable-div/scalable-div.component.d.ts +0 -24
- package/lib/wm-spinner/wm-spinner.component.d.ts +0 -37
- package/lib/wm-state-icon/wm-state-icon.component.d.ts +0 -9
- package/lib/wm-tag/wm-tag.component.d.ts +0 -10
- package/lib/wm-tamplate-image/wm-template-image.component.d.ts +0 -49
- package/lib/wm-toggle/wm-toggle.component.d.ts +0 -11
- package/models/guidExtension.d.ts +0 -5
- package/public-api.d.ts +0 -24
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<div class="wm-info-card flex-row">
|
|
2
|
+
<div class="info-icon" *ngIf="!useCustomIcon">
|
|
3
|
+
<div class="icon-bg"></div>
|
|
4
|
+
<img class="info-svg" src="{{'./assets/icon/svg/' + icon + '.svg'}}" alt="type" />
|
|
5
|
+
</div>
|
|
6
|
+
<div class="info-icon" *ngIf="useCustomIcon">
|
|
7
|
+
<ng-content select="[wmCustomIcon]"></ng-content>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="flex-col info-content">
|
|
10
|
+
<div class="info-card-value text-hidden" title="{{value}}">{{value}}</div>
|
|
11
|
+
<div class="info-card-label text-hidden" title="{{label}}">{{label}}</div>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
@import './../../assets/theme/wmGlobals.scss';
|
|
2
|
+
.wm-info-card {
|
|
3
|
+
background: var(--pageBackgroundColor);
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 100px;
|
|
6
|
+
margin-right: 18px;
|
|
7
|
+
padding: 25px;
|
|
8
|
+
border-radius: 4px;
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
}
|
|
11
|
+
.info-icon {
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
width: 48px;
|
|
14
|
+
height: 48px;
|
|
15
|
+
border: 1px solid transparent;
|
|
16
|
+
border-radius: 50%;
|
|
17
|
+
margin: auto 18px auto 0;
|
|
18
|
+
flex-shrink: 0;
|
|
19
|
+
position: relative;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.icon-bg {
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
position: absolute;
|
|
27
|
+
background-color: var(--strongFontColor);
|
|
28
|
+
opacity: 0.05;
|
|
29
|
+
}
|
|
30
|
+
.info-svg {
|
|
31
|
+
margin: auto;
|
|
32
|
+
width: 24px;
|
|
33
|
+
height: 24px;
|
|
34
|
+
z-index: 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.info-content {
|
|
38
|
+
justify-content: center;
|
|
39
|
+
flex-grow: 1;
|
|
40
|
+
flex-shrink: 1;
|
|
41
|
+
overflow: hidden;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.info-card-value {
|
|
45
|
+
color: var(--strongFontColor);
|
|
46
|
+
line-height: 20px;
|
|
47
|
+
font-size: 22px;
|
|
48
|
+
width: 100%;
|
|
49
|
+
height: 20px;
|
|
50
|
+
margin-bottom: 2px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.info-card-label {
|
|
54
|
+
color: var(--disabledTextColor);
|
|
55
|
+
font-size: 14px;
|
|
56
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
+
import { IIllustrationId } from '../illustration/illustration.component';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'wm-no-content',
|
|
6
|
+
styleUrls: ['./wm-no-content.scss'],
|
|
7
|
+
templateUrl: './wm-no-content.html',
|
|
8
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
export class WmNoContentComponent {
|
|
12
|
+
@Input() icon: IIllustrationId = '';
|
|
13
|
+
@Input() label: string = '';
|
|
14
|
+
@Input() description: string = '';
|
|
15
|
+
@Input() useFooter: boolean = true;
|
|
16
|
+
@Input() additionContent: boolean = false;
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<wm-illustration [illustrationId]="icon" class="illustration">
|
|
3
|
+
</wm-illustration>
|
|
4
|
+
<div class="no-content-body" *ngIf="(label || description)">
|
|
5
|
+
<div class="no-content-label" *ngIf="label" [innerHTML]="label"></div>
|
|
6
|
+
<div class="no-content-desc" *ngIf="description"> {{description}}</div>
|
|
7
|
+
<div class="no-content-desc" *ngIf="additionContent">
|
|
8
|
+
<ng-content select="[additionContent]"></ng-content>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="no-foot" *ngIf="useFooter">
|
|
12
|
+
<ng-content></ng-content>
|
|
13
|
+
</div>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
@import './../../assets/theme/wmGlobals.scss';
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
width: 100%;
|
|
7
|
+
height: 100%;
|
|
8
|
+
|
|
9
|
+
margin: auto;
|
|
10
|
+
text-align: center;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
padding: 0px 10px;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.illustration {
|
|
17
|
+
min-width: 260px;
|
|
18
|
+
max-width: 520px;
|
|
19
|
+
margin: auto;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.no-content-wrap * {
|
|
23
|
+
box-sizing: inherit;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.img-wrap {
|
|
27
|
+
width: 120px;
|
|
28
|
+
height: 120px;
|
|
29
|
+
margin: 0px auto;
|
|
30
|
+
background-repeat: no-repeat;
|
|
31
|
+
cursor: default;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.no-content-body {
|
|
35
|
+
width: 100%;
|
|
36
|
+
padding: 12px 0px;
|
|
37
|
+
overflow-y: hidden;
|
|
38
|
+
cursor: default;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.no-content-label {
|
|
42
|
+
color: var(--disabledFontColor);
|
|
43
|
+
font-size: $fontSize + 4;
|
|
44
|
+
padding-top: 12px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.no-content-desc {
|
|
48
|
+
color: var(--mediumFontColor);
|
|
49
|
+
font-size: $fontSize + 2;
|
|
50
|
+
word-break: break-word;
|
|
51
|
+
padding-top: 12px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.no-foot {
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 64px;
|
|
57
|
+
display: flex;
|
|
58
|
+
justify-content: center;
|
|
59
|
+
padding: 12px 0px;
|
|
60
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
selector: 'wm-panel-bar',
|
|
5
|
+
styleUrls: ['wm-panel-bar.scss'],
|
|
6
|
+
templateUrl: './wm-panel-bar.html'
|
|
7
|
+
})
|
|
8
|
+
export class WmPanelBarComponent {
|
|
9
|
+
@Input() label: string;
|
|
10
|
+
@Input() labelClasses: 'pb-label' | 'brand-label' = 'pb-label';
|
|
11
|
+
@Input() openedLabel: string;
|
|
12
|
+
|
|
13
|
+
@Input() width: string;
|
|
14
|
+
@Input() height: string;
|
|
15
|
+
@Input() maxHeight: string = 'unset';
|
|
16
|
+
@Input() maxWidth: string = 'unset';
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
private _open: boolean= false;
|
|
20
|
+
|
|
21
|
+
@Input() set open(value: boolean) {
|
|
22
|
+
if (value === this._open) return;
|
|
23
|
+
this._open = value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get open(): boolean {
|
|
27
|
+
return this._open;
|
|
28
|
+
}
|
|
29
|
+
@Input() collapseText: string = 'Collapse';
|
|
30
|
+
@Input() expandText: string = 'Expand';
|
|
31
|
+
@Output() openChange: EventEmitter<boolean> = new EventEmitter<boolean>();
|
|
32
|
+
directionBottom: boolean = true;
|
|
33
|
+
directionLeft: boolean = false;
|
|
34
|
+
|
|
35
|
+
private _direction: 'bottom' | 'left' = 'bottom';
|
|
36
|
+
get direction() { return this._direction; }
|
|
37
|
+
@Input() set direction(val) {
|
|
38
|
+
if (val !== 'bottom' && val !== 'left') {
|
|
39
|
+
val = 'bottom';
|
|
40
|
+
}
|
|
41
|
+
this._direction = val;
|
|
42
|
+
switch (val) {
|
|
43
|
+
case 'left':
|
|
44
|
+
this.directionLeft = true;
|
|
45
|
+
this.directionBottom = false;
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
this.directionBottom = true;
|
|
49
|
+
this.directionLeft = false;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
onClick() {
|
|
56
|
+
this.open = !this.open;
|
|
57
|
+
this.openChange.emit(this.open);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<div *ngIf="directionBottom" class="wm-panel-bar drb flex-col"
|
|
2
|
+
[ngStyle]="{'max-width': maxWidth, 'max-height': maxHeight}">
|
|
3
|
+
<div class="pb-header align-center flex-row">
|
|
4
|
+
<div class={{labelClasses}} *ngIf="label">{{label}}</div>
|
|
5
|
+
<ng-content select="[headerLabel]"></ng-content>
|
|
6
|
+
<div class="pb-header-content flex-row">
|
|
7
|
+
<ng-content select="[headerContent]"></ng-content>
|
|
8
|
+
<div class="ex-button" (click)="onClick()">
|
|
9
|
+
<span>{{ (open ? collapseText : expandText)}}</span>
|
|
10
|
+
<wm-template-image class="bar-arrow" [ngClass]="{'bar-open-bottom': open}" icon="arrow-down">
|
|
11
|
+
</wm-template-image>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="flex-row pb-content pb-vertical" [ngStyle]="{'height': !open ? '0px': ''}"
|
|
16
|
+
[ngClass]="{'pb-vertical-visible': open}">
|
|
17
|
+
<ng-container *ngTemplateOutlet="body"></ng-container>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div *ngIf="!directionBottom" class="wm-panel-bar flex-col drl" [ngClass]="{'pb-drl-open': open}"
|
|
22
|
+
[ngStyle]="{'max-width': maxWidth, 'max-height': maxHeight}">
|
|
23
|
+
<div class="ex-panel flex-row ex-panel-drl" (click)="onClick()">
|
|
24
|
+
<wm-template-image class="bar-arrow arrow-left" [ngClass]="{'bar-open-left': open}" icon="arrow-left">
|
|
25
|
+
</wm-template-image>
|
|
26
|
+
<div class="preview-label" *ngIf="!open">{{label}}</div>
|
|
27
|
+
<div class="preview-label" *ngIf="open">{{openedLabel || label}}</div>
|
|
28
|
+
|
|
29
|
+
</div>
|
|
30
|
+
<div class="flex-col pb-content pb-horizontal-visible" *ngIf="open">
|
|
31
|
+
<ng-container *ngTemplateOutlet="body"></ng-container>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<ng-template #body>
|
|
36
|
+
<ng-content></ng-content>
|
|
37
|
+
</ng-template>
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
@import './../../assets/theme/wmGlobals.scss';
|
|
2
|
+
|
|
3
|
+
.wm-panel-bar {
|
|
4
|
+
border-radius: 4px;
|
|
5
|
+
background: var(--pageBackgroundColor);
|
|
6
|
+
flex-shrink: 0;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
direction: ltr;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
.ex-button {
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
color: var(--mediumFontColor);
|
|
16
|
+
letter-spacing: 0;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
background: transparent;
|
|
19
|
+
border: none;
|
|
20
|
+
@include flexJA(flex-end, center);
|
|
21
|
+
width: 86px;
|
|
22
|
+
margin-left: 8px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.pb-header {
|
|
26
|
+
width: 100%;
|
|
27
|
+
flex-shrink: 0;
|
|
28
|
+
min-height: 48px;
|
|
29
|
+
font-size: $fontSize;
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
padding: 4px 16px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.pb-label {
|
|
35
|
+
font-weight: bold;
|
|
36
|
+
color: var(--strongFontColor);
|
|
37
|
+
letter-spacing: 1.2px;
|
|
38
|
+
line-height: 16px;
|
|
39
|
+
margin-right: 12px;
|
|
40
|
+
flex-shrink: 1;
|
|
41
|
+
white-space: nowrap;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
text-overflow: ellipsis;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.brand-label {
|
|
47
|
+
@extend .pb-label;
|
|
48
|
+
color: var(--brandColor);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.pb-header-content {
|
|
52
|
+
align-items: center;
|
|
53
|
+
margin-left: auto;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.bar-open-left,
|
|
57
|
+
.bar-open-right {
|
|
58
|
+
transform: rotate3d(0, 1, 0, -180deg);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.drb {
|
|
62
|
+
box-shadow: 0 0 1px 0 rgba(10, 22, 70, 0.06), 0 1px 1px 0 rgba(10, 22, 70, 0.10);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.drr {
|
|
66
|
+
flex-direction: row-reverse;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.pb-drl-open {
|
|
70
|
+
width: 100%;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.pb-vertical {
|
|
74
|
+
height: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.pb-content {
|
|
78
|
+
direction: ltr;
|
|
79
|
+
visibility: hidden;
|
|
80
|
+
overflow: auto;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.pb-vertical-visible {
|
|
84
|
+
visibility: visible;
|
|
85
|
+
height: 100%;
|
|
86
|
+
max-height: calc(100% - 48px);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.pb-horizontal-visible {
|
|
90
|
+
visibility: visible;
|
|
91
|
+
width: 100%;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.ex-panel {
|
|
95
|
+
height: 40px;
|
|
96
|
+
width: auto;;
|
|
97
|
+
min-width: 1px;
|
|
98
|
+
max-width: 100%;
|
|
99
|
+
flex-shrink: 0;
|
|
100
|
+
cursor: pointer;
|
|
101
|
+
background: transparent;
|
|
102
|
+
border-radius: 4px;
|
|
103
|
+
box-shadow: 1px 1px 2px 2px rgba(10, 22, 70, 0.06);
|
|
104
|
+
justify-content: flex-start;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.arrow-left {
|
|
108
|
+
margin: auto 0px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.preview-label {
|
|
112
|
+
align-items: center;
|
|
113
|
+
margin: auto 4px;
|
|
114
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, ViewChild, OnDestroy, NgZone, ChangeDetectorRef } from '@angular/core';
|
|
2
|
+
import { interval, Subscription } from 'rxjs';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'wm-scalable-div',
|
|
6
|
+
styleUrls: ['./scalable-div.scss'],
|
|
7
|
+
templateUrl: './scalable-div.html'
|
|
8
|
+
})
|
|
9
|
+
export class ScalableDivComponent implements AfterViewInit, OnDestroy {
|
|
10
|
+
|
|
11
|
+
@Input() divClass: string;
|
|
12
|
+
@ViewChild('divEl', { static: true }) divEl: ElementRef;
|
|
13
|
+
isCalculated: boolean = false;
|
|
14
|
+
firstObservable: Subscription;
|
|
15
|
+
|
|
16
|
+
private _text: string | number;
|
|
17
|
+
public get text(): string | number { return this._text; }
|
|
18
|
+
@Input() public set text(value: string | number) {
|
|
19
|
+
this._text = value;
|
|
20
|
+
this.recalculateWidth();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
constructor(private _zone: NgZone, private _change: ChangeDetectorRef) {
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public ngAfterViewInit() {
|
|
28
|
+
this._zone.runOutsideAngular(() => {
|
|
29
|
+
this.firstObservable = interval(500).subscribe(it => {
|
|
30
|
+
if (this.isCalculated) {
|
|
31
|
+
this.firstObservable.unsubscribe();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.recalculateWidth();
|
|
35
|
+
this._change.detectChanges();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
ngOnDestroy(): void {
|
|
41
|
+
if (!this.firstObservable) return;
|
|
42
|
+
this.firstObservable.unsubscribe();
|
|
43
|
+
this.firstObservable = undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private getNumberFromFontSize(fontSize: string): number {
|
|
47
|
+
const numberSize = Number(fontSize.substr(0, fontSize.length - 2));
|
|
48
|
+
return numberSize;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private getFontSizeDim(fontSize: string): string {
|
|
52
|
+
let num: number;
|
|
53
|
+
let dimLength: number = 0;
|
|
54
|
+
while (!num) {
|
|
55
|
+
dimLength = dimLength + 1;
|
|
56
|
+
num = Number(fontSize.substr(0, fontSize.length - dimLength));
|
|
57
|
+
}
|
|
58
|
+
return fontSize.substr(fontSize.length - dimLength, dimLength);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private divWidth(text: string, font: string, padding: string) {
|
|
62
|
+
const f = font || '12px arial';
|
|
63
|
+
const o = document.createElement('div');
|
|
64
|
+
o.innerHTML = text;
|
|
65
|
+
o.style.position = 'absolute';
|
|
66
|
+
o.style.visibility = 'hidden';
|
|
67
|
+
o.style['text-align'] = 'center';
|
|
68
|
+
o.style.font = f;
|
|
69
|
+
o.style.padding = padding;
|
|
70
|
+
document.body.appendChild(o);
|
|
71
|
+
const w = o.clientWidth;
|
|
72
|
+
document.body.removeChild(o);
|
|
73
|
+
return w;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public recalculateWidth() {
|
|
77
|
+
if (!this.divEl) return;
|
|
78
|
+
const divTag = this.divEl.nativeElement;
|
|
79
|
+
if ((<any>divTag).clientWidth === 0) return;
|
|
80
|
+
this.isCalculated = true;
|
|
81
|
+
this.doRecalculateWidth(divTag);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private doRecalculateWidth(divTag: HTMLElement) {
|
|
85
|
+
divTag.style.fontSize = '';
|
|
86
|
+
const style = window.getComputedStyle(divTag);
|
|
87
|
+
const availableWidth = divTag.offsetParent.clientWidth;
|
|
88
|
+
const sizeDim = this.getFontSizeDim(style.fontSize);
|
|
89
|
+
const text = divTag.textContent;
|
|
90
|
+
let font = style.font;
|
|
91
|
+
let textWidth = this.divWidth(text, font, style.padding);
|
|
92
|
+
const needChange: boolean = availableWidth < textWidth;
|
|
93
|
+
let numberSize = this.getNumberFromFontSize(style.fontSize);
|
|
94
|
+
let stringSize = numberSize.toString() + sizeDim;
|
|
95
|
+
while (textWidth - availableWidth > 1) {
|
|
96
|
+
numberSize = numberSize - 1;
|
|
97
|
+
const oldString = stringSize;
|
|
98
|
+
stringSize = numberSize.toString() + sizeDim;
|
|
99
|
+
font = font.replace(oldString, stringSize);
|
|
100
|
+
textWidth = this.divWidth(text, font, style.padding);
|
|
101
|
+
}
|
|
102
|
+
if (needChange) divTag.style.fontSize = stringSize;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<div #divEl [ngClass]="divClass">{{text}}<div>
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, NgZone, OnDestroy, OnInit } from '@angular/core';
|
|
2
|
+
import { Subscription, timer } from 'rxjs';
|
|
3
|
+
import { Guid } from '../../models/guidExtension';
|
|
4
|
+
import { InfoType } from '../wm-info/info-models';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'wm-spinner',
|
|
8
|
+
styleUrls: ['./wm-spinner.scss'],
|
|
9
|
+
templateUrl: './wm-spinner.html',
|
|
10
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
11
|
+
})
|
|
12
|
+
export class SpinnerComponent implements OnInit, OnDestroy {
|
|
13
|
+
|
|
14
|
+
private uid = Guid.newGuid();
|
|
15
|
+
|
|
16
|
+
private _longMessageTimeSubscription: Subscription;
|
|
17
|
+
private _showOverlayTimerSubscription: Subscription;
|
|
18
|
+
private _startDate;
|
|
19
|
+
private _initialized = false;
|
|
20
|
+
public isOverlayVisible = false;
|
|
21
|
+
public isOverlayContrast = false;
|
|
22
|
+
public minTimeOfVisibilityMs = 500;
|
|
23
|
+
public showDelay = 250;
|
|
24
|
+
|
|
25
|
+
@Input() public delay = false;
|
|
26
|
+
@Input() public longMessageDelay = 12500;
|
|
27
|
+
@Input() public message: string = 'Waiting for data from server';
|
|
28
|
+
@Input() public messageTakesLong = 'Request is taking a bit longer than expected';
|
|
29
|
+
@Input() public messageBottomWait: string = 'Please Wait';
|
|
30
|
+
@Input() public detailInfoMessage: string;
|
|
31
|
+
@Input() public infoType: InfoType = InfoType.Error;
|
|
32
|
+
|
|
33
|
+
private _showSpinner: boolean;
|
|
34
|
+
public get showSpinner() { return this._showSpinner; }
|
|
35
|
+
@Input() public set showSpinner(value: boolean) {
|
|
36
|
+
// tslint:disable-next-line:triple-equals we should treat bool false and bool undefined as same. The same for all other cases.
|
|
37
|
+
if (this._showSpinner == value) return;
|
|
38
|
+
this._showSpinner = value;
|
|
39
|
+
this.unsubscribeTimers();
|
|
40
|
+
|
|
41
|
+
if (value) {
|
|
42
|
+
console.log('spinner started', this.uid);
|
|
43
|
+
// block UI, keep it light
|
|
44
|
+
this.isOverlayVisible = true;
|
|
45
|
+
this.subscribeTimers();
|
|
46
|
+
this.detectChanges();
|
|
47
|
+
} else {
|
|
48
|
+
this.stopShowingProgress();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
constructor(private zone: NgZone, private change: ChangeDetectorRef) {
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
ngOnInit(): void {
|
|
56
|
+
this._initialized = true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ngOnDestroy(): void {
|
|
60
|
+
console.log('destroy');
|
|
61
|
+
this.unsubscribeTimers();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private subscribeTimers() {
|
|
65
|
+
this.zone.runOutsideAngular(() => {
|
|
66
|
+
// show long wait message after few configured seconds
|
|
67
|
+
const longMessageTimer = timer(this.longMessageDelay);
|
|
68
|
+
this._longMessageTimeSubscription = longMessageTimer.subscribe(t => {
|
|
69
|
+
this.message = this.messageTakesLong;
|
|
70
|
+
this.change.detectChanges();
|
|
71
|
+
this._longMessageTimeSubscription.unsubscribe();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// draw overlay message after few configured seconds
|
|
75
|
+
if (!this.delay) {
|
|
76
|
+
this.startShowingProgress();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const showAfterDelayTimer = timer(this.showDelay);
|
|
80
|
+
this._showOverlayTimerSubscription = showAfterDelayTimer.subscribe(t => {
|
|
81
|
+
if (this.showSpinner) this.startShowingProgress();
|
|
82
|
+
this.change.detectChanges();
|
|
83
|
+
this._showOverlayTimerSubscription.unsubscribe();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private unsubscribeTimers() {
|
|
89
|
+
if (this._longMessageTimeSubscription) this._longMessageTimeSubscription.unsubscribe();
|
|
90
|
+
if (this._showOverlayTimerSubscription) this._showOverlayTimerSubscription.unsubscribe();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private stopShowingProgress() {
|
|
94
|
+
if (this._startDate) {
|
|
95
|
+
const now = new Date().getTime();
|
|
96
|
+
const duration = (now - this._startDate.getTime()); // ms
|
|
97
|
+
if (duration < this.minTimeOfVisibilityMs) {
|
|
98
|
+
this.zone.runOutsideAngular(() => {
|
|
99
|
+
// let it be at least one second.
|
|
100
|
+
console.log('remains', this.minTimeOfVisibilityMs - duration);
|
|
101
|
+
setTimeout(() => this.doStopProgress(), this.minTimeOfVisibilityMs - duration);
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
this.doStopProgress();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private startShowingProgress() {
|
|
110
|
+
console.log('contrast spinner', this.uid);
|
|
111
|
+
this._startDate = new Date();
|
|
112
|
+
this.isOverlayContrast = true;
|
|
113
|
+
this.detectChanges();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private doStopProgress() {
|
|
117
|
+
console.log('spinner ended', this.uid);
|
|
118
|
+
this.isOverlayContrast = false;
|
|
119
|
+
this.isOverlayVisible = false;
|
|
120
|
+
this._startDate = undefined;
|
|
121
|
+
this.detectChanges();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private detectChanges() {
|
|
125
|
+
if (!this._initialized) return;
|
|
126
|
+
this.change.detectChanges();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<div class="spinner-wrap flex-col wh-100" *ngIf="isOverlayVisible">
|
|
2
|
+
<div class="spinner-bg wh-100" [ngClass]="{'invisible': !isOverlayContrast }"></div>
|
|
3
|
+
<div class="spinner-content inline-col marginXA align-center" [ngClass]="{'invisible': !isOverlayContrast }">
|
|
4
|
+
<div class="msg-wrap marginBottomX8">
|
|
5
|
+
<div style="display: flex">
|
|
6
|
+
<div class="msg">{{message}}</div>
|
|
7
|
+
<wm-info class="info" [type]="infoType" popupPosition="top-center"
|
|
8
|
+
[iconAsTemplate]="infoType===2" [useThemeForIconTemplate]="infoType===2"
|
|
9
|
+
*ngIf="detailInfoMessage" [header]="detailInfoMessage" style="margin-left: 4px"></wm-info>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div class="msg">{{messageBottomWait}}</div>
|
|
13
|
+
</div>
|
|
14
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 168 168" id="loader">
|
|
15
|
+
<defs>
|
|
16
|
+
<linearGradient id="a" x1="38.078%" x2="4.941%" y1="8.411%" y2="16.987%">
|
|
17
|
+
<stop offset="0%" stop-color="var(--brandColor)" stop-opacity="0.1" />
|
|
18
|
+
<stop offset="61.554%" stop-color="var(--brandColor)" stop-opacity="0.4" />
|
|
19
|
+
<stop offset="100%" stop-color="var(--brandColor)" stop-opacity="0.5" />
|
|
20
|
+
</linearGradient>
|
|
21
|
+
<radialGradient id="b" cy="43.835%" r="54.9%" fx="50%" fy="43.835%"
|
|
22
|
+
gradientTransform="matrix(-.77913 .62687 -.6485 -.80602 1.174 .478)">
|
|
23
|
+
<stop offset="0%" stop-color="#FFF" />
|
|
24
|
+
<stop offset="100%" stop-color="var(--brandColor)" stop-opacity="0.5" />
|
|
25
|
+
</radialGradient>
|
|
26
|
+
</defs>
|
|
27
|
+
<g fill="none" fill-rule="evenodd">
|
|
28
|
+
<g transform="translate(10 10)">
|
|
29
|
+
<path stroke="url(#a)" stroke-linecap="round" stroke-width="19"
|
|
30
|
+
d="M16.198 27.79C6.062 40.453 0 56.518 0 74c0 40.87 33.13 74 74 74s74-33.13 74-74c0-24.611-12.014-46.416-30.498-59.87C105.292 5.244 90.258 0 74 0" />
|
|
31
|
+
<circle cx="16.5" cy="27.5" r="9.5" fill="url(#b)" />
|
|
32
|
+
</g>
|
|
33
|
+
</g>
|
|
34
|
+
</svg>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
</div>
|