@colijnit/configurator 1.0.20 → 1.0.21
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/.idea/Configurator.iml +12 -0
- package/.idea/codeStyles/Project.xml +21 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/misc.xml +9 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/angular.json +193 -0
- package/configurator.iml +11 -0
- package/dist/configurator/index.html +14 -0
- package/dist/configurator/main-es2015.js +3129 -0
- package/dist/configurator/main-es2015.js.map +1 -0
- package/dist/configurator/main-es5.js +5482 -0
- package/dist/configurator/main-es5.js.map +1 -0
- package/dist/configurator/polyfills-es2015.js +4520 -0
- package/dist/configurator/polyfills-es2015.js.map +1 -0
- package/dist/configurator/polyfills-es5.js +18375 -0
- package/dist/configurator/polyfills-es5.js.map +1 -0
- package/dist/configurator/runtime-es2015.js +155 -0
- package/dist/configurator/runtime-es2015.js.map +1 -0
- package/dist/configurator/runtime-es5.js +155 -0
- package/dist/configurator/runtime-es5.js.map +1 -0
- package/dist/configurator/styles-es2015.js +450 -0
- package/dist/configurator/styles-es2015.js.map +1 -0
- package/dist/configurator/styles-es5.js +432 -0
- package/dist/configurator/styles-es5.js.map +1 -0
- package/dist/configurator/vendor-es2015.js +155551 -0
- package/dist/configurator/vendor-es2015.js.map +1 -0
- package/dist/configurator/vendor-es5.js +183588 -0
- package/dist/configurator/vendor-es5.js.map +1 -0
- package/ng-package.json +9 -0
- package/package.json +47 -14
- package/src/app/app.component.ts +222 -0
- package/src/app/app.module.ts +34 -0
- package/src/app/builder.ts +480 -0
- package/src/app/components/answers/answer/answer.component.ts +61 -0
- package/src/app/components/answers/answers.component.ts +41 -0
- package/src/app/components/answers/answers.module.ts +26 -0
- package/src/app/components/selections/selections.component.ts +131 -0
- package/src/app/components/selections/selections.module.ts +20 -0
- package/src/app/components/shared/loader/loader.component.scss +33 -0
- package/src/app/components/shared/loader/loader.component.ts +20 -0
- package/src/app/components/shared/shared.module.ts +16 -0
- package/src/app/directives/visibility-observer-master.directive.ts +71 -0
- package/src/app/directives/visibility-observer.directive.ts +74 -0
- package/src/app/services/configurator.service.ts +86 -0
- package/src/app/services/image-cache.service.ts +56 -0
- package/src/app/services/locator.service.ts +6 -0
- package/src/environments/environment.prod.ts +3 -0
- package/src/environments/environment.ts +8 -0
- package/src/helper/variation-helper.ts +220 -0
- package/src/index.html +14 -0
- package/src/main.ts +11 -0
- package/src/model/material.ts +22 -0
- package/src/model/variation-settings.ts +14 -0
- package/src/model/variation.ts +11 -0
- package/src/polyfills.ts +73 -0
- package/{public_api.d.ts → src/public_api.ts} +6 -6
- package/src/style/shared.scss +173 -0
- package/src/style/styles.scss +45 -0
- package/src/tsconfig.app.json +16 -0
- package/src/tsconfig.spec.json +19 -0
- package/src/utils/asset.utils.ts +88 -0
- package/src/utils/file.utils.ts +156 -0
- package/src/utils/file.utils.unit.test.ts +8 -0
- package/src/utils/image.utils.ts +54 -0
- package/src/utils/object.utils.ts +52 -0
- package/src/utils/scene-utils.ts +119 -0
- package/src/utils/threed.utils.ts +219 -0
- package/src/utils/variation-utils.ts +216 -0
- package/tsconfig.json +23 -0
- package/tslint.json +132 -0
- package/app/builder.d.ts +0 -53
- package/app/components/answers/answer/answer.component.d.ts +0 -11
- package/app/components/answers/answers.component.d.ts +0 -8
- package/app/components/answers/answers.module.d.ts +0 -2
- package/app/components/selections/selections.component.d.ts +0 -22
- package/app/components/selections/selections.module.d.ts +0 -2
- package/app/components/shared/loader/loader.component.d.ts +0 -2
- package/app/components/shared/shared.module.d.ts +0 -2
- package/app/directives/visibility-observer-master.directive.d.ts +0 -9
- package/app/directives/visibility-observer.directive.d.ts +0 -13
- package/app/services/configurator.service.d.ts +0 -22
- package/app/services/image-cache.service.d.ts +0 -10
- package/app/services/locator.service.d.ts +0 -4
- package/bundles/colijnit-configurator.umd.js +0 -2745
- package/bundles/colijnit-configurator.umd.js.map +0 -1
- package/bundles/colijnit-configurator.umd.min.js +0 -17
- package/bundles/colijnit-configurator.umd.min.js.map +0 -1
- package/colijnit-configurator.d.ts +0 -10
- package/colijnit-configurator.metadata.json +0 -1
- package/esm2015/app/builder.js +0 -477
- package/esm2015/app/components/answers/answer/answer.component.js +0 -69
- package/esm2015/app/components/answers/answers.component.js +0 -43
- package/esm2015/app/components/answers/answers.module.js +0 -29
- package/esm2015/app/components/selections/selections.component.js +0 -134
- package/esm2015/app/components/selections/selections.module.js +0 -23
- package/esm2015/app/components/shared/loader/loader.component.js +0 -24
- package/esm2015/app/components/shared/shared.module.js +0 -21
- package/esm2015/app/directives/visibility-observer-master.directive.js +0 -51
- package/esm2015/app/directives/visibility-observer.directive.js +0 -57
- package/esm2015/app/services/configurator.service.js +0 -94
- package/esm2015/app/services/image-cache.service.js +0 -66
- package/esm2015/app/services/locator.service.js +0 -10
- package/esm2015/colijnit-configurator.js +0 -11
- package/esm2015/helper/variation-helper.js +0 -216
- package/esm2015/model/material.js +0 -11
- package/esm2015/model/variation-settings.js +0 -6
- package/esm2015/model/variation.js +0 -3
- package/esm2015/public_api.js +0 -7
- package/esm2015/utils/asset.utils.js +0 -74
- package/esm2015/utils/file.utils.js +0 -139
- package/esm2015/utils/image.utils.js +0 -52
- package/esm2015/utils/object.utils.js +0 -49
- package/esm2015/utils/scene-utils.js +0 -94
- package/esm2015/utils/threed.utils.js +0 -222
- package/esm2015/utils/variation-utils.js +0 -224
- package/esm5/app/builder.js +0 -591
- package/esm5/app/components/answers/answer/answer.component.js +0 -64
- package/esm5/app/components/answers/answers.component.js +0 -27
- package/esm5/app/components/answers/answers.module.js +0 -32
- package/esm5/app/components/selections/selections.component.js +0 -104
- package/esm5/app/components/selections/selections.module.js +0 -26
- package/esm5/app/components/shared/loader/loader.component.js +0 -16
- package/esm5/app/components/shared/shared.module.js +0 -24
- package/esm5/app/directives/visibility-observer-master.directive.js +0 -64
- package/esm5/app/directives/visibility-observer.directive.js +0 -59
- package/esm5/app/services/configurator.service.js +0 -160
- package/esm5/app/services/image-cache.service.js +0 -69
- package/esm5/app/services/locator.service.js +0 -13
- package/esm5/colijnit-configurator.js +0 -11
- package/esm5/helper/variation-helper.js +0 -268
- package/esm5/model/material.js +0 -13
- package/esm5/model/variation-settings.js +0 -8
- package/esm5/model/variation.js +0 -7
- package/esm5/public_api.js +0 -7
- package/esm5/utils/asset.utils.js +0 -106
- package/esm5/utils/file.utils.js +0 -151
- package/esm5/utils/image.utils.js +0 -56
- package/esm5/utils/object.utils.js +0 -56
- package/esm5/utils/scene-utils.js +0 -98
- package/esm5/utils/threed.utils.js +0 -279
- package/esm5/utils/variation-utils.js +0 -327
- package/fesm2015/colijnit-configurator.js +0 -2109
- package/fesm2015/colijnit-configurator.js.map +0 -1
- package/fesm5/colijnit-configurator.js +0 -2527
- package/fesm5/colijnit-configurator.js.map +0 -1
- package/helper/variation-helper.d.ts +0 -14
- package/model/material.d.ts +0 -17
- package/model/variation-settings.d.ts +0 -14
- package/model/variation.d.ts +0 -10
- package/utils/asset.utils.d.ts +0 -13
- package/utils/file.utils.d.ts +0 -27
- package/utils/image.utils.d.ts +0 -8
- package/utils/object.utils.d.ts +0 -7
- package/utils/scene-utils.d.ts +0 -7
- package/utils/threed.utils.d.ts +0 -16
- package/utils/variation-utils.d.ts +0 -12
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
|
2
|
+
import {Selection} from "@colijnit/configuratorapi/build/model/selection";
|
|
3
|
+
import {animate, state, style, transition, trigger} from "@angular/animations";
|
|
4
|
+
import {ImageCacheService} from '../../services/image-cache.service';
|
|
5
|
+
|
|
6
|
+
class SelectionViewModel {
|
|
7
|
+
public selection: Selection;
|
|
8
|
+
public children: Selection[] = [];
|
|
9
|
+
public expanded: boolean = false;
|
|
10
|
+
public thumbnail: string = '';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@Component({
|
|
14
|
+
selector: "selections",
|
|
15
|
+
template: `
|
|
16
|
+
<div class="ione-configurator">
|
|
17
|
+
<div class="rp-selections-summary">
|
|
18
|
+
<header class="drawer__header">
|
|
19
|
+
<h2 class="mat-title" [textContent]="'Configuratie'"></h2>
|
|
20
|
+
<!--<button>-->
|
|
21
|
+
<!---->
|
|
22
|
+
<!--</button>-->
|
|
23
|
+
</header>
|
|
24
|
+
<div class="selections-content">
|
|
25
|
+
<ng-container *ngFor="let selectionViewModel of selectionViewModels">
|
|
26
|
+
|
|
27
|
+
<div class="co-summary-line" (click)="selectSelection(selectionViewModel.selection, $event)">
|
|
28
|
+
<div class="selection-thumbnail">
|
|
29
|
+
<rp-loader *ngIf="selectionViewModel.thumbnail === ''"></rp-loader>
|
|
30
|
+
<img visibilityObserver *ngIf="selectionViewModel.thumbnail !== '' && selectionViewModel.thumbnail !== null" class="selection-img" [src]="selectionViewModel.thumbnail">
|
|
31
|
+
</div>
|
|
32
|
+
<div class="titles">
|
|
33
|
+
<div class="title-wrapper">
|
|
34
|
+
<label class="question" [textContent]="selectionViewModel.selection.question"></label>
|
|
35
|
+
<span class="answer" [textContent]="selectionViewModel.selection.answer"></span>
|
|
36
|
+
<div *ngIf="selectionViewModel.children.length > 0 && selectionViewModel.expanded" @showHideChildren>
|
|
37
|
+
<div class="child-selection" *ngFor="let selection of selectionViewModel.children"
|
|
38
|
+
(click)="selectSelection(selection, $event)"
|
|
39
|
+
>
|
|
40
|
+
<label class="question" [textContent]="selection.commercialQuestion"></label>
|
|
41
|
+
<span class="answer" [textContent]="selection.answer"></span>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div class="price-wrapper">
|
|
48
|
+
<span class="price-value"></span>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div class="collapse-wrapper">
|
|
52
|
+
<div class="collapse-content">
|
|
53
|
+
<div class="collapse-handle" [class.expanded]="selectionViewModel.expanded"
|
|
54
|
+
*ngIf="selectionViewModel.children.length > 0" (click)="expandClicked(selectionViewModel, $event)"></div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
</ng-container>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
`,
|
|
64
|
+
styleUrls: [
|
|
65
|
+
'../../../style/shared.scss'
|
|
66
|
+
],
|
|
67
|
+
animations: [
|
|
68
|
+
trigger('showHideChildren', [
|
|
69
|
+
state('void', style({'height': '0'})),
|
|
70
|
+
state('*', style({'height': '*'})),
|
|
71
|
+
transition('void <=> *', animate(200))
|
|
72
|
+
])
|
|
73
|
+
]
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
export class SelectionsComponent implements OnInit {
|
|
77
|
+
@Input()
|
|
78
|
+
public set selections(value: Selection[]) {
|
|
79
|
+
this._prepareSelections(value);
|
|
80
|
+
this._loadThumbnails();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public selectionViewModels: SelectionViewModel[] = [];
|
|
84
|
+
|
|
85
|
+
@Output()
|
|
86
|
+
public selectionClick: EventEmitter<Selection> = new EventEmitter<Selection>();
|
|
87
|
+
|
|
88
|
+
constructor(private _imageCacheService: ImageCacheService) {}
|
|
89
|
+
|
|
90
|
+
public ngOnInit(): void {
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public expandClicked(selectionViewModel: SelectionViewModel, mouseEvent: MouseEvent): void {
|
|
95
|
+
mouseEvent.preventDefault();
|
|
96
|
+
mouseEvent.stopImmediatePropagation();
|
|
97
|
+
selectionViewModel.expanded = !selectionViewModel.expanded;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public selectSelection(selection: Selection, mouseEvent: MouseEvent): void {
|
|
101
|
+
mouseEvent.preventDefault();
|
|
102
|
+
mouseEvent.stopImmediatePropagation();
|
|
103
|
+
this.selectionClick.next(selection);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private async _loadThumbnails(): Promise<void> {
|
|
107
|
+
if (this.selectionViewModels.length > 0) {
|
|
108
|
+
this.selectionViewModels.forEach(async (viewModel: SelectionViewModel) => {
|
|
109
|
+
await this._imageCacheService.getImageForSelectionOrAnswer(viewModel.selection).then((imageSrc: string) => {
|
|
110
|
+
viewModel.thumbnail = imageSrc === "" ? null : imageSrc;
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private _prepareSelections(value: Selection[]): void {
|
|
117
|
+
this.selectionViewModels.length = 0;
|
|
118
|
+
let selectionViewModel: SelectionViewModel;
|
|
119
|
+
value.forEach(s => {
|
|
120
|
+
if (s.presentationLevel === 1) {
|
|
121
|
+
selectionViewModel = new SelectionViewModel();
|
|
122
|
+
selectionViewModel.selection = s;
|
|
123
|
+
this.selectionViewModels.push(selectionViewModel);
|
|
124
|
+
} else if (s.presentationLevel > 1) {
|
|
125
|
+
if (selectionViewModel) {
|
|
126
|
+
selectionViewModel.children.push(s);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {NgModule} from "@angular/core";
|
|
2
|
+
import {CommonModule} from "@angular/common";
|
|
3
|
+
import {SelectionsComponent} from "./selections.component";
|
|
4
|
+
import {SharedModule} from '../shared/shared.module';
|
|
5
|
+
|
|
6
|
+
@NgModule({
|
|
7
|
+
imports: [
|
|
8
|
+
CommonModule,
|
|
9
|
+
SharedModule
|
|
10
|
+
],
|
|
11
|
+
declarations: [
|
|
12
|
+
SelectionsComponent
|
|
13
|
+
],
|
|
14
|
+
exports: [
|
|
15
|
+
SelectionsComponent
|
|
16
|
+
]
|
|
17
|
+
})
|
|
18
|
+
export class SelectionsModule {
|
|
19
|
+
|
|
20
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
user-select: none;
|
|
3
|
+
pointer-events: none;
|
|
4
|
+
.loader-wrapper {
|
|
5
|
+
z-index: 1100; // above dialogs
|
|
6
|
+
position: absolute;
|
|
7
|
+
width: 54px;
|
|
8
|
+
height: 54px;
|
|
9
|
+
svg {
|
|
10
|
+
width: 100%;
|
|
11
|
+
height: 100%;
|
|
12
|
+
.ripple1 {
|
|
13
|
+
transform-origin: center;
|
|
14
|
+
animation: ripple 1.5s infinite;
|
|
15
|
+
}
|
|
16
|
+
.ripple2 {
|
|
17
|
+
transform-origin: center;
|
|
18
|
+
animation: ripple 1.5s infinite .4s;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@keyframes ripple {
|
|
25
|
+
0% {
|
|
26
|
+
transform: scale(0);
|
|
27
|
+
opacity: 1;
|
|
28
|
+
}
|
|
29
|
+
100% {
|
|
30
|
+
transform: scale(1);
|
|
31
|
+
opacity: 0;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {Component} from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
selector: 'rp-loader',
|
|
5
|
+
template: `
|
|
6
|
+
<div class="loader-wrapper">
|
|
7
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="44" height="44" viewBox="0 0 44 44" stroke="#3760a1">
|
|
8
|
+
<g fill="none" fill-rule="evenodd" stroke-width="3">
|
|
9
|
+
<circle class="ripple1" cx="22" cy="22" r="19">
|
|
10
|
+
</circle>
|
|
11
|
+
<circle class="ripple2" cx="22" cy="22" r="19">
|
|
12
|
+
</circle>
|
|
13
|
+
</g>
|
|
14
|
+
</svg>
|
|
15
|
+
</div>
|
|
16
|
+
`,
|
|
17
|
+
styleUrls: ['./loader.component.scss']
|
|
18
|
+
})
|
|
19
|
+
export class LoaderComponent {
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import {LoaderComponent} from './loader/loader.component';
|
|
4
|
+
|
|
5
|
+
@NgModule({
|
|
6
|
+
imports: [
|
|
7
|
+
CommonModule
|
|
8
|
+
],
|
|
9
|
+
declarations: [
|
|
10
|
+
LoaderComponent
|
|
11
|
+
],
|
|
12
|
+
exports: [
|
|
13
|
+
LoaderComponent
|
|
14
|
+
]
|
|
15
|
+
})
|
|
16
|
+
export class SharedModule { }
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Import the core angular services.
|
|
2
|
+
import {Directive, OnDestroy} from '@angular/core';
|
|
3
|
+
|
|
4
|
+
@Directive({
|
|
5
|
+
selector: '[visibilityObserverMaster]'
|
|
6
|
+
})
|
|
7
|
+
export class VisibilityObserverMasterDirective implements OnDestroy {
|
|
8
|
+
|
|
9
|
+
private _mapping: Map<Element, Function>;
|
|
10
|
+
private _observer: IntersectionObserver;
|
|
11
|
+
|
|
12
|
+
// I initialize the intersection observer parent directive.
|
|
13
|
+
constructor() {
|
|
14
|
+
|
|
15
|
+
// As each observable child attaches itself to the parent observer, we need to
|
|
16
|
+
// map Elements to Callbacks so that when an Element's intersection changes,
|
|
17
|
+
// we'll know which callback to invoke. For this, we'll use an ES6 Map.
|
|
18
|
+
this._mapping = new Map();
|
|
19
|
+
|
|
20
|
+
this._observer = new IntersectionObserver(
|
|
21
|
+
(entries: IntersectionObserverEntry[]) => {
|
|
22
|
+
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
|
|
25
|
+
const callback = this._mapping.get(entry.target);
|
|
26
|
+
if (callback) {
|
|
27
|
+
callback(entry.isIntersecting);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
// This classifies the "intersection" as being a bit outside the
|
|
34
|
+
// viewport. The intent here is give the elements a little time to react
|
|
35
|
+
// to the change before the element is actually visible to the user.
|
|
36
|
+
rootMargin: '300px 0px 300px 0px'
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// I get called once when the host element is being destroyed.
|
|
43
|
+
public ngOnDestroy(): void {
|
|
44
|
+
|
|
45
|
+
this._mapping.clear();
|
|
46
|
+
this._observer.disconnect();
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ---
|
|
51
|
+
// PUBLIC METHODS.
|
|
52
|
+
// ---
|
|
53
|
+
|
|
54
|
+
// I add the given Element for intersection observation. When the intersection status
|
|
55
|
+
// changes, the given callback is invoked with the new status.
|
|
56
|
+
public add(element: HTMLElement, callback: Function): void {
|
|
57
|
+
|
|
58
|
+
this._mapping.set(element, callback);
|
|
59
|
+
this._observer.observe(element);
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// I remove the given Element from intersection observation.
|
|
64
|
+
public remove(element: HTMLElement): void {
|
|
65
|
+
|
|
66
|
+
this._mapping.delete(element);
|
|
67
|
+
this._observer.unobserve(element);
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
|
|
2
|
+
import {VisibilityObserverMasterDirective} from './visibility-observer-master.directive';
|
|
3
|
+
|
|
4
|
+
@Directive({
|
|
5
|
+
selector: '[visibilityObserver]',
|
|
6
|
+
exportAs: 'intersection'
|
|
7
|
+
})
|
|
8
|
+
export class VisibilityObserverDirective implements OnDestroy, OnInit {
|
|
9
|
+
|
|
10
|
+
@Input()
|
|
11
|
+
public observerEnabled: boolean = false;
|
|
12
|
+
|
|
13
|
+
public isIntersecting: boolean;
|
|
14
|
+
// These are just some human-friendly constants to make the HTML template a bit more
|
|
15
|
+
// readable when being consumed as part of SWTCH/CASE statements.
|
|
16
|
+
public IS_INTERSECTING: boolean = true;
|
|
17
|
+
public IS_NOT_INTERSECTING: boolean = false;
|
|
18
|
+
|
|
19
|
+
private _elementRef: ElementRef;
|
|
20
|
+
private _parent: VisibilityObserverMasterDirective;
|
|
21
|
+
|
|
22
|
+
// I initialize the intersection observer directive.
|
|
23
|
+
constructor(
|
|
24
|
+
parent: VisibilityObserverMasterDirective,
|
|
25
|
+
elementRef: ElementRef
|
|
26
|
+
) {
|
|
27
|
+
|
|
28
|
+
this._parent = parent;
|
|
29
|
+
this._elementRef = elementRef;
|
|
30
|
+
|
|
31
|
+
// By default, we're going to assume that the host element is NOT intersecting.
|
|
32
|
+
// Then, we'll use the IntersectionObserver to asynchronously check for changes
|
|
33
|
+
// in viewport visibility.
|
|
34
|
+
this.isIntersecting = false;
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ---
|
|
39
|
+
// PUBLIC METHODS.
|
|
40
|
+
// ---
|
|
41
|
+
|
|
42
|
+
// I get called once when the host element is being destroyed.
|
|
43
|
+
public ngOnDestroy(): void {
|
|
44
|
+
|
|
45
|
+
this._parent.remove(this._elementRef.nativeElement);
|
|
46
|
+
this._elementRef = undefined;
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
// I get called once after the inputs have been bound for the first time.
|
|
52
|
+
public ngOnInit(): void {
|
|
53
|
+
|
|
54
|
+
// In this demo, instead of using an IntersectionObserver per Element, we're
|
|
55
|
+
// going to use a shared observer in the parent element. However, we're still
|
|
56
|
+
// going to use a CALLBACK style approach so that we're only reducing the number
|
|
57
|
+
// of IntersectionObserver instances, not the number of Function calls.
|
|
58
|
+
if (this.observerEnabled) {
|
|
59
|
+
this._parent.add(
|
|
60
|
+
this._elementRef.nativeElement,
|
|
61
|
+
(isIntersecting: boolean) => {
|
|
62
|
+
|
|
63
|
+
this.isIntersecting = isIntersecting;
|
|
64
|
+
if (this.isIntersecting) {
|
|
65
|
+
this._parent.remove(this._elementRef.nativeElement);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {Injectable, Injector, OnDestroy} from '@angular/core';
|
|
2
|
+
import {Configurator} from '@colijnit/configuratorapi/build/configurator';
|
|
3
|
+
import {Subscription} from 'rxjs';
|
|
4
|
+
import {Selection} from '@colijnit/configuratorapi/build/model/selection';
|
|
5
|
+
import {Answer} from '@colijnit/configuratorapi/build/model/answer';
|
|
6
|
+
import {DataServiceResponseData} from '@colijnit/ioneconnector/build/model/data-service-response-data';
|
|
7
|
+
import {Options} from "@colijnit/ioneconnector/build/model/options";
|
|
8
|
+
import {QuestionAndAnswers} from "@colijnit/configuratorapi/build/model/question-and-answers";
|
|
9
|
+
import {ServiceLocator} from './locator.service';
|
|
10
|
+
import {notNill} from '@colijnit/configuratorapi/build/utils/function/not-nill.function';
|
|
11
|
+
import {NodeType} from '@colijnit/configuratorapi/build/enum/node-type.enum';
|
|
12
|
+
import {isNill} from '@colijnit/configuratorapi/build/utils/function/is-nill.function';
|
|
13
|
+
|
|
14
|
+
@Injectable({
|
|
15
|
+
providedIn: 'root'
|
|
16
|
+
})
|
|
17
|
+
export class ConfiguratorService {
|
|
18
|
+
|
|
19
|
+
private _configuratorApi: Configurator;
|
|
20
|
+
|
|
21
|
+
constructor(private _injector: Injector) {
|
|
22
|
+
if (!ServiceLocator.injector) {
|
|
23
|
+
ServiceLocator.injector = _injector;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public initApi(options: Options): void {
|
|
28
|
+
this._configuratorApi = new Configurator(options);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public async initNodeInstance(goodId: number): Promise<DataServiceResponseData> {
|
|
32
|
+
return await this._configuratorApi.initNodeInstance(goodId);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public async setInstanceToConfigure(id: string, showLoader: boolean = false): Promise<DataServiceResponseData> {
|
|
36
|
+
return await this._configuratorApi.setInstanceToConfigure(id, showLoader);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public async getGoodIdFromSku(sku: string, showLoader: boolean = false): Promise<DataServiceResponseData> {
|
|
40
|
+
return await this._configuratorApi.getGoodIdFromSku(sku, showLoader);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public async getArticleQuickSel(goodId: number, showLoader: boolean = false): Promise<DataServiceResponseData> {
|
|
44
|
+
return await this._configuratorApi.getArticleQuickSel(goodId, showLoader);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public async getSelections(showLoader: boolean = false, publicationCode: number = 2): Promise<DataServiceResponseData> {
|
|
48
|
+
const selections: DataServiceResponseData = await this._configuratorApi.getSelections(showLoader);
|
|
49
|
+
selections.resultObjects.filter((s: Selection) => {
|
|
50
|
+
(isNill(s.hierarchicalPublicationCode) || ((s.hierarchicalPublicationCode & publicationCode) > 0)) && (
|
|
51
|
+
(s.nodeType === NodeType.Question && (((s.questionPublicationCode & publicationCode) > 0) || isNill(s.questionPublicationCode))) ||
|
|
52
|
+
(s.nodeType === NodeType.Answer && (((s.answerPublicationCode & publicationCode) > 0) || isNill(s.answerPublicationCode))));
|
|
53
|
+
});
|
|
54
|
+
return selections;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public async getDecos(showLoader: boolean = false): Promise<DataServiceResponseData> {
|
|
58
|
+
return await this._configuratorApi.getDecos(showLoader);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public async getQuestionAndAnswers(showLoader: boolean = false, publicationCode: number = 2): Promise<QuestionAndAnswers> {
|
|
62
|
+
const questionAndAnswers: QuestionAndAnswers = await this._configuratorApi.getQuestionAndAnswers(showLoader);
|
|
63
|
+
questionAndAnswers.answers.filter((answer: Answer) => {
|
|
64
|
+
(notNill(answer.hierarchicalPublicationCode) && (answer.hierarchicalPublicationCode & publicationCode) === 0) ||
|
|
65
|
+
(answer.type === NodeType.Question && (answer.questionPublicationCode & publicationCode) === 0 && notNill(answer.questionPublicationCode)) ||
|
|
66
|
+
(answer.type === NodeType.Answer && (answer.publicationCode & publicationCode) === 0 && notNill(answer.publicationCode));
|
|
67
|
+
});
|
|
68
|
+
return questionAndAnswers;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public async getSingleImage(nodeId: number | string, publication: number, includeMimetype: boolean, thumb: boolean, showLoader: boolean): Promise<DataServiceResponseData> {
|
|
72
|
+
if (!nodeId) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
return await this._configuratorApi.getSingleImage(nodeId, publication, includeMimetype, thumb, showLoader);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public async selectSelection(selection: Selection, showLoader: boolean = false): Promise<DataServiceResponseData> {
|
|
79
|
+
return await this._configuratorApi.selectSelection(selection, showLoader);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public async selectAnswer(answer: Answer, showLoader: boolean = false): Promise<DataServiceResponseData> {
|
|
83
|
+
return await this._configuratorApi.selectAnswer(answer, showLoader);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import {DataServiceResponseData} from '@colijnit/ioneconnector/build/model/data-service-response-data';
|
|
3
|
+
import {ImageUtils} from '../../utils/image.utils';
|
|
4
|
+
import {Answer} from '@colijnit/configuratorapi/build/model/answer';
|
|
5
|
+
import {Selection} from '@colijnit/configuratorapi/build/model/selection';
|
|
6
|
+
import {ConfiguratorService} from './configurator.service';
|
|
7
|
+
|
|
8
|
+
@Injectable({
|
|
9
|
+
providedIn: 'root'
|
|
10
|
+
})
|
|
11
|
+
export class ImageCacheService {
|
|
12
|
+
|
|
13
|
+
// Map containing the retrieved images, @number = nodeId, @string = base64 string
|
|
14
|
+
private _imageCache: Map<number, string> = new Map();
|
|
15
|
+
|
|
16
|
+
constructor(private _configuratorService: ConfiguratorService) { }
|
|
17
|
+
|
|
18
|
+
private static _handleResponseData(includeMimetype: boolean, thumb: boolean, responseData: DataServiceResponseData): string {
|
|
19
|
+
if (responseData && responseData.resultObject) {
|
|
20
|
+
if (responseData.resultObject.filePath !== null && responseData.resultObject.filePath !== "") {
|
|
21
|
+
return ImageUtils.getFixedImageFilepathUrl(responseData.resultObject.filePath);
|
|
22
|
+
} else {
|
|
23
|
+
if (includeMimetype) {
|
|
24
|
+
return ImageUtils.getDocBodyWithMimeTypeDefinition(responseData.resultObject.fileName,
|
|
25
|
+
thumb ? responseData.resultObject.thumbnailBody : responseData.resultObject.documentBody);
|
|
26
|
+
} else {
|
|
27
|
+
return thumb ? responseData.resultObject.thumbnailBody : responseData.resultObject.documentBody;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public getImageForSelectionOrAnswer(object: Selection | Answer): Promise<string> {
|
|
36
|
+
const includeMimeType: boolean = true, thumb: boolean = true;
|
|
37
|
+
return new Promise((resolve: Function, reject: Function) => {
|
|
38
|
+
if (object && object.nodeId) {
|
|
39
|
+
if (!this._imageCache.has(object.nodeId)) {
|
|
40
|
+
return this._configuratorService.getSingleImage(object.nodeId, 4, includeMimeType, thumb, true)
|
|
41
|
+
.then((responseData: DataServiceResponseData) => {
|
|
42
|
+
const base64: string = ImageCacheService._handleResponseData(includeMimeType, thumb, responseData);
|
|
43
|
+
this._imageCache.set(object.nodeId, base64);
|
|
44
|
+
resolve(base64);
|
|
45
|
+
}).catch(() => {
|
|
46
|
+
reject();
|
|
47
|
+
});
|
|
48
|
+
} else {
|
|
49
|
+
resolve(this._imageCache.get(object.nodeId));
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
reject();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// The file contents for the current environment will overwrite these during build.
|
|
2
|
+
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
|
3
|
+
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
|
4
|
+
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
|
5
|
+
|
|
6
|
+
export const environment = {
|
|
7
|
+
production: false
|
|
8
|
+
};
|