mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Compare commits
424 Commits
post-2.1-h
...
feature/rd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6daa96119d | ||
|
|
128a280dee | ||
|
|
475c885344 | ||
|
|
ee62649bf6 | ||
|
|
109999d66f | ||
|
|
9ec34b07c4 | ||
|
|
216d302a86 | ||
|
|
4a97800a05 | ||
|
|
f98aac5231 | ||
|
|
9c4e94ce8d | ||
|
|
65a19feffc | ||
|
|
62a1be7abe | ||
|
|
ad4481cfc7 | ||
|
|
e4c20b953d | ||
|
|
e8044fae1b | ||
|
|
c4818319aa | ||
|
|
8cb25d6ca1 | ||
|
|
5a14e0afbd | ||
|
|
0804eeeccb | ||
|
|
f015169011 | ||
|
|
201ea2ee9c | ||
|
|
961211e638 | ||
|
|
22a494e31e | ||
|
|
75e24771b3 | ||
|
|
97b30d5b14 | ||
|
|
e065c1a8da | ||
|
|
fc76f34d38 | ||
|
|
98e963d782 | ||
|
|
8a4fe7aedd | ||
|
|
90268b4ec1 | ||
|
|
034693df98 | ||
|
|
5b31661f8d | ||
|
|
3b89777648 | ||
|
|
d48b59b374 | ||
|
|
7d72fc56db | ||
|
|
90edb7dd7e | ||
|
|
7ee0c4d145 | ||
|
|
67f2ff54be | ||
|
|
1b85c8ff50 | ||
|
|
f0470d3faa | ||
|
|
4d5e81a638 | ||
|
|
7676ae8143 | ||
|
|
fb97db99b0 | ||
|
|
92aad95603 | ||
|
|
513cef2a66 | ||
|
|
bdf3bbc530 | ||
|
|
9a17f95026 | ||
|
|
e6b44d8365 | ||
|
|
874f8f4758 | ||
|
|
47baf2fa89 | ||
|
|
57bfc523ab | ||
|
|
23edea5fa4 | ||
|
|
7b12857a35 | ||
|
|
d6d919ed52 | ||
|
|
330c59f7e9 | ||
|
|
0c65e9dace | ||
|
|
ed144f0a15 | ||
|
|
c0c2cc86d3 | ||
|
|
9b8ea11866 | ||
|
|
17aed38316 | ||
|
|
48a7cc4dd4 | ||
|
|
4417fd9f0d | ||
|
|
3e429cb261 | ||
|
|
48e30e795f | ||
|
|
953e528298 | ||
|
|
4276f427b9 | ||
|
|
4b2bfefc9b | ||
|
|
11e79c4830 | ||
|
|
264d914044 | ||
|
|
12f1e7c3af | ||
|
|
9eb4fbab65 | ||
|
|
8d1a63e47f | ||
|
|
e449e612c1 | ||
|
|
6ba65f031b | ||
|
|
f31ac4c2e3 | ||
|
|
f980f5aaf9 | ||
|
|
45989d7abd | ||
|
|
87a1e8a2c4 | ||
|
|
ae27da1127 | ||
|
|
ca21931d93 | ||
|
|
5bb9ebd6ec | ||
|
|
45ab1e9cc5 | ||
|
|
8d2685a8c3 | ||
|
|
d38c41a99d | ||
|
|
ff3dacde39 | ||
|
|
5c9f4c5b21 | ||
|
|
c134f645ef | ||
|
|
6f0933a350 | ||
|
|
c9a90211ee | ||
|
|
95d96dd295 | ||
|
|
86bf079f6f | ||
|
|
c202490555 | ||
|
|
da0100dd35 | ||
|
|
b634247463 | ||
|
|
84df6493f6 | ||
|
|
90b752e185 | ||
|
|
d3858c731c | ||
|
|
f247ac641c | ||
|
|
be1a9e8f7e | ||
|
|
d86f595b1f | ||
|
|
3ed9227508 | ||
|
|
74bf2133c6 | ||
|
|
e4570946c4 | ||
|
|
a8213d79fd | ||
|
|
13ec323ac4 | ||
|
|
9cfe8176d4 | ||
|
|
c544cebba9 | ||
|
|
74dffe8af2 | ||
|
|
3999b8f623 | ||
|
|
9d3bb9dcf3 | ||
|
|
05e58aa060 | ||
|
|
f74d14d573 | ||
|
|
741e651a20 | ||
|
|
4e1bd89378 | ||
|
|
c8f54b8be5 | ||
|
|
413d2f5178 | ||
|
|
503f44891f | ||
|
|
35c2a6a046 | ||
|
|
5bf326f680 | ||
|
|
1df201525c | ||
|
|
e7793b15e3 | ||
|
|
d2e16ca256 | ||
|
|
31164befc9 | ||
|
|
8f4dfa0674 | ||
|
|
eb7a01907a | ||
|
|
fb1fd1ec7c | ||
|
|
7528c7df63 | ||
|
|
e6ca19ab91 | ||
|
|
dc3e097dfd | ||
|
|
a5e8c06dda | ||
|
|
bf7fd13ef2 | ||
|
|
a424e015b4 | ||
|
|
c67fef64fe | ||
|
|
12055de1fc | ||
|
|
a2ad2f8c0b | ||
|
|
af7cebda66 | ||
|
|
2230cf2e7b | ||
|
|
aa048e8d22 | ||
|
|
4961fb9756 | ||
|
|
6801e3858a | ||
|
|
ef72dcf554 | ||
|
|
c228147c00 | ||
|
|
266358f0cc | ||
|
|
6717f0ee3d | ||
|
|
8880ed0df6 | ||
|
|
4b56b973c8 | ||
|
|
28a00b9f22 | ||
|
|
b1fe692de5 | ||
|
|
08b2f6cbc9 | ||
|
|
10e1db388f | ||
|
|
cd7f71b968 | ||
|
|
395fd544e5 | ||
|
|
2c10d6bf10 | ||
|
|
9361a631dd | ||
|
|
59c5abfd93 | ||
|
|
633c23a6f0 | ||
|
|
779e7323e2 | ||
|
|
6e7fbd940b | ||
|
|
6878b608fc | ||
|
|
a4fab8b64e | ||
|
|
21c0cc8794 | ||
|
|
7ea11ea0c4 | ||
|
|
d2c307b08a | ||
|
|
4dc98f7980 | ||
|
|
c89ee18db3 | ||
|
|
c4aa7999a6 | ||
|
|
778343f636 | ||
|
|
d2fb3b6c85 | ||
|
|
a8bfedcd5d | ||
|
|
4c7b5eec38 | ||
|
|
35068e23cd | ||
|
|
bc30b86cce | ||
|
|
461f166e33 | ||
|
|
628dbd5227 | ||
|
|
c05b290e49 | ||
|
|
696015b6a4 | ||
|
|
f2f70e1d83 | ||
|
|
b4d967f721 | ||
|
|
bf760677ef | ||
|
|
4d1dbaa2f3 | ||
|
|
595bb27d99 | ||
|
|
ad95faffa7 | ||
|
|
a0eb3c0459 | ||
|
|
fea435a6d2 | ||
|
|
7b72532c9e | ||
|
|
ea9920c4d5 | ||
|
|
6b756fe893 | ||
|
|
54c7f51766 | ||
|
|
94b787655e | ||
|
|
259d0f1648 | ||
|
|
872d3ff383 | ||
|
|
cf1c4d37b9 | ||
|
|
ada16bac6c | ||
|
|
d68055f8a9 | ||
|
|
8d98dcf7e7 | ||
|
|
c828a69f66 | ||
|
|
eefb6062c7 | ||
|
|
470a451168 | ||
|
|
e3b018c5f7 | ||
|
|
bd695e21d4 | ||
|
|
6311ebe467 | ||
|
|
f8a5ceed97 | ||
|
|
0420bda5da | ||
|
|
6dc532f40e | ||
|
|
0560d01f30 | ||
|
|
bc67ec3287 | ||
|
|
bed35a2377 | ||
|
|
aaf156cee3 | ||
|
|
e8020ffde6 | ||
|
|
8d6bd80902 | ||
|
|
8aa870dddd | ||
|
|
26a3c76d5f | ||
|
|
18f738f2c3 | ||
|
|
bba50ccbcc | ||
|
|
3eea3b913d | ||
|
|
2dbeec831e | ||
|
|
88a06628e3 | ||
|
|
37ceb30ffb | ||
|
|
ebd0515e96 | ||
|
|
ece5d0fa0d | ||
|
|
6be214c6cd | ||
|
|
c470453ea4 | ||
|
|
bbe9326954 | ||
|
|
27961bb4e5 | ||
|
|
4952c090ef | ||
|
|
74e4016625 | ||
|
|
c389008811 | ||
|
|
e6dcf22012 | ||
|
|
d067f925b9 | ||
|
|
8b5609f765 | ||
|
|
dd04a1f2af | ||
|
|
9caabb6cc0 | ||
|
|
33b28d5f41 | ||
|
|
475f9b5e34 | ||
|
|
60f1348ea5 | ||
|
|
533b6e1fcf | ||
|
|
8961730b74 | ||
|
|
5d580714c8 | ||
|
|
daf1ead75b | ||
|
|
aef2654a39 | ||
|
|
8243cd3528 | ||
|
|
447456d7a6 | ||
|
|
241a34d7a8 | ||
|
|
4e67b2e8b9 | ||
|
|
8bc2ea8373 | ||
|
|
00a6a113c8 | ||
|
|
dc04619128 | ||
|
|
e066da3762 | ||
|
|
ad96278956 | ||
|
|
83406277ad | ||
|
|
9e89348381 | ||
|
|
0fb7419598 | ||
|
|
1790298cb4 | ||
|
|
ffe8e39c85 | ||
|
|
67e0f4bd46 | ||
|
|
e7b3a58da3 | ||
|
|
598f9f3777 | ||
|
|
0a7dca2e12 | ||
|
|
4b342778df | ||
|
|
10e8fd904a | ||
|
|
1de342fd3b | ||
|
|
f4c1c3dd7f | ||
|
|
80bfc59356 | ||
|
|
3796f3ed5f | ||
|
|
f2e03d22d8 | ||
|
|
ef967b66e8 | ||
|
|
58ea70cc6c | ||
|
|
e4823950df | ||
|
|
8f9923ba5d | ||
|
|
72bbd2c36e | ||
|
|
9bdb902a56 | ||
|
|
bbc2e55ae3 | ||
|
|
6995bdb527 | ||
|
|
a7abc35316 | ||
|
|
772aed597b | ||
|
|
9e18825c27 | ||
|
|
27b7ffcf99 | ||
|
|
d804a744b6 | ||
|
|
fc5cf27bd1 | ||
|
|
355bba8966 | ||
|
|
e31c5f5a19 | ||
|
|
22837bbf8d | ||
|
|
6324486dca | ||
|
|
653100f539 | ||
|
|
d671ba583d | ||
|
|
fba324c6cb | ||
|
|
ccbec5bcff | ||
|
|
da1978bf21 | ||
|
|
1672b89775 | ||
|
|
d9a9db6ec8 | ||
|
|
0882bc2ca7 | ||
|
|
89b8d07bb4 | ||
|
|
c65c8edd2d | ||
|
|
5f7ce96919 | ||
|
|
d9a2601f75 | ||
|
|
37a04cadf8 | ||
|
|
ca10c01398 | ||
|
|
24f6ba117d | ||
|
|
7508144e27 | ||
|
|
9f0fec8046 | ||
|
|
67d70fac8e | ||
|
|
1775f6fd89 | ||
|
|
438c367101 | ||
|
|
cb9d8ffa91 | ||
|
|
2ecb0c5cf6 | ||
|
|
b01ce5b3b6 | ||
|
|
8a55d52b2b | ||
|
|
c7e6f00ddb | ||
|
|
85831ffe5d | ||
|
|
762a5a2072 | ||
|
|
405e1ed023 | ||
|
|
41177436d4 | ||
|
|
d1fca976a2 | ||
|
|
59cf407c26 | ||
|
|
e95828a514 | ||
|
|
8b915c7c83 | ||
|
|
ebc6a01b7a | ||
|
|
8cad3c4c14 | ||
|
|
a5537c21a1 | ||
|
|
edf96434b7 | ||
|
|
257df95c72 | ||
|
|
a268df503a | ||
|
|
a57ccbe4c2 | ||
|
|
7f37771dc7 | ||
|
|
3a753dde83 | ||
|
|
8e91b1363b | ||
|
|
e77929ab89 | ||
|
|
02031e97e3 | ||
|
|
ede1c505d4 | ||
|
|
5cd5b685d2 | ||
|
|
d856f1d1cc | ||
|
|
10bb912bda | ||
|
|
3b2135a570 | ||
|
|
9c5d209887 | ||
|
|
763a770bcf | ||
|
|
f8f3456ba3 | ||
|
|
4da7f02cf7 | ||
|
|
4772e24c78 | ||
|
|
c3a9b82abb | ||
|
|
4716940708 | ||
|
|
0eb09e2dbb | ||
|
|
111a33b12f | ||
|
|
bcff2272ab | ||
|
|
f30ae91854 | ||
|
|
7eaad843a9 | ||
|
|
cb367d32c3 | ||
|
|
b4cf88bd54 | ||
|
|
b8097fcd3a | ||
|
|
6db2238096 | ||
|
|
cd426d5534 | ||
|
|
c214d47aad | ||
|
|
c09c44ec5f | ||
|
|
f9f6d0d836 | ||
|
|
74a6c75c21 | ||
|
|
526ebc77bc | ||
|
|
addac44c0f | ||
|
|
303d575fde | ||
|
|
bf8438b229 | ||
|
|
ea8bbafbfa | ||
|
|
14815e79d5 | ||
|
|
4a3de35224 | ||
|
|
974f549c31 | ||
|
|
76596939c5 | ||
|
|
138974bca7 | ||
|
|
02aee02694 | ||
|
|
e2ada75611 | ||
|
|
78b757c55b | ||
|
|
dfd273e7bf | ||
|
|
1a72c23412 | ||
|
|
55a92ad029 | ||
|
|
aea6a0d131 | ||
|
|
e76e031675 | ||
|
|
ed095a95f0 | ||
|
|
3cdb3d6294 | ||
|
|
06fe8b3742 | ||
|
|
6ba7c54089 | ||
|
|
e2bc284091 | ||
|
|
66bf91e177 | ||
|
|
6039545f9d | ||
|
|
cc6f70e834 | ||
|
|
55d7687561 | ||
|
|
90866e2bea | ||
|
|
2059e4eba4 | ||
|
|
243a288061 | ||
|
|
623155be92 | ||
|
|
a404469085 | ||
|
|
b0e12b717b | ||
|
|
fdc1dadd36 | ||
|
|
872db4085c | ||
|
|
8af8cbacd3 | ||
|
|
01beef4312 | ||
|
|
a91ffd9ad7 | ||
|
|
dc42107668 | ||
|
|
670012676c | ||
|
|
8910ce47cd | ||
|
|
bc76ecba46 | ||
|
|
e50707e1dd | ||
|
|
a03c6fe0cb | ||
|
|
d5c17b08cc | ||
|
|
656bab3d48 | ||
|
|
cc6e01bd05 | ||
|
|
d4546a2865 | ||
|
|
7e0dd05f3d | ||
|
|
3bbefd3dfc | ||
|
|
fdca2ecfee | ||
|
|
ae08e46b30 | ||
|
|
bf18b83a75 | ||
|
|
393172ec9f | ||
|
|
781e9df148 | ||
|
|
2691a217db | ||
|
|
b421f74d1a | ||
|
|
e3bd33ffc3 | ||
|
|
38c2fd07ae | ||
|
|
77ebafd018 | ||
|
|
dfab7e3540 | ||
|
|
e4410fe2c7 | ||
|
|
1dbd3fd274 | ||
|
|
abdbab807d | ||
|
|
718077025d | ||
|
|
08161c29d3 | ||
|
|
942f84dfcf | ||
|
|
41defdc291 | ||
|
|
045b8e162a | ||
|
|
e3d7813edb |
7
.browserslistrc
Normal file
7
.browserslistrc
Normal file
@@ -0,0 +1,7 @@
|
||||
last 1 Chrome version
|
||||
last 1 Firefox version
|
||||
last 2 Edge major versions
|
||||
last 2 iOS major versions
|
||||
safari > 11
|
||||
Firefox ESR
|
||||
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -31,6 +31,7 @@ speed-measure-plugin.json
|
||||
.history/*
|
||||
|
||||
# misc
|
||||
/.angular/cache
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
|
||||
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
@@ -3,6 +3,5 @@
|
||||
"johnpapa.angular2",
|
||||
"esbenp.prettier-vscode",
|
||||
"angular.ng-template",
|
||||
"eg2.vscode-npm-script"
|
||||
]
|
||||
}
|
||||
35
.vscode/launch.json
vendored
35
.vscode/launch.json
vendored
@@ -1,22 +1,15 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.11.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "Launch Chrome",
|
||||
"url": "https://192.168.2.112:4200",
|
||||
"webRoot": "${workspaceFolder}",
|
||||
"sourceMaps": true,
|
||||
"sourceMapPathOverrides": {
|
||||
"/./*": "${webRoot}/*",
|
||||
"/src/*": "${webRoot}/*",
|
||||
"/*": "*",
|
||||
"/./~/*": "${webRoot}/node_modules/*"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "ISA-App Chrome",
|
||||
"url": "https://localhost:4200",
|
||||
"webRoot": "${workspaceFolder}",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#stage 1
|
||||
FROM node:14 as base
|
||||
FROM node:18 as base
|
||||
ARG IS_PRODUCTION=false
|
||||
ARG SEMVERSION=1.0.0
|
||||
ARG BuildUniqueID
|
||||
|
||||
3055
angular.json
3055
angular.json
File diff suppressed because it is too large
Load Diff
@@ -1,41 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true, // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/adapter/scan'),
|
||||
subdir: '.',
|
||||
reporters: [{ type: 'html' }, { type: 'text-summary' }],
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -1,22 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, isDevMode } from '@angular/core';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
import { PromptModalData, UiModalService, UiPromptModalComponent } from '@ui/modal';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ScanAdapter } from './scan-adapter';
|
||||
|
||||
@Injectable()
|
||||
export class DevScanAdapter implements ScanAdapter {
|
||||
constructor(private _modal: UiModalService) {}
|
||||
readonly name = 'Dev';
|
||||
|
||||
getName(): string {
|
||||
return 'Dev Scanner';
|
||||
}
|
||||
constructor(private _modal: UiModalService, private _environmentService: EnvironmentService) {}
|
||||
|
||||
isPrimary(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
isReady(): boolean {
|
||||
return true;
|
||||
async init(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(isDevMode());
|
||||
});
|
||||
}
|
||||
|
||||
scan(): Observable<string> {
|
||||
|
||||
5
apps/adapter/scan/src/lib/dummy.spec.ts
Normal file
5
apps/adapter/scan/src/lib/dummy.spec.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
describe('Dummy', () => {
|
||||
it('should work', () => {
|
||||
expect(true).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -6,20 +6,14 @@ import { ScanAdapter } from './scan-adapter';
|
||||
|
||||
@Injectable()
|
||||
export class NativeScanAdapter implements ScanAdapter {
|
||||
readonly name = 'Native';
|
||||
|
||||
constructor(private readonly nativeContainerService: NativeContainerService) {}
|
||||
|
||||
getName(): string {
|
||||
return 'Native Scanner';
|
||||
}
|
||||
|
||||
isPrimary(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
isReady(): boolean {
|
||||
// TODO: Fix Login Keycard Dauerschleife
|
||||
return this.nativeContainerService.isUiWebview().isNative || this.nativeContainerService.isIpadMini6();
|
||||
// return false;
|
||||
init(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(this.nativeContainerService.isNative);
|
||||
});
|
||||
}
|
||||
|
||||
scan(): Observable<string> {
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface ScanAdapter {
|
||||
getName(): string;
|
||||
/**
|
||||
* Name to identify the adapter
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
isPrimary(): boolean;
|
||||
|
||||
isReady(): boolean;
|
||||
/**
|
||||
* @returns true if this adapter can be used
|
||||
*/
|
||||
init(): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* scan for a barcode
|
||||
*/
|
||||
scan(): Observable<string>;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,13 @@ import { SCAN_ADAPTER } from './tokens';
|
||||
|
||||
@NgModule({})
|
||||
export class ScanAdapterModule {
|
||||
static forRoot(dev?: boolean) {
|
||||
static forRoot() {
|
||||
return {
|
||||
ngModule: ScanAdapterModule,
|
||||
providers: [{ provide: SCAN_ADAPTER, useClass: NativeScanAdapter, multi: true }],
|
||||
providers: [
|
||||
{ provide: SCAN_ADAPTER, useClass: NativeScanAdapter, multi: true },
|
||||
{ provide: SCAN_ADAPTER, useClass: DevScanAdapter, multi: true },
|
||||
],
|
||||
// Use for testing:
|
||||
// providers: [{ provide: SCAN_ADAPTER, useClass: dev ? DevScanAdapter : NativeScanAdapter, multi: true }],
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { ScanAdapter } from './scan-adapter';
|
||||
import { SCAN_ADAPTER } from './tokens';
|
||||
|
||||
@@ -6,25 +7,69 @@ import { SCAN_ADAPTER } from './tokens';
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ScanAdapterService {
|
||||
private _readyAdapters: Record<string, boolean> = {};
|
||||
|
||||
constructor(@Inject(SCAN_ADAPTER) private readonly scanAdapters: ScanAdapter[]) {}
|
||||
|
||||
scanners() {
|
||||
return this.scanAdapters.filter((adapter) => adapter.isReady());
|
||||
}
|
||||
|
||||
scanner() {
|
||||
return this.scanners().find((scanner) => scanner.isPrimary()) || this.scanners().find(() => true);
|
||||
}
|
||||
|
||||
isReady() {
|
||||
return this.scanAdapters.some((adapter) => adapter.isReady());
|
||||
}
|
||||
|
||||
scan() {
|
||||
const primaryScanner = this.scanner();
|
||||
if (primaryScanner) {
|
||||
return primaryScanner.scan();
|
||||
async init(): Promise<void> {
|
||||
for (const adapter of this.scanAdapters) {
|
||||
const isReady = await adapter.init();
|
||||
console.log('ScanAdapterService.init', adapter.name, isReady);
|
||||
this._readyAdapters[adapter.name] = isReady;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
adapters(): ScanAdapter[] {
|
||||
return [...this.scanAdapters];
|
||||
}
|
||||
|
||||
getAdapter(name: string): ScanAdapter | undefined {
|
||||
return this.scanAdapters.find((adapter) => adapter.name === name);
|
||||
}
|
||||
|
||||
// return true if at least one adapter is ready
|
||||
isReady(): boolean {
|
||||
return Object.values(this._readyAdapters).some((ready) => ready);
|
||||
}
|
||||
|
||||
scan(ops: { use?: string; include?: string[]; exclude?: string[] } = {}): Observable<string> {
|
||||
let adapter: ScanAdapter;
|
||||
|
||||
if (ops.use == undefined) {
|
||||
const adapterOrder = ['Native', 'Scandit', 'Dev'];
|
||||
|
||||
for (const name of adapterOrder) {
|
||||
adapter = this.getAdapter(name);
|
||||
|
||||
if (adapter) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// get the first adapter that is ready to use
|
||||
// adapter = this.scanAdapters
|
||||
// .filter((adapter) => {
|
||||
// if (ops.include?.length) {
|
||||
// return ops.include.includes(adapter.name);
|
||||
// } else if (ops.exclude?.length) {
|
||||
// return !ops.exclude.includes(adapter.name);
|
||||
// } else {
|
||||
// return true;
|
||||
// }
|
||||
// })
|
||||
// .find((adapter) => this._readyAdapters[adapter.name]);
|
||||
} else {
|
||||
adapter = this.getAdapter(ops.use);
|
||||
}
|
||||
|
||||
if (!adapter) {
|
||||
return throwError('No adapter found');
|
||||
}
|
||||
|
||||
if (this._readyAdapters[adapter.name] == false) {
|
||||
return throwError('Adapter is not ready');
|
||||
}
|
||||
|
||||
return adapter.scan();
|
||||
}
|
||||
}
|
||||
|
||||
3
apps/adapter/scan/src/lib/scandit/index.ts
Normal file
3
apps/adapter/scan/src/lib/scandit/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './scandit-overlay.component';
|
||||
export * from './scandit-scan-adapter.module';
|
||||
export * from './scandit.scan-adapter';
|
||||
@@ -0,0 +1,20 @@
|
||||
:host {
|
||||
@apply block relative;
|
||||
}
|
||||
|
||||
.scanner-container {
|
||||
width: 100vw;
|
||||
max-width: 95vw;
|
||||
max-height: calc(95vh - 120px);
|
||||
}
|
||||
|
||||
.close-scanner {
|
||||
@apply block px-6 py-4 bg-white text-brand border-2 border-solid border-brand rounded-full text-lg font-bold mx-auto mt-4;
|
||||
}
|
||||
|
||||
@screen desktop {
|
||||
.scanner-container {
|
||||
max-width: 900px;
|
||||
max-height: 900px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<div class="scanner-container" #scanContainer></div>
|
||||
<button class="close-scanner" type="button" (click)="close()">
|
||||
Scan abbrechen
|
||||
</button>
|
||||
100
apps/adapter/scan/src/lib/scandit/scandit-overlay.component.ts
Normal file
100
apps/adapter/scan/src/lib/scandit/scandit-overlay.component.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { Component, ChangeDetectionStrategy, ElementRef, ViewChild, NgZone, AfterViewInit, OnDestroy } from '@angular/core';
|
||||
import { UiMessageModalComponent, UiModalService } from '@ui/modal';
|
||||
import { Barcode, BarcodePicker, ScanResult, ScanSettings } from 'scandit-sdk';
|
||||
|
||||
@Component({
|
||||
selector: 'app-scandit-overlay',
|
||||
templateUrl: 'scandit-overlay.component.html',
|
||||
styleUrls: ['scandit-overlay.component.css'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ScanditOverlayComponent implements AfterViewInit, OnDestroy {
|
||||
private _barcodePicker: BarcodePicker;
|
||||
|
||||
private _onScan?: (code: string) => void;
|
||||
|
||||
private _onClose?: () => void;
|
||||
|
||||
@ViewChild('scanContainer', { read: ElementRef, static: true }) scanContainer: ElementRef;
|
||||
|
||||
constructor(private _zone: NgZone, private _modal: UiModalService) {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.createBarcodePicker()
|
||||
.then(() => {
|
||||
this._barcodePicker.on('scan', (scanResult) => {
|
||||
this._zone.run(() => this.handleScanrResult(scanResult));
|
||||
});
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
this._modal
|
||||
.open({
|
||||
content: UiMessageModalComponent,
|
||||
title: 'Zugriff auf Kamera verweigert',
|
||||
data: { message: 'Falls Sie den Zugriff erlauben möchten, können Sie das über die Webseiteinstellung Ihres Browsers.' },
|
||||
})
|
||||
.afterClosed$.subscribe(() => {
|
||||
this._onClose?.();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async createBarcodePicker() {
|
||||
this._barcodePicker = await BarcodePicker.create(this.scanContainer.nativeElement, {
|
||||
playSoundOnScan: true,
|
||||
vibrateOnScan: true,
|
||||
});
|
||||
|
||||
this._barcodePicker.applyScanSettings(this.getScanSettings());
|
||||
}
|
||||
|
||||
getScanSettings(): ScanSettings {
|
||||
return new ScanSettings({
|
||||
blurryRecognition: false,
|
||||
|
||||
enabledSymbologies: [
|
||||
Barcode.Symbology.EAN8,
|
||||
Barcode.Symbology.EAN13,
|
||||
Barcode.Symbology.UPCA,
|
||||
Barcode.Symbology.UPCE,
|
||||
Barcode.Symbology.CODE128,
|
||||
Barcode.Symbology.CODE39,
|
||||
Barcode.Symbology.CODE93,
|
||||
Barcode.Symbology.INTERLEAVED_2_OF_5,
|
||||
Barcode.Symbology.QR,
|
||||
],
|
||||
codeDuplicateFilter: 1000,
|
||||
});
|
||||
}
|
||||
|
||||
onScan(fn: (code: string) => void) {
|
||||
this._onScan = fn;
|
||||
}
|
||||
|
||||
onClose(fn: () => void) {
|
||||
this._onClose = fn;
|
||||
}
|
||||
|
||||
handleScanrResult(scanRestul: ScanResult) {
|
||||
let result: string | undefined;
|
||||
if (scanRestul.barcodes.length) {
|
||||
result = scanRestul.barcodes[0].data;
|
||||
} else if (scanRestul.texts.length) {
|
||||
result = scanRestul.texts[0].value;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
this._onScan?.(result);
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this._onClose?.();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._zone.runOutsideAngular(() => {
|
||||
this._barcodePicker?.destroy(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { ScanditOverlayComponent } from './scandit-overlay.component';
|
||||
import { ScanditScanAdapter } from './scandit.scan-adapter';
|
||||
import { SCAN_ADAPTER } from '../tokens';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
exports: [ScanditOverlayComponent],
|
||||
declarations: [ScanditOverlayComponent],
|
||||
})
|
||||
export class ScanditScanAdapterModule {
|
||||
static forRoot() {
|
||||
return {
|
||||
ngModule: ScanditScanAdapterModule,
|
||||
providers: [{ provide: SCAN_ADAPTER, useClass: ScanditScanAdapter, multi: true }],
|
||||
};
|
||||
}
|
||||
}
|
||||
82
apps/adapter/scan/src/lib/scandit/scandit.scan-adapter.ts
Normal file
82
apps/adapter/scan/src/lib/scandit/scandit.scan-adapter.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, Subscriber } from 'rxjs';
|
||||
import { ScanAdapter } from '../scan-adapter';
|
||||
import { Overlay } from '@angular/cdk/overlay';
|
||||
|
||||
import { configure } from 'scandit-sdk';
|
||||
// import { ScanditModalComponent } from './scandit-modal';
|
||||
import { Config } from '@core/config';
|
||||
import { ComponentPortal } from '@angular/cdk/portal';
|
||||
import { ScanditOverlayComponent } from './scandit-overlay.component';
|
||||
import { EnvironmentService } from '@core/environment';
|
||||
|
||||
@Injectable()
|
||||
export class ScanditScanAdapter implements ScanAdapter {
|
||||
readonly name = 'Scandit';
|
||||
|
||||
constructor(private readonly _config: Config, private _overlay: Overlay, private _environmentService: EnvironmentService) {}
|
||||
|
||||
async init(): Promise<boolean> {
|
||||
if (this._environmentService.isTablet()) {
|
||||
await configure(this._config.get('licence.scandit'), {
|
||||
engineLocation: '/scandit/',
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
scan(): Observable<string> {
|
||||
return new Observable((observer) => {
|
||||
const overlay = this.createOverlay();
|
||||
|
||||
const portal = this.createPortal();
|
||||
|
||||
const ref = overlay.attach(portal);
|
||||
|
||||
const sub = new Subscriber();
|
||||
|
||||
const complete = () => {
|
||||
overlay.detach();
|
||||
ref.destroy();
|
||||
sub.unsubscribe();
|
||||
sub.complete();
|
||||
observer.complete();
|
||||
};
|
||||
|
||||
sub.add(
|
||||
overlay.backdropClick().subscribe(() => {
|
||||
complete();
|
||||
})
|
||||
);
|
||||
|
||||
ref.instance.onScan((code) => {
|
||||
observer.next(code);
|
||||
complete();
|
||||
});
|
||||
|
||||
ref.instance.onClose(() => {
|
||||
complete();
|
||||
});
|
||||
|
||||
return complete;
|
||||
});
|
||||
}
|
||||
|
||||
createOverlay() {
|
||||
const overlay = this._overlay.create({
|
||||
positionStrategy: this._overlay.position().global().centerHorizontally().centerVertically(),
|
||||
hasBackdrop: true,
|
||||
});
|
||||
|
||||
return overlay;
|
||||
}
|
||||
|
||||
createPortal() {
|
||||
const portal = new ComponentPortal(ScanditOverlayComponent);
|
||||
|
||||
return portal;
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,10 @@
|
||||
* Public API Surface of scan
|
||||
*/
|
||||
|
||||
export * from './lib/scan.service';
|
||||
export * from './lib/scandit';
|
||||
export * from './lib/dev.scan-adapter';
|
||||
export * from './lib/native.scan-adapter';
|
||||
export * from './lib/scan-adapter';
|
||||
export * from './lib/scan.module';
|
||||
export * from './lib/scan.service';
|
||||
export * from './lib/tokens';
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { teardown: { destroyAfterEach: true } });
|
||||
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -3,7 +3,6 @@
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
|
||||
@@ -7,11 +7,8 @@
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/cdn/product-image'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -2,8 +2,8 @@ import { NgModule } from '@angular/core';
|
||||
import { ProductImagePipe } from './product-image.pipe';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProductImagePipe],
|
||||
imports: [],
|
||||
declarations: [],
|
||||
imports: [ProductImagePipe],
|
||||
exports: [ProductImagePipe],
|
||||
})
|
||||
export class ProductImageModule {}
|
||||
|
||||
@@ -3,6 +3,8 @@ import { ProductImageService } from './product-image.service';
|
||||
|
||||
@Pipe({
|
||||
name: 'productImage',
|
||||
standalone: true,
|
||||
pure: true,
|
||||
})
|
||||
export class ProductImagePipe implements PipeTransform {
|
||||
constructor(private imageService: ProductImageService) {}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { Config } from '@core/config';
|
||||
import { createServiceFactory, SpectatorService } from '@ngneat/spectator';
|
||||
|
||||
import { ProductImageService } from './product-image.service';
|
||||
|
||||
describe('ProductImageService', () => {
|
||||
let service: ProductImageService;
|
||||
let spectator: SpectatorService<ProductImageService>;
|
||||
const createService = createServiceFactory({
|
||||
service: ProductImageService,
|
||||
mocks: [Config],
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(ProductImageService);
|
||||
spectator = createService();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
expect(spectator.service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -3,7 +3,6 @@
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
"compilationMode": "partial"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,8 @@
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,24 @@
|
||||
# Auth
|
||||
# Core
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.0.
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.0.0.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project auth` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project auth`.
|
||||
Run `ng generate component component-name --project core` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project core`.
|
||||
|
||||
> Note: Don't forget to add `--project auth` or else it will be added to the default project in your `angular.json` file.
|
||||
> Note: Don't forget to add `--project core` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build auth` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
Run `ng build core` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build auth`, go to the dist folder `cd dist/auth` and run `npm publish`.
|
||||
After building your library with `ng build core`, go to the dist folder `cd dist/core` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test auth` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
Run `ng test core` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# Application
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project application` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project application`.
|
||||
|
||||
> Note: Don't forget to add `--project application` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build application` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build application`, go to the dist folder `cd dist/application` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test application` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
@@ -1,43 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
const customLaunchers = require('../../../karma/custom-launchers');
|
||||
const junitReporter = require('../../../karma/junit-reporter')('core-application');
|
||||
const coverageReporter = require('../../../karma/coverage-reporter')('core-application');
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('karma-junit-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true, // removes the duplicated traces
|
||||
},
|
||||
coverageReporter,
|
||||
junitReporter,
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
customLaunchers,
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "@core/application",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^10.1.2",
|
||||
"@angular/core": "^10.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,233 +1,233 @@
|
||||
import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { ApplicationProcess } from './defs';
|
||||
// import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator';
|
||||
// import { Store } from '@ngrx/store';
|
||||
// import { Observable, of } from 'rxjs';
|
||||
// import { first } from 'rxjs/operators';
|
||||
// import { ApplicationProcess } from './defs';
|
||||
|
||||
import { ApplicationService } from './application.service';
|
||||
import * as actions from './store/application.actions';
|
||||
// import { ApplicationService } from './application.service';
|
||||
// import * as actions from './store/application.actions';
|
||||
|
||||
describe('ApplicationService', () => {
|
||||
let spectator: SpectatorService<ApplicationService>;
|
||||
let store: SpyObject<Store>;
|
||||
const createService = createServiceFactory({
|
||||
service: ApplicationService,
|
||||
mocks: [Store],
|
||||
});
|
||||
// describe('ApplicationService', () => {
|
||||
// let spectator: SpectatorService<ApplicationService>;
|
||||
// let store: SpyObject<Store>;
|
||||
// const createService = createServiceFactory({
|
||||
// service: ApplicationService,
|
||||
// mocks: [Store],
|
||||
// });
|
||||
|
||||
beforeEach(() => {
|
||||
spectator = createService({});
|
||||
store = spectator.inject(Store);
|
||||
});
|
||||
// beforeEach(() => {
|
||||
// spectator = createService({});
|
||||
// store = spectator.inject(Store);
|
||||
// });
|
||||
|
||||
it('should be created', () => {
|
||||
expect(spectator.service).toBeTruthy();
|
||||
});
|
||||
// it('should be created', () => {
|
||||
// expect(spectator.service).toBeTruthy();
|
||||
// });
|
||||
|
||||
describe('activatedProcessId$', () => {
|
||||
it('should return an observable', () => {
|
||||
expect(spectator.service.activatedProcessId$).toBeInstanceOf(Observable);
|
||||
});
|
||||
});
|
||||
// describe('activatedProcessId$', () => {
|
||||
// it('should return an observable', () => {
|
||||
// expect(spectator.service.activatedProcessId$).toBeInstanceOf(Observable);
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('activatedProcessId', () => {
|
||||
it('should return the process id as a number', () => {
|
||||
spyOnProperty(spectator.service['activatedProcessIdSubject'] as any, 'value').and.returnValue(2);
|
||||
expect(spectator.service.activatedProcessId).toBe(2);
|
||||
});
|
||||
});
|
||||
// describe('activatedProcessId', () => {
|
||||
// it('should return the process id as a number', () => {
|
||||
// spyOnProperty(spectator.service['activatedProcessIdSubject'] as any, 'value').and.returnValue(2);
|
||||
// expect(spectator.service.activatedProcessId).toBe(2);
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('getProcesses$()', () => {
|
||||
it('should call select on store and return all selected processes', async () => {
|
||||
const processes: ApplicationProcess[] = [
|
||||
{ id: 1, name: 'Vorgang', type: 'cart', section: 'customer', data: { count: 1 } },
|
||||
{ id: 2, name: 'Vorgang', type: 'task-calendar', section: 'branch' },
|
||||
];
|
||||
store.select.and.returnValue(of(processes));
|
||||
const result = await spectator.service.getProcesses$().pipe(first()).toPromise();
|
||||
expect(result).toEqual(processes);
|
||||
expect(store.select).toHaveBeenCalled();
|
||||
});
|
||||
// describe('getProcesses$()', () => {
|
||||
// it('should call select on store and return all selected processes', async () => {
|
||||
// const processes: ApplicationProcess[] = [
|
||||
// { id: 1, name: 'Vorgang', type: 'cart', section: 'customer', data: { count: 1 } },
|
||||
// { id: 2, name: 'Vorgang', type: 'task-calendar', section: 'branch' },
|
||||
// ];
|
||||
// store.select.and.returnValue(of(processes));
|
||||
// const result = await spectator.service.getProcesses$().pipe(first()).toPromise();
|
||||
// expect(result).toEqual(processes);
|
||||
// expect(store.select).toHaveBeenCalled();
|
||||
// });
|
||||
|
||||
it('should call select on store and return all section customer processes', async () => {
|
||||
const processes: ApplicationProcess[] = [
|
||||
{ id: 1, name: 'Vorgang', type: 'cart', section: 'customer', data: { count: 1 } },
|
||||
{ id: 2, name: 'Vorgang', type: 'task-calendar', section: 'branch' },
|
||||
];
|
||||
store.select.and.returnValue(of(processes));
|
||||
const result = await spectator.service.getProcesses$('customer').pipe(first()).toPromise();
|
||||
expect(result).toEqual([processes[0]]);
|
||||
expect(store.select).toHaveBeenCalled();
|
||||
});
|
||||
// it('should call select on store and return all section customer processes', async () => {
|
||||
// const processes: ApplicationProcess[] = [
|
||||
// { id: 1, name: 'Vorgang', type: 'cart', section: 'customer', data: { count: 1 } },
|
||||
// { id: 2, name: 'Vorgang', type: 'task-calendar', section: 'branch' },
|
||||
// ];
|
||||
// store.select.and.returnValue(of(processes));
|
||||
// const result = await spectator.service.getProcesses$('customer').pipe(first()).toPromise();
|
||||
// expect(result).toEqual([processes[0]]);
|
||||
// expect(store.select).toHaveBeenCalled();
|
||||
// });
|
||||
|
||||
it('should call select on store and return all section branch processes', async () => {
|
||||
const processes: ApplicationProcess[] = [
|
||||
{ id: 1, name: 'Vorgang', type: 'cart', section: 'customer', data: { count: 1 } },
|
||||
{ id: 2, name: 'Vorgang', type: 'task-calendar', section: 'branch' },
|
||||
];
|
||||
store.select.and.returnValue(of(processes));
|
||||
const result = await spectator.service.getProcesses$('branch').pipe(first()).toPromise();
|
||||
expect(result).toEqual([processes[1]]);
|
||||
expect(store.select).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
// it('should call select on store and return all section branch processes', async () => {
|
||||
// const processes: ApplicationProcess[] = [
|
||||
// { id: 1, name: 'Vorgang', type: 'cart', section: 'customer', data: { count: 1 } },
|
||||
// { id: 2, name: 'Vorgang', type: 'task-calendar', section: 'branch' },
|
||||
// ];
|
||||
// store.select.and.returnValue(of(processes));
|
||||
// const result = await spectator.service.getProcesses$('branch').pipe(first()).toPromise();
|
||||
// expect(result).toEqual([processes[1]]);
|
||||
// expect(store.select).toHaveBeenCalled();
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('getProcessById$()', () => {
|
||||
it('should return the process by id', async () => {
|
||||
const processes: ApplicationProcess[] = [
|
||||
{ id: 1, name: 'Vorgang 1', section: 'customer' },
|
||||
{ id: 2, name: 'Vorgang 2', section: 'customer' },
|
||||
];
|
||||
spyOn(spectator.service, 'getProcesses$').and.returnValue(of(processes));
|
||||
// describe('getProcessById$()', () => {
|
||||
// it('should return the process by id', async () => {
|
||||
// const processes: ApplicationProcess[] = [
|
||||
// { id: 1, name: 'Vorgang 1', section: 'customer' },
|
||||
// { id: 2, name: 'Vorgang 2', section: 'customer' },
|
||||
// ];
|
||||
// spyOn(spectator.service, 'getProcesses$').and.returnValue(of(processes));
|
||||
|
||||
const process = await spectator.service.getProcessById$(1).toPromise();
|
||||
expect(process.id).toBe(1);
|
||||
});
|
||||
});
|
||||
// const process = await spectator.service.getProcessById$(1).toPromise();
|
||||
// expect(process.id).toBe(1);
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('getSection$()', () => {
|
||||
it('should return the selected section branch', async () => {
|
||||
const section = 'branch';
|
||||
store.select.and.returnValue(of(section));
|
||||
const result = await spectator.service.getSection$().pipe(first()).toPromise();
|
||||
expect(result).toEqual(section);
|
||||
expect(store.select).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
// describe('getSection$()', () => {
|
||||
// it('should return the selected section branch', async () => {
|
||||
// const section = 'branch';
|
||||
// store.select.and.returnValue(of(section));
|
||||
// const result = await spectator.service.getSection$().pipe(first()).toPromise();
|
||||
// expect(result).toEqual(section);
|
||||
// expect(store.select).toHaveBeenCalled();
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('getActivatedProcessId$', () => {
|
||||
it('should return the current selected activated process id', async () => {
|
||||
const activatedProcessId = 2;
|
||||
store.select.and.returnValue(of({ id: activatedProcessId }));
|
||||
const result = await spectator.service.getActivatedProcessId$().pipe(first()).toPromise();
|
||||
expect(result).toEqual(activatedProcessId);
|
||||
expect(store.select).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
// describe('getActivatedProcessId$', () => {
|
||||
// it('should return the current selected activated process id', async () => {
|
||||
// const activatedProcessId = 2;
|
||||
// store.select.and.returnValue(of({ id: activatedProcessId }));
|
||||
// const result = await spectator.service.getActivatedProcessId$().pipe(first()).toPromise();
|
||||
// expect(result).toEqual(activatedProcessId);
|
||||
// expect(store.select).toHaveBeenCalled();
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('activateProcess()', () => {
|
||||
it('should dispatch action setActivatedProcess with argument activatedProcessId and action type', () => {
|
||||
const activatedProcessId = 2;
|
||||
spectator.service.activateProcess(activatedProcessId);
|
||||
expect(store.dispatch).toHaveBeenCalledWith({ activatedProcessId, type: actions.setActivatedProcess.type });
|
||||
});
|
||||
});
|
||||
// describe('activateProcess()', () => {
|
||||
// it('should dispatch action setActivatedProcess with argument activatedProcessId and action type', () => {
|
||||
// const activatedProcessId = 2;
|
||||
// spectator.service.activateProcess(activatedProcessId);
|
||||
// expect(store.dispatch).toHaveBeenCalledWith({ activatedProcessId, type: actions.setActivatedProcess.type });
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('removeProcess()', () => {
|
||||
it('should dispatch action removeProcess with argument processId and action type', () => {
|
||||
const processId = 2;
|
||||
spectator.service.removeProcess(processId);
|
||||
expect(store.dispatch).toHaveBeenCalledWith({ processId, type: actions.removeProcess.type });
|
||||
});
|
||||
});
|
||||
// describe('removeProcess()', () => {
|
||||
// it('should dispatch action removeProcess with argument processId and action type', () => {
|
||||
// const processId = 2;
|
||||
// spectator.service.removeProcess(processId);
|
||||
// expect(store.dispatch).toHaveBeenCalledWith({ processId, type: actions.removeProcess.type });
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('createProcess()', () => {
|
||||
it('should dispatch action addProcess with process', async () => {
|
||||
const process: ApplicationProcess = {
|
||||
id: 1,
|
||||
name: 'Vorgang 1',
|
||||
section: 'customer',
|
||||
type: 'cart',
|
||||
};
|
||||
// describe('createProcess()', () => {
|
||||
// it('should dispatch action addProcess with process', async () => {
|
||||
// const process: ApplicationProcess = {
|
||||
// id: 1,
|
||||
// name: 'Vorgang 1',
|
||||
// section: 'customer',
|
||||
// type: 'cart',
|
||||
// };
|
||||
|
||||
const timestamp = 100;
|
||||
spyOn(spectator.service as any, '_createTimestamp').and.returnValue(timestamp);
|
||||
spyOn(spectator.service, 'getProcessById$').and.returnValue(of(undefined));
|
||||
await spectator.service.createProcess(process);
|
||||
// const timestamp = 100;
|
||||
// spyOn(spectator.service as any, '_createTimestamp').and.returnValue(timestamp);
|
||||
// spyOn(spectator.service, 'getProcessById$').and.returnValue(of(undefined));
|
||||
// await spectator.service.createProcess(process);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith({
|
||||
type: actions.addProcess.type,
|
||||
process: {
|
||||
...process,
|
||||
activated: 0,
|
||||
created: timestamp,
|
||||
},
|
||||
});
|
||||
});
|
||||
// expect(store.dispatch).toHaveBeenCalledWith({
|
||||
// type: actions.addProcess.type,
|
||||
// process: {
|
||||
// ...process,
|
||||
// activated: 0,
|
||||
// created: timestamp,
|
||||
// },
|
||||
// });
|
||||
// });
|
||||
|
||||
it('should throw an error if the process id is already existing', async () => {
|
||||
const process: ApplicationProcess = {
|
||||
id: 1,
|
||||
name: 'Vorgang 1',
|
||||
section: 'customer',
|
||||
type: 'cart',
|
||||
};
|
||||
spyOn(spectator.service, 'getProcessById$').and.returnValue(of(process));
|
||||
await expectAsync(spectator.service.createProcess(process)).toBeRejectedWithError('Process Id existiert bereits');
|
||||
});
|
||||
// it('should throw an error if the process id is already existing', async () => {
|
||||
// const process: ApplicationProcess = {
|
||||
// id: 1,
|
||||
// name: 'Vorgang 1',
|
||||
// section: 'customer',
|
||||
// type: 'cart',
|
||||
// };
|
||||
// spyOn(spectator.service, 'getProcessById$').and.returnValue(of(process));
|
||||
// await expectAsync(spectator.service.createProcess(process)).toBeRejectedWithError('Process Id existiert bereits');
|
||||
// });
|
||||
|
||||
it('should throw an error if the process id is not a number', async () => {
|
||||
const process: ApplicationProcess = {
|
||||
id: undefined,
|
||||
name: 'Vorgang 1',
|
||||
section: 'customer',
|
||||
type: 'cart',
|
||||
};
|
||||
spyOn(spectator.service, 'getProcessById$').and.returnValue(of({ id: 5, name: 'Vorgang 2', section: 'customer' }));
|
||||
await expectAsync(spectator.service.createProcess(process)).toBeRejectedWithError('Process Id nicht gesetzt');
|
||||
});
|
||||
});
|
||||
// it('should throw an error if the process id is not a number', async () => {
|
||||
// const process: ApplicationProcess = {
|
||||
// id: undefined,
|
||||
// name: 'Vorgang 1',
|
||||
// section: 'customer',
|
||||
// type: 'cart',
|
||||
// };
|
||||
// spyOn(spectator.service, 'getProcessById$').and.returnValue(of({ id: 5, name: 'Vorgang 2', section: 'customer' }));
|
||||
// await expectAsync(spectator.service.createProcess(process)).toBeRejectedWithError('Process Id nicht gesetzt');
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('patchProcess', () => {
|
||||
it('should dispatch action patchProcess with changes', async () => {
|
||||
const process: ApplicationProcess = {
|
||||
id: 1,
|
||||
name: 'Vorgang 1',
|
||||
section: 'customer',
|
||||
type: 'cart',
|
||||
};
|
||||
// describe('patchProcess', () => {
|
||||
// it('should dispatch action patchProcess with changes', async () => {
|
||||
// const process: ApplicationProcess = {
|
||||
// id: 1,
|
||||
// name: 'Vorgang 1',
|
||||
// section: 'customer',
|
||||
// type: 'cart',
|
||||
// };
|
||||
|
||||
await spectator.service.patchProcess(process.id, process);
|
||||
// await spectator.service.patchProcess(process.id, process);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith({
|
||||
type: actions.patchProcess.type,
|
||||
processId: process.id,
|
||||
changes: {
|
||||
...process,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
// expect(store.dispatch).toHaveBeenCalledWith({
|
||||
// type: actions.patchProcess.type,
|
||||
// processId: process.id,
|
||||
// changes: {
|
||||
// ...process,
|
||||
// },
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('setSection()', () => {
|
||||
it('should dispatch action setSection with argument section and action type', () => {
|
||||
const section = 'customer';
|
||||
spectator.service.setSection(section);
|
||||
expect(store.dispatch).toHaveBeenCalledWith({ section, type: actions.setSection.type });
|
||||
});
|
||||
});
|
||||
// describe('setSection()', () => {
|
||||
// it('should dispatch action setSection with argument section and action type', () => {
|
||||
// const section = 'customer';
|
||||
// spectator.service.setSection(section);
|
||||
// expect(store.dispatch).toHaveBeenCalledWith({ section, type: actions.setSection.type });
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('getLastActivatedProcessWithSectionAndType()', () => {
|
||||
it('should return the last activated process by section and type', async () => {
|
||||
const processes: ApplicationProcess[] = [
|
||||
{ id: 1, name: 'Vorgang 1', section: 'customer', type: 'cart', activated: 100 },
|
||||
{ id: 2, name: 'Vorgang 2', section: 'customer', type: 'cart', activated: 200 },
|
||||
{ id: 3, name: 'Vorgang 3', section: 'customer', type: 'goodsOut', activated: 300 },
|
||||
];
|
||||
spyOn(spectator.service, 'getProcesses$').and.returnValue(of(processes));
|
||||
// describe('getLastActivatedProcessWithSectionAndType()', () => {
|
||||
// it('should return the last activated process by section and type', async () => {
|
||||
// const processes: ApplicationProcess[] = [
|
||||
// { id: 1, name: 'Vorgang 1', section: 'customer', type: 'cart', activated: 100 },
|
||||
// { id: 2, name: 'Vorgang 2', section: 'customer', type: 'cart', activated: 200 },
|
||||
// { id: 3, name: 'Vorgang 3', section: 'customer', type: 'goodsOut', activated: 300 },
|
||||
// ];
|
||||
// spyOn(spectator.service, 'getProcesses$').and.returnValue(of(processes));
|
||||
|
||||
expect(await spectator.service.getLastActivatedProcessWithSectionAndType$('customer', 'cart').pipe(first()).toPromise()).toBe(
|
||||
processes[1]
|
||||
);
|
||||
});
|
||||
});
|
||||
// expect(await spectator.service.getLastActivatedProcessWithSectionAndType$('customer', 'cart').pipe(first()).toPromise()).toBe(
|
||||
// processes[1]
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('getLastActivatedProcessWithSection()', () => {
|
||||
it('should return the last activated process by section', async () => {
|
||||
const processes: ApplicationProcess[] = [
|
||||
{ id: 1, name: 'Vorgang 1', section: 'customer', activated: 100 },
|
||||
{ id: 2, name: 'Vorgang 2', section: 'customer', activated: 200 },
|
||||
{ id: 3, name: 'Vorgang 3', section: 'customer', activated: 300 },
|
||||
];
|
||||
spyOn(spectator.service, 'getProcesses$').and.returnValue(of(processes));
|
||||
// describe('getLastActivatedProcessWithSection()', () => {
|
||||
// it('should return the last activated process by section', async () => {
|
||||
// const processes: ApplicationProcess[] = [
|
||||
// { id: 1, name: 'Vorgang 1', section: 'customer', activated: 100 },
|
||||
// { id: 2, name: 'Vorgang 2', section: 'customer', activated: 200 },
|
||||
// { id: 3, name: 'Vorgang 3', section: 'customer', activated: 300 },
|
||||
// ];
|
||||
// spyOn(spectator.service, 'getProcesses$').and.returnValue(of(processes));
|
||||
|
||||
expect(await spectator.service.getLastActivatedProcessWithSection$('customer').pipe(first()).toPromise()).toBe(processes[2]);
|
||||
});
|
||||
});
|
||||
// expect(await spectator.service.getLastActivatedProcessWithSection$('customer').pipe(first()).toPromise()).toBe(processes[2]);
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('_createTimestamp', () => {
|
||||
it('should return the current timestamp in ms', () => {
|
||||
expect(spectator.service['_createTimestamp']()).toBeCloseTo(Date.now());
|
||||
});
|
||||
});
|
||||
});
|
||||
// describe('_createTimestamp', () => {
|
||||
// it('should return the current timestamp in ms', () => {
|
||||
// expect(spectator.service['_createTimestamp']()).toBeCloseTo(Date.now());
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { BranchDTO } from '@swagger/checkout';
|
||||
import { isBoolean, isNumber } from '@utils/common';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { first, map, switchMap } from 'rxjs/operators';
|
||||
@@ -14,19 +15,18 @@ import {
|
||||
selectActivatedProcess,
|
||||
patchProcess,
|
||||
patchProcessData,
|
||||
selectTitle,
|
||||
setTitle,
|
||||
} from './store';
|
||||
|
||||
@Injectable()
|
||||
export class ApplicationService {
|
||||
/** @deprecated */
|
||||
private activatedProcessIdSubject = new BehaviorSubject<number>(undefined);
|
||||
|
||||
/** @deprecated */
|
||||
get activatedProcessId() {
|
||||
return this.activatedProcessIdSubject.value;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
get activatedProcessId$() {
|
||||
return this.activatedProcessIdSubject.asObservable();
|
||||
}
|
||||
@@ -46,6 +46,14 @@ export class ApplicationService {
|
||||
return this.store.select(selectSection);
|
||||
}
|
||||
|
||||
getTitle$() {
|
||||
return this.getSection$().pipe(
|
||||
map((section) => {
|
||||
return section === 'customer' ? 'Kundenbereich' : 'Filialbereich';
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
getActivatedProcessId$() {
|
||||
return this.store.select(selectActivatedProcess).pipe(map((process) => process?.id));
|
||||
@@ -68,6 +76,16 @@ export class ApplicationService {
|
||||
this.store.dispatch(patchProcessData({ processId, data }));
|
||||
}
|
||||
|
||||
getSelectedBranch$(processId?: number): Observable<BranchDTO> {
|
||||
if (!processId) {
|
||||
return this.activatedProcessId$.pipe(
|
||||
switchMap((processId) => this.getProcessById$(processId).pipe(map((process) => process?.data?.selectedBranch)))
|
||||
);
|
||||
}
|
||||
|
||||
return this.getProcessById$(processId).pipe(map((process) => process?.data?.selectedBranch));
|
||||
}
|
||||
|
||||
async createProcess(process: ApplicationProcess) {
|
||||
const existingProcess = await this.getProcessById$(process?.id).pipe(first()).toPromise();
|
||||
if (existingProcess?.id === process?.id) {
|
||||
|
||||
@@ -3,6 +3,8 @@ import { ApplicationProcess } from '..';
|
||||
|
||||
const prefix = '[CORE-APPLICATION]';
|
||||
|
||||
export const setTitle = createAction(`${prefix} Set Title`, props<{ title: string }>());
|
||||
|
||||
export const setSection = createAction(`${prefix} Set Section`, props<{ section: 'customer' | 'branch' }>());
|
||||
|
||||
export const addProcess = createAction(`${prefix} Add Process`, props<{ process: ApplicationProcess }>());
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import { Action, createReducer, on } from '@ngrx/store';
|
||||
import { setSection, addProcess, removeProcess, setActivatedProcess, patchProcess, patchProcessData } from './application.actions';
|
||||
import {
|
||||
setSection,
|
||||
addProcess,
|
||||
removeProcess,
|
||||
setActivatedProcess,
|
||||
patchProcess,
|
||||
patchProcessData,
|
||||
setTitle,
|
||||
} from './application.actions';
|
||||
import { ApplicationState, INITIAL_APPLICATION_STATE } from './application.state';
|
||||
|
||||
const _applicationReducer = createReducer(
|
||||
INITIAL_APPLICATION_STATE,
|
||||
on(setTitle, (state, { title }) => ({ ...state, title })),
|
||||
on(setSection, (state, { section }) => ({ ...state, section })),
|
||||
on(addProcess, (state, { process }) => ({ ...state, processes: [...state.processes, { data: {}, ...process }] })),
|
||||
on(removeProcess, (state, { processId }) => {
|
||||
|
||||
@@ -5,14 +5,16 @@ import * as selectors from './application.selectors';
|
||||
describe('applicationSelectors', () => {
|
||||
it('should select the processes', () => {
|
||||
const processes: ApplicationProcess[] = [{ id: 1, name: 'Vorgang 1', section: 'customer' }];
|
||||
const state: Partial<ApplicationState> = {
|
||||
const state: ApplicationState = {
|
||||
processes,
|
||||
section: 'customer',
|
||||
};
|
||||
expect(selectors.selectProcesses.projector(state)).toEqual(processes);
|
||||
});
|
||||
|
||||
it('should select the section', () => {
|
||||
const state: Partial<ApplicationState> = {
|
||||
const state: ApplicationState = {
|
||||
processes: [],
|
||||
section: 'customer',
|
||||
};
|
||||
expect(selectors.selectSection.projector(state)).toEqual('customer');
|
||||
@@ -24,8 +26,9 @@ describe('applicationSelectors', () => {
|
||||
{ id: 2, name: 'Vorgang 2', section: 'customer', activated: 300 },
|
||||
{ id: 3, name: 'Vorgang 3', section: 'customer', activated: 200 },
|
||||
];
|
||||
const state: Partial<ApplicationState> = {
|
||||
const state: ApplicationState = {
|
||||
processes,
|
||||
section: 'customer',
|
||||
};
|
||||
expect(selectors.selectActivatedProcess.projector(state)).toEqual(processes[1]);
|
||||
});
|
||||
|
||||
@@ -2,6 +2,8 @@ import { createFeatureSelector, createSelector } from '@ngrx/store';
|
||||
import { ApplicationState } from './application.state';
|
||||
export const selectApplicationState = createFeatureSelector<ApplicationState>('core-application');
|
||||
|
||||
export const selectTitle = createSelector(selectApplicationState, (s) => s.title);
|
||||
|
||||
export const selectSection = createSelector(selectApplicationState, (s) => s.section);
|
||||
|
||||
export const selectProcesses = createSelector(selectApplicationState, (s) => s.processes);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { ApplicationProcess } from '../defs';
|
||||
|
||||
export interface ApplicationState {
|
||||
title: string;
|
||||
processes: ApplicationProcess[];
|
||||
section: 'customer' | 'branch';
|
||||
}
|
||||
|
||||
export const INITIAL_APPLICATION_STATE: ApplicationState = {
|
||||
title: '',
|
||||
processes: [],
|
||||
section: 'customer',
|
||||
};
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -1,25 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"compilerOptions": {
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
const customLaunchers = require('../../../karma/custom-launchers');
|
||||
const junitReporter = require('../../../karma/junit-reporter')('core-auth');
|
||||
const coverageReporter = require('../../../karma/coverage-reporter')('core-auth');
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('karma-junit-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true, // removes the duplicated traces
|
||||
},
|
||||
coverageReporter,
|
||||
junitReporter,
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
customLaunchers,
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -1,7 +1,11 @@
|
||||
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { AuthService } from './auth.service';
|
||||
import { OAuthModule } from 'angular-oauth2-oidc';
|
||||
@NgModule({})
|
||||
import { IfRoleDirective } from './if-role.directive';
|
||||
@NgModule({
|
||||
declarations: [IfRoleDirective],
|
||||
exports: [IfRoleDirective],
|
||||
})
|
||||
export class AuthModule {
|
||||
static forRoot(): ModuleWithProviders<AuthModule> {
|
||||
return {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { coerceArray, coerceStringArray } from '@angular/cdk/coercion';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Config } from '@core/config';
|
||||
import { isNullOrUndefined } from '@utils/common';
|
||||
import { AuthConfig, OAuthService } from 'angular-oauth2-oidc';
|
||||
import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { asapScheduler, BehaviorSubject } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -14,20 +15,29 @@ export class AuthService {
|
||||
return this._initialized.asObservable();
|
||||
}
|
||||
|
||||
constructor(private _config: Config, private readonly _oAuthService: OAuthService) {}
|
||||
private _authConfig: AuthConfig;
|
||||
|
||||
constructor(private _config: Config, private readonly _oAuthService: OAuthService) {
|
||||
this._oAuthService.events?.subscribe((event) => {
|
||||
if (event.type === 'token_received') {
|
||||
console.log('SSO Token Expiration:', new Date(this._oAuthService.getAccessTokenExpiration()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async init() {
|
||||
if (this._initialized.getValue()) {
|
||||
throw new Error('AuthService is already initialized');
|
||||
}
|
||||
|
||||
const authConfig: AuthConfig = this._config.get('@core/auth');
|
||||
this._authConfig = this._config.get('@core/auth');
|
||||
|
||||
authConfig.redirectUri = window.location.origin;
|
||||
authConfig.silentRefreshRedirectUri = window.location.origin + '/silent-refresh.html';
|
||||
authConfig.useSilentRefresh = true;
|
||||
this._authConfig.redirectUri = window.location.origin;
|
||||
|
||||
this._oAuthService.configure(authConfig);
|
||||
this._authConfig.silentRefreshRedirectUri = window.location.origin + '/silent-refresh.html';
|
||||
this._authConfig.useSilentRefresh = true;
|
||||
|
||||
this._oAuthService.configure(this._authConfig);
|
||||
this._oAuthService.tokenValidationHandler = new JwksValidationHandler();
|
||||
|
||||
this._oAuthService.setupAutomaticSilentRefresh();
|
||||
@@ -84,5 +94,32 @@ export class AuthService {
|
||||
|
||||
async logout() {
|
||||
await this._oAuthService.revokeTokenAndLogout();
|
||||
// asapScheduler.schedule(() => {
|
||||
// window.location.reload();
|
||||
// }, 250);
|
||||
}
|
||||
|
||||
hasRole(role: string | string[]) {
|
||||
const roles = coerceArray(role);
|
||||
|
||||
const userRoles = this.getClaimByKey('role');
|
||||
|
||||
if (isNullOrUndefined(userRoles)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return roles.every((r) => userRoles.includes(r));
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
try {
|
||||
if (this._authConfig.responseType.includes('code') && this._authConfig.scope.includes('offline_access')) {
|
||||
await this._oAuthService.refreshToken();
|
||||
} else {
|
||||
await this._oAuthService.silentRefresh();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
65
apps/core/auth/src/lib/if-role.directive.spec.ts
Normal file
65
apps/core/auth/src/lib/if-role.directive.spec.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
// import { SpectatorDirective, createDirectiveFactory } from '@ngneat/spectator';
|
||||
// import { IfRoleDirective } from './if-role.directive';
|
||||
// import { AuthService } from './auth.service';
|
||||
// import { TemplateRef, ViewContainerRef } from '@angular/core';
|
||||
|
||||
// describe('IfRoleDirective', () => {
|
||||
// let spectator: SpectatorDirective<IfRoleDirective>;
|
||||
// const createDirective = createDirectiveFactory({
|
||||
// directive: IfRoleDirective,
|
||||
// mocks: [AuthService],
|
||||
// });
|
||||
|
||||
// it('should create an instance', () => {
|
||||
// spectator = createDirective(`<div *ifRole="'admin'"></div>`);
|
||||
// expect(spectator.directive).toBeTruthy();
|
||||
// });
|
||||
|
||||
// it('should render template when user has the role', () => {
|
||||
// spectator = createDirective(`<div *ifRole="'admin'"></div>`);
|
||||
// const authService = spectator.inject(AuthService);
|
||||
// const viewContainerRef = spectator.inject(ViewContainerRef);
|
||||
// const templateRef = spectator.inject(TemplateRef);
|
||||
// authService.hasRole.and.returnValue(true);
|
||||
// spectator.directive.ngOnChanges();
|
||||
// expect(viewContainerRef.createEmbeddedView).toHaveBeenCalledWith(templateRef, spectator.directive.getContext());
|
||||
// });
|
||||
|
||||
// it('should render else template when user does not have the role', () => {
|
||||
// authService.hasRole.and.returnValue(false);
|
||||
// const elseTemplateRef = {} as TemplateRef<any>;
|
||||
// spectator = createDirective(`<ng-template #elseTemplateRef></ng-template><div *ifRole="'admin'; else elseTemplateRef"></div>`, {
|
||||
// hostProps: {
|
||||
// elseTemplateRef,
|
||||
// },
|
||||
// });
|
||||
// spectator.directive.ngOnChanges();
|
||||
// expect(viewContainerRef.createEmbeddedView).toHaveBeenCalledWith(elseTemplateRef, spectator.directive.getContext());
|
||||
// });
|
||||
|
||||
// it('should render else template when user does not have the role using ifNotRole input', () => {
|
||||
// authService.hasRole.and.returnValue(false);
|
||||
// const elseTemplateRef = {} as TemplateRef<any>;
|
||||
// spectator = createDirective(`<ng-template #elseTemplateRef></ng-template><div *ifNotRole="'admin'; else elseTemplateRef"></div>`, {
|
||||
// hostProps: {
|
||||
// elseTemplateRef,
|
||||
// },
|
||||
// });
|
||||
// spectator.directive.ngOnChanges();
|
||||
// expect(viewContainerRef.createEmbeddedView).toHaveBeenCalledWith(elseTemplateRef, spectator.directive.getContext());
|
||||
// });
|
||||
|
||||
// it('should clear view when user does not have the role and elseTemplateRef is not defined', () => {
|
||||
// authService.hasRole.and.returnValue(false);
|
||||
// spectator = createDirective(`<div *ifRole="'admin'"></div>`);
|
||||
// spectator.directive.ngOnChanges();
|
||||
// expect(viewContainerRef.clear).toHaveBeenCalled();
|
||||
// });
|
||||
|
||||
// it('should set $implicit to ifRole or ifNotRole input', () => {
|
||||
// spectator = createDirective(`<div *ifRole="'admin'"></div>`);
|
||||
// expect(spectator.directive.getContext().$implicit).toEqual('admin');
|
||||
// spectator.setInput('ifNotRole', 'user');
|
||||
// expect(spectator.directive.getContext().$implicit).toEqual('user');
|
||||
// });
|
||||
// });
|
||||
59
apps/core/auth/src/lib/if-role.directive.ts
Normal file
59
apps/core/auth/src/lib/if-role.directive.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Directive, Input, OnChanges, TemplateRef, ViewContainerRef } from '@angular/core';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[ifRole],[ifRoleElse],[ifNotRole],[ifNotRoleElse]',
|
||||
})
|
||||
export class IfRoleDirective implements OnChanges {
|
||||
@Input()
|
||||
ifRole: string | string[];
|
||||
|
||||
@Input()
|
||||
ifRoleElse: TemplateRef<any>;
|
||||
|
||||
@Input()
|
||||
ifNotRole: string | string[];
|
||||
|
||||
@Input()
|
||||
ifNotRoleElse: TemplateRef<any>;
|
||||
|
||||
get renderTemplateRef() {
|
||||
if (this.ifRole) {
|
||||
return this._authService.hasRole(this.ifRole);
|
||||
}
|
||||
if (this.ifNotRole) {
|
||||
return !this._authService.hasRole(this.ifNotRole);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
get elseTemplateRef() {
|
||||
return this.ifRoleElse || this.ifNotRoleElse;
|
||||
}
|
||||
|
||||
constructor(private _templateRef: TemplateRef<any>, private _viewContainer: ViewContainerRef, private _authService: AuthService) {}
|
||||
|
||||
ngOnChanges() {
|
||||
this.render();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.renderTemplateRef) {
|
||||
this._viewContainer.createEmbeddedView(this._templateRef, this.getContext());
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.elseTemplateRef) {
|
||||
this._viewContainer.createEmbeddedView(this.elseTemplateRef, this.getContext());
|
||||
return;
|
||||
}
|
||||
|
||||
this._viewContainer.clear();
|
||||
}
|
||||
|
||||
getContext(): { $implicit: string | string[] } {
|
||||
return {
|
||||
$implicit: this.ifRole || this.ifNotRole,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { teardown: { destroyAfterEach: true } });
|
||||
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -1,25 +0,0 @@
|
||||
# Breadcrumb
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project breadcrumb` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project breadcrumb`.
|
||||
|
||||
> Note: Don't forget to add `--project breadcrumb` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build breadcrumb` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build breadcrumb`, go to the dist folder `cd dist/breadcrumb` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test breadcrumb` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
@@ -1,32 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/core/breadcrumb'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "@core/breadcrumb",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^10.1.2",
|
||||
"@angular/core": "^10.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
}
|
||||
@@ -22,17 +22,9 @@ describe('Breadcrumb Service', () => {
|
||||
service = TestBed.inject(BreadcrumbService);
|
||||
});
|
||||
|
||||
describe('getByKey$', () => {
|
||||
it('should call store.select with the selectBreadcrumbsByKey selector', () => {
|
||||
store.select.and.returnValue(of([]));
|
||||
service.getByKey$('unit-test');
|
||||
expect(store.select).toHaveBeenCalledWith(selectors.selectBreadcrumbsByKey, 'unit-test');
|
||||
});
|
||||
});
|
||||
|
||||
describe('addBreadcrumb', () => {
|
||||
it('should call store.dispatch with the addBreadecrumb action and retuns a breadcrumb with an id', () => {
|
||||
let breadcrumb: Breadcrumb = { name: 'unit-test', key: 'hello-key', path: 'Run The Test' };
|
||||
let breadcrumb: Breadcrumb = { name: 'unit-test', key: 'hello-key', path: 'Run The Test', section: 'customer' };
|
||||
breadcrumb = service.addBreadcrumb(breadcrumb);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(actions.addBreadcrumb({ breadcrumb }));
|
||||
expect(isNumber(breadcrumb.id)).toBeTruthy();
|
||||
|
||||
@@ -135,9 +135,9 @@ export class BreadcrumbService {
|
||||
crumbs.forEach((crumb) => this.removeBreadcrumb(crumb.id));
|
||||
}
|
||||
|
||||
getLatestBreadcrumbForSection(section: 'customer' | 'branch') {
|
||||
getLatestBreadcrumbForSection(section: 'customer' | 'branch', predicate: (crumb: Breadcrumb) => boolean = (_) => true) {
|
||||
return this.store
|
||||
.select(selectors.selectBreadcrumbsBySection, { section })
|
||||
.pipe(map((crumbs) => crumbs.sort((a, b) => b.changed - a.changed).find((f) => true)));
|
||||
.pipe(map((crumbs) => crumbs.sort((a, b) => b.timestamp - a.timestamp).find((f) => predicate(f))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export interface Breadcrumb {
|
||||
/**
|
||||
* Url
|
||||
*/
|
||||
path: string;
|
||||
path: string | any[];
|
||||
|
||||
/**
|
||||
* Query Parameter
|
||||
|
||||
@@ -17,6 +17,7 @@ describe('Breadcrumb Reducer', () => {
|
||||
key: 'unit-test',
|
||||
name: 'Test Name',
|
||||
path: 'Test Patch',
|
||||
section: 'customer',
|
||||
};
|
||||
|
||||
const fixture = breadcrumbReducer(INIT, action.addBreadcrumb({ breadcrumb }));
|
||||
@@ -32,6 +33,7 @@ describe('Breadcrumb Reducer', () => {
|
||||
key: 'unit-test',
|
||||
name: 'Test Name',
|
||||
path: 'Test Patch',
|
||||
section: 'customer',
|
||||
};
|
||||
|
||||
const expected = {
|
||||
@@ -54,6 +56,7 @@ describe('Breadcrumb Reducer', () => {
|
||||
key: 'unit-test',
|
||||
name: 'Test Name',
|
||||
path: 'Test Patch',
|
||||
section: 'customer',
|
||||
};
|
||||
|
||||
const state = breadcrumbReducer(INIT, action.addBreadcrumb({ breadcrumb }));
|
||||
@@ -71,6 +74,7 @@ describe('Breadcrumb Reducer', () => {
|
||||
key: 'unit-test',
|
||||
name: 'Test Name',
|
||||
path: 'Test Patch',
|
||||
section: 'customer',
|
||||
};
|
||||
const breadcrumb2 = { ...breadcrumb1, id: 2 };
|
||||
const breadcrumb3 = { ...breadcrumb1, id: 3 };
|
||||
|
||||
@@ -8,16 +8,29 @@ describe('Breadcrumb Selectors', () => {
|
||||
let state: BreadcrumbState;
|
||||
|
||||
beforeEach(() => {
|
||||
state = breadcrumbReducer(INIT, action.addBreadcrumb({ breadcrumb: { id: 1, key: 'unit-test-1', path: '', name: 'Unit Test 1' } }));
|
||||
state = breadcrumbReducer(
|
||||
state,
|
||||
action.addBreadcrumb({ breadcrumb: { id: 2, key: 'unit-test-1', path: '', name: 'Unit Test 1', tags: ['details'] } })
|
||||
INIT,
|
||||
action.addBreadcrumb({ breadcrumb: { id: 1, key: 'unit-test-1', path: '', name: 'Unit Test 1', section: 'customer' } })
|
||||
);
|
||||
state = breadcrumbReducer(state, action.addBreadcrumb({ breadcrumb: { id: 3, key: 'unit-test-2', path: '', name: 'Unit Test 1' } }));
|
||||
state = breadcrumbReducer(state, action.addBreadcrumb({ breadcrumb: { id: 4, key: 'unit-test-3', path: '', name: 'Unit Test 1' } }));
|
||||
state = breadcrumbReducer(
|
||||
state,
|
||||
action.addBreadcrumb({ breadcrumb: { id: 5, key: 'unit-test-3', path: '', name: 'Unit Test 1', tags: ['details'] } })
|
||||
action.addBreadcrumb({
|
||||
breadcrumb: { id: 2, key: 'unit-test-1', path: '', name: 'Unit Test 1', tags: ['details'], section: 'customer' },
|
||||
})
|
||||
);
|
||||
state = breadcrumbReducer(
|
||||
state,
|
||||
action.addBreadcrumb({ breadcrumb: { id: 3, key: 'unit-test-2', path: '', name: 'Unit Test 1', section: 'customer' } })
|
||||
);
|
||||
state = breadcrumbReducer(
|
||||
state,
|
||||
action.addBreadcrumb({ breadcrumb: { id: 4, key: 'unit-test-3', path: '', name: 'Unit Test 1', section: 'customer' } })
|
||||
);
|
||||
state = breadcrumbReducer(
|
||||
state,
|
||||
action.addBreadcrumb({
|
||||
breadcrumb: { id: 5, key: 'unit-test-3', path: '', name: 'Unit Test 1', tags: ['details'], section: 'customer' },
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ export const selectBreadcrumbById = createSelector(selectEntities, (entities, id
|
||||
/**
|
||||
* Gibt alle Breadcrumb Entities als Array zurück die den key enthalten
|
||||
*/
|
||||
export const selectBreadcrumbsByKey = createSelector(selectAll, (entities, key: string) => entities.filter((crumb) => crumb.key === key));
|
||||
export const selectBreadcrumbsByKey = createSelector(selectAll, (entities, key: string) => entities.filter((crumb) => crumb.key == key));
|
||||
|
||||
/**
|
||||
* Gibt alle Breadcrumb Entities als Array zurück die den key und tag enthalten
|
||||
@@ -28,7 +28,7 @@ export const selectBreadcrumbsByKey = createSelector(selectAll, (entities, key:
|
||||
export const selectBreadcrumbsByKeyAndTag = createSelector(
|
||||
selectAll,
|
||||
(entities: Breadcrumb[], { key, tag }: { key: string; tag: string }) =>
|
||||
entities.filter((crumb) => crumb.key === key && isArray(crumb.tags) && crumb.tags.includes(tag))
|
||||
entities.filter((crumb) => crumb.key == key && isArray(crumb.tags) && crumb.tags.includes(tag))
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ export const selectBreadcrumbsByKeyAndTag = createSelector(
|
||||
export const selectBreadcrumbsByKeyAndTags = createSelector(
|
||||
selectAll,
|
||||
(entities: Breadcrumb[], { key, tags }: { key: string; tags: string[] }) =>
|
||||
entities.filter((crumb) => crumb.key === key && isArray(crumb.tags) && tags.every((tag) => crumb.tags.includes(tag)))
|
||||
entities.filter((crumb) => crumb.key == key && isArray(crumb.tags) && tags.every((tag) => crumb.tags.includes(tag)))
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -1,25 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"compilerOptions": {
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
25
apps/core/cache/README.md
vendored
25
apps/core/cache/README.md
vendored
@@ -1,25 +0,0 @@
|
||||
# Cache
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project cache` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project cache`.
|
||||
|
||||
> Note: Don't forget to add `--project cache` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build cache` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build cache`, go to the dist folder `cd dist/cache` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test cache` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
32
apps/core/cache/karma.conf.js
vendored
32
apps/core/cache/karma.conf.js
vendored
@@ -1,32 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/core/cache'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
11
apps/core/cache/package.json
vendored
11
apps/core/cache/package.json
vendored
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "@core/cache",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^10.1.2",
|
||||
"@angular/core": "^10.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
}
|
||||
24
apps/core/cache/src/test.ts
vendored
24
apps/core/cache/src/test.ts
vendored
@@ -1,24 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
25
apps/core/cache/tsconfig.lib.json
vendored
25
apps/core/cache/tsconfig.lib.json
vendored
@@ -1,25 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
10
apps/core/cache/tsconfig.lib.prod.json
vendored
10
apps/core/cache/tsconfig.lib.prod.json
vendored
@@ -1,10 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"compilerOptions": {
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
17
apps/core/cache/tslint.json
vendored
17
apps/core/cache/tslint.json
vendored
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
# Command
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project command` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project command`.
|
||||
|
||||
> Note: Don't forget to add `--project command` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build command` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build command`, go to the dist folder `cd dist/command` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test command` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
@@ -1,32 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/core/command'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "@core/command",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^10.1.2",
|
||||
"@angular/core": "^10.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import { CommandService } from './command.service';
|
||||
|
||||
export abstract class ActionHandler<T = any> {
|
||||
constructor(readonly action: string) {}
|
||||
abstract handler(data: T): Promise<T>;
|
||||
abstract handler(data: T, service?: CommandService): Promise<T>;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { ModuleWithProviders, NgModule, Type } from '@angular/core';
|
||||
import { ModuleWithProviders, NgModule, Provider, Type } from '@angular/core';
|
||||
import { ActionHandler } from './action-handler.interface';
|
||||
import { CommandService } from './command.service';
|
||||
import { FEATURE_ACTION_HANDLERS, ROOT_ACTION_HANDLERS } from './tokens';
|
||||
|
||||
export function provideActionHandlers(actionHandlers: Type<ActionHandler>[]): Provider[] {
|
||||
return [CommandService, actionHandlers.map((handler) => ({ provide: FEATURE_ACTION_HANDLERS, useClass: handler, multi: true }))];
|
||||
}
|
||||
|
||||
@NgModule({})
|
||||
export class CoreCommandModule {
|
||||
static forRoot(actionHandlers: Type<ActionHandler>[]): ModuleWithProviders<CoreCommandModule> {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
// import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CommandService } from './command.service';
|
||||
// import { CommandService } from './command.service';
|
||||
|
||||
describe('CommandService', () => {
|
||||
let service: CommandService;
|
||||
// describe('CommandService', () => {
|
||||
// let service: CommandService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(CommandService);
|
||||
});
|
||||
// beforeEach(() => {
|
||||
// TestBed.configureTestingModule({});
|
||||
// service = TestBed.inject(CommandService);
|
||||
// });
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
// it('should be created', () => {
|
||||
// expect(service).toBeTruthy();
|
||||
// });
|
||||
// });
|
||||
|
||||
@@ -16,7 +16,7 @@ export class CommandService {
|
||||
throw new Error('Action Handler does not exist');
|
||||
}
|
||||
|
||||
data = await handler.handler(data);
|
||||
data = await handler.handler(data, this);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -1,25 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"compilerOptions": {
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
# Config
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.0.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project config` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project config`.
|
||||
|
||||
> Note: Don't forget to add `--project config` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build config` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build config`, go to the dist folder `cd dist/config` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test config` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
||||
@@ -1,43 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
const customLaunchers = require('../../../karma/custom-launchers');
|
||||
const junitReporter = require('../../../karma/junit-reporter')('core-config');
|
||||
const coverageReporter = require('../../../karma/coverage-reporter')('core-config');
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('karma-junit-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true, // removes the duplicated traces
|
||||
},
|
||||
coverageReporter,
|
||||
junitReporter,
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
customLaunchers,
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { teardown: { destroyAfterEach: true } });
|
||||
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -1,17 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
# Environment
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project environment` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project environment`.
|
||||
|
||||
> Note: Don't forget to add `--project environment` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build environment` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build environment`, go to the dist folder `cd dist/environment` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test environment` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
@@ -1,32 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/core/environment'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "@core/environment",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^10.1.2",
|
||||
"@angular/core": "^10.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,62 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { fromEvent } from 'rxjs';
|
||||
import { map, take, tap } from 'rxjs/operators';
|
||||
import { Platform } from '@angular/cdk/platform';
|
||||
import { NativeContainerService } from 'native-container';
|
||||
import { BreakpointObserver } from '@angular/cdk/layout';
|
||||
import { shareReplay } from 'rxjs/operators';
|
||||
|
||||
const MATCH_TABLET = '(max-width: 1024px)';
|
||||
|
||||
const MATCH_DESKTOP_SMALL = '(min-width: 1025px) and (max-width: 1439px)';
|
||||
|
||||
const MATCH_DESKTOP = '(min-width: 1440px)';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class EnvironmentService {
|
||||
constructor() {}
|
||||
constructor(
|
||||
private _platform: Platform,
|
||||
private _nativeContainer: NativeContainerService,
|
||||
private _breakpointObserver: BreakpointObserver
|
||||
) {}
|
||||
|
||||
// /** Returns whether app is used within native container*/
|
||||
// isNative(): Promise<boolean> {
|
||||
// return fromEvent(window, 'message')
|
||||
// .pipe(
|
||||
// map((evt: MessageEvent) => evt.data),
|
||||
// tap(console.log.bind(window)),
|
||||
// map((data) => data.status === 'INIT'),
|
||||
// take(1)
|
||||
// )
|
||||
// .toPromise();
|
||||
// }
|
||||
|
||||
/** Returns whether current device is mobile phone or tablet */
|
||||
async isMobile(): Promise<boolean> {
|
||||
return 'orientation' in window;
|
||||
matchTablet(): boolean {
|
||||
return this._breakpointObserver.isMatched(MATCH_TABLET);
|
||||
}
|
||||
|
||||
/** Returns whether current device is desktop */
|
||||
async isDesktop(): Promise<boolean> {
|
||||
return !(await this.isMobile());
|
||||
matchTablet$ = this._breakpointObserver.observe(MATCH_TABLET).pipe(shareReplay());
|
||||
|
||||
matchDesktopSmall(): boolean {
|
||||
return this._breakpointObserver.isMatched(MATCH_DESKTOP_SMALL);
|
||||
}
|
||||
|
||||
matchDesktopSmall$ = this._breakpointObserver.observe(MATCH_DESKTOP_SMALL).pipe(shareReplay());
|
||||
|
||||
matchDesktop(): boolean {
|
||||
return this._breakpointObserver.isMatched(MATCH_DESKTOP);
|
||||
}
|
||||
|
||||
matchDesktop$ = this._breakpointObserver.observe(MATCH_DESKTOP).pipe(shareReplay());
|
||||
|
||||
/**
|
||||
* @deprecated Use `matchDesktopSmall` or 'matchDesktop' instead.
|
||||
*/
|
||||
isDesktop(): boolean {
|
||||
return !this.isTablet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `matchTablet` instead.
|
||||
*/
|
||||
isTablet(): boolean {
|
||||
return this.isNative() || this.isSafari();
|
||||
}
|
||||
|
||||
isNative(): boolean {
|
||||
return this._nativeContainer.isNative;
|
||||
}
|
||||
|
||||
isSafari(): boolean {
|
||||
return this._platform.IOS && this._platform.SAFARI;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -1,25 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"compilerOptions": {
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
const customLaunchers = require('../../../karma/custom-launchers');
|
||||
const junitReporter = require('../../../karma/junit-reporter')('core-logger');
|
||||
const coverageReporter = require('../../../karma/coverage-reporter')('core-logger');
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('karma-junit-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true, // removes the duplicated traces
|
||||
},
|
||||
junitReporter,
|
||||
coverageReporter,
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
customLaunchers,
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js';
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { teardown: { destroyAfterEach: true } });
|
||||
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
@@ -1,17 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user