@duetds/cli 4.1.4 → 4.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/package.json +2 -2
  2. package/templates/angular/18.1.0-standalone/.browserlistrc +16 -0
  3. package/templates/angular/18.1.0-standalone/.depcheckrc +2 -0
  4. package/templates/angular/18.1.0-standalone/.editorconfig +16 -0
  5. package/templates/angular/18.1.0-standalone/.eslintrc.json +52 -0
  6. package/templates/angular/18.1.0-standalone/.prettierignore +3 -0
  7. package/templates/angular/18.1.0-standalone/.prettierrc +14 -0
  8. package/templates/angular/18.1.0-standalone/LICENSE.md +29 -0
  9. package/templates/angular/18.1.0-standalone/README.md +32 -0
  10. package/templates/angular/18.1.0-standalone/angular.json +138 -0
  11. package/templates/angular/18.1.0-standalone/config/jest.base.ts +17 -0
  12. package/templates/angular/18.1.0-standalone/config/jest.setup.ts +24 -0
  13. package/templates/angular/18.1.0-standalone/package.file +59 -0
  14. package/templates/angular/18.1.0-standalone/playwright.config.ts +26 -0
  15. package/templates/angular/18.1.0-standalone/src/app/agreement.model.ts +3 -0
  16. package/templates/angular/18.1.0-standalone/src/app/app-routing.module.ts +11 -0
  17. package/templates/angular/18.1.0-standalone/src/app/app.component.html +5 -0
  18. package/templates/angular/18.1.0-standalone/src/app/app.component.scss +0 -0
  19. package/templates/angular/18.1.0-standalone/src/app/app.component.ts +25 -0
  20. package/templates/angular/18.1.0-standalone/src/app/currency-formatter.service.ts +12 -0
  21. package/templates/angular/18.1.0-standalone/src/app/footer/footer.component.html +22 -0
  22. package/templates/angular/18.1.0-standalone/src/app/footer/footer.component.scss +0 -0
  23. package/templates/angular/18.1.0-standalone/src/app/footer/footer.component.ts +12 -0
  24. package/templates/angular/18.1.0-standalone/src/app/header/header.component.html +1 -0
  25. package/templates/angular/18.1.0-standalone/src/app/header/header.component.scss +0 -0
  26. package/templates/angular/18.1.0-standalone/src/app/header/header.component.ts +12 -0
  27. package/templates/angular/18.1.0-standalone/src/app/index-page/index-page.component.html +49 -0
  28. package/templates/angular/18.1.0-standalone/src/app/index-page/index-page.component.scss +0 -0
  29. package/templates/angular/18.1.0-standalone/src/app/index-page/index-page.component.ts +74 -0
  30. package/templates/angular/18.1.0-standalone/src/app/investment-amount/investment-amount.component.html +87 -0
  31. package/templates/angular/18.1.0-standalone/src/app/investment-amount/investment-amount.component.scss +0 -0
  32. package/templates/angular/18.1.0-standalone/src/app/investment-amount/investment-amount.component.ts +41 -0
  33. package/templates/angular/18.1.0-standalone/src/app/investment-origin/investment-origin.component.html +12 -0
  34. package/templates/angular/18.1.0-standalone/src/app/investment-origin/investment-origin.component.scss +0 -0
  35. package/templates/angular/18.1.0-standalone/src/app/investment-origin/investment-origin.component.ts +35 -0
  36. package/templates/angular/18.1.0-standalone/src/app/summary/summary.component.html +74 -0
  37. package/templates/angular/18.1.0-standalone/src/app/summary/summary.component.scss +0 -0
  38. package/templates/angular/18.1.0-standalone/src/app/summary/summary.component.ts +24 -0
  39. package/templates/angular/18.1.0-standalone/src/app/value-accessors.ts +156 -0
  40. package/templates/angular/18.1.0-standalone/src/assets/.gitkeep +0 -0
  41. package/templates/angular/18.1.0-standalone/src/assets/img/android-chrome-192x192.png +0 -0
  42. package/templates/angular/18.1.0-standalone/src/assets/img/apple-touch-icon-180x180.png +0 -0
  43. package/templates/angular/18.1.0-standalone/src/assets/img/splash-screen-icon-512x512.png +0 -0
  44. package/templates/angular/18.1.0-standalone/src/environments/environment.prod.ts +3 -0
  45. package/templates/angular/18.1.0-standalone/src/environments/environment.ts +16 -0
  46. package/templates/angular/18.1.0-standalone/src/favicon.ico +0 -0
  47. package/templates/angular/18.1.0-standalone/src/index.html +24 -0
  48. package/templates/angular/18.1.0-standalone/src/main.ts +35 -0
  49. package/templates/angular/18.1.0-standalone/src/manifest.json +19 -0
  50. package/templates/angular/18.1.0-standalone/src/polyfills.ts +62 -0
  51. package/templates/angular/18.1.0-standalone/src/styles.scss +3 -0
  52. package/templates/angular/18.1.0-standalone/src/tests/app.test.ts +13 -0
  53. package/templates/angular/18.1.0-standalone/src/tests/playwright/playwright.test.ts +54 -0
  54. package/templates/angular/18.1.0-standalone/src/tests/playwright/playwright.test.ts-snapshots/angular-1-chromium-darwin.png +0 -0
  55. package/templates/angular/18.1.0-standalone/src/tests/playwright/playwright.test.ts-snapshots/angular-2-chromium-darwin.png +0 -0
  56. package/templates/angular/18.1.0-standalone/src/tests/playwright/playwright.test.ts-snapshots/angular-3-chromium-darwin.png +0 -0
  57. package/templates/angular/18.1.0-standalone/src/tests/playwright/playwright.test.ts-snapshots/angular-4-chromium-darwin.png +0 -0
  58. package/templates/angular/18.1.0-standalone/src/tests/playwright/playwright.test.ts-snapshots/angular-5-chromium-darwin.png +0 -0
  59. package/templates/angular/18.1.0-standalone/src/tests/playwright/playwright.test.ts-snapshots/code-chromium-darwin.json +16 -0
  60. package/templates/angular/18.1.0-standalone/src/utils/string.utils.ts +1 -0
  61. package/templates/angular/18.1.0-standalone/tsconfig.app.json +9 -0
  62. package/templates/angular/18.1.0-standalone/tsconfig.base.json +17 -0
  63. package/templates/angular/18.1.0-standalone/tsconfig.json +9 -0
  64. package/templates/angular/18.1.0-standalone/tsconfig.spec.json +15 -0
@@ -0,0 +1,74 @@
1
+ import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"
2
+ import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"
3
+ import { Agreement } from "../agreement.model"
4
+
5
+ import { currencyFormatFI } from "../../utils/string.utils"
6
+ import { JsonPipe } from "@angular/common"
7
+ import { InvestmentAmountComponent } from "../investment-amount/investment-amount.component"
8
+ import { InvestmentOriginComponent } from "../investment-origin/investment-origin.component"
9
+ import { SummaryComponent } from "../summary/summary.component"
10
+
11
+ @Component({
12
+ standalone: true,
13
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
14
+ selector: "app-index-page",
15
+ templateUrl: "./index-page.component.html",
16
+ imports: [
17
+ JsonPipe,
18
+ ReactiveFormsModule,
19
+ InvestmentAmountComponent,
20
+ InvestmentOriginComponent,
21
+ SummaryComponent
22
+ ],
23
+ styleUrls: ["./index-page.component.scss"]
24
+ })
25
+ export class IndexPageComponent {
26
+ constructor(private formBuilder: FormBuilder) {}
27
+
28
+ currentStep = 0
29
+ completed = false
30
+
31
+ form = this.formBuilder.group({
32
+ investmentAmount: this.formBuilder.group({
33
+ agreement: [null, [Validators.required]],
34
+ additionalInvestment: 50
35
+ }),
36
+ investmentOrigin: this.formBuilder.group({
37
+ salary: false,
38
+ gift: false,
39
+ heritage: false,
40
+ entrepreneurialIncome: false,
41
+ assets: false,
42
+ otherIncome: false,
43
+ investment: false,
44
+ extras: null
45
+ })
46
+ })
47
+
48
+ agreements: Record<number, Agreement> = {
49
+ 1: new Agreement("Vakuutus 1", 2500),
50
+ 2: new Agreement("Vakuutus 2", 1000)
51
+ }
52
+
53
+ get selectedAgreement() {
54
+ return this.agreements[this.form.value.investmentAmount.agreement ?? 1]
55
+ }
56
+
57
+ formatNumber(value: number) {
58
+ return currencyFormatFI.format(value)
59
+ }
60
+
61
+ handleStepChange(event: CustomEvent) {
62
+ this.currentStep = event.detail.toStep
63
+ }
64
+
65
+ handleNextClick(event: Event) {
66
+ event.preventDefault()
67
+ this.currentStep++
68
+ }
69
+
70
+ handleSubmit(event: Event) {
71
+ event.preventDefault()
72
+ this.completed = true
73
+ }
74
+ }
@@ -0,0 +1,87 @@
1
+ <ng-container [formGroup]="form">
2
+ <duet-select
3
+ formControlName="agreement"
4
+ expand
5
+ label="Valitse sopimus"
6
+ placeholder="Valitse…"
7
+ [items]="agreementOptions"
8
+ >
9
+ </duet-select>
10
+ <duet-table variation="plain" *ngIf="selectedAgreement">
11
+ <table>
12
+ <thead>
13
+ <tr>
14
+ <th>Sijoituskohde</th>
15
+ <th class="duet-text-right">Osuus</th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <tr>
20
+ <td>
21
+ <duet-button
22
+ variation="plain"
23
+ margin="none"
24
+ padding="none"
25
+ url="https://www.duetds.com/assets/downloads/localtapiola-brand-guidelines.pdf"
26
+ external
27
+ >
28
+ Kohde 1<duet-spacer size="xx-small" direction="horizontal"></duet-spacer>
29
+ <duet-visually-hidden>, avautuu uuteen ikkunaan</duet-visually-hidden>
30
+ </duet-button>
31
+ </td>
32
+ <td class="duet-text-right">25%</td>
33
+ </tr>
34
+ <tr>
35
+ <td>
36
+ <duet-button
37
+ variation="plain"
38
+ margin="none"
39
+ padding="none"
40
+ url="https://www.duetds.com/assets/downloads/localtapiola-brand-guidelines.pdf"
41
+ external
42
+ >
43
+ Kohde 2<duet-spacer size="xx-small" direction="horizontal"></duet-spacer>
44
+ <duet-visually-hidden>, avautuu uuteen ikkunaan</duet-visually-hidden>
45
+ </duet-button>
46
+ </td>
47
+ <td class="duet-text-right">25%</td>
48
+ </tr>
49
+ <tr>
50
+ <td>
51
+ <duet-button
52
+ variation="plain"
53
+ margin="none"
54
+ padding="none"
55
+ url="https://www.duetds.com/assets/downloads/localtapiola-brand-guidelines.pdf"
56
+ external
57
+ >
58
+ Kohde 3<duet-spacer size="xx-small" direction="horizontal"></duet-spacer>
59
+ <duet-visually-hidden>, avautuu uuteen ikkunaan</duet-visually-hidden>
60
+ </duet-button>
61
+ </td>
62
+ <td class="duet-text-right">50%</td>
63
+ </tr>
64
+ </tbody>
65
+ <tfoot>
66
+ <tr>
67
+ <td class="duet-font-weight-semi-bold">Yhteisarvo</td>
68
+ <td class="duet-text-right duet-font-weight-semi-bold duet-font-size-large">
69
+ {{ formatter.format(selectedAgreement.price) }}
70
+ </td>
71
+ </tr>
72
+ </tfoot>
73
+ </table>
74
+ </duet-table>
75
+ <duet-spacer></duet-spacer>
76
+ <duet-card variation="plain" background="gray-lighter">
77
+ <duet-input
78
+ formControlName="additionalInvestment"
79
+ numeric-keyboard
80
+ expand
81
+ label="Syötä summa"
82
+ placeholder="50"
83
+ icon="form-money"
84
+ type="number"
85
+ ></duet-input>
86
+ </duet-card>
87
+ </ng-container>
@@ -0,0 +1,41 @@
1
+ import { Component, OnInit, Input, ElementRef, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"
2
+ import { FormGroup, ReactiveFormsModule } from "@angular/forms"
3
+ import { Agreement } from "../agreement.model"
4
+ import { CurrencyFormatterService } from "../currency-formatter.service"
5
+ import { NumericValueAccessorDirective, SelectValueAccessorDirective } from "../value-accessors"
6
+ import { NgIf } from "@angular/common"
7
+
8
+ @Component({
9
+ standalone: true,
10
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
11
+ selector: "app-investment-amount",
12
+ templateUrl: "./investment-amount.component.html",
13
+ imports: [
14
+ ReactiveFormsModule,
15
+ SelectValueAccessorDirective,
16
+ NumericValueAccessorDirective,
17
+ NgIf
18
+ ],
19
+ styleUrls: ["./investment-amount.component.scss"]
20
+ })
21
+ export class InvestmentAmountComponent implements OnInit {
22
+ @Input() agreements: Record<number, Agreement>
23
+ @Input() form: FormGroup
24
+
25
+ constructor(public formatter: CurrencyFormatterService) {}
26
+
27
+ ngOnInit(): void {}
28
+
29
+ get selectedAgreement() {
30
+ return this.agreements[this.form.value.agreement]
31
+ }
32
+
33
+ get agreementOptions() {
34
+ return Object.entries(this.agreements).map(([value, { label, price }]) => {
35
+ return {
36
+ value,
37
+ label: `${label} - ${this.formatter.format(price)}`
38
+ }
39
+ })
40
+ }
41
+ }
@@ -0,0 +1,12 @@
1
+ <ng-container [formGroup]="form">
2
+ <duet-checkbox formControlName="salary" label="Valinta 1"></duet-checkbox>
3
+ <duet-checkbox formControlName="gift" label="Valinta 2"></duet-checkbox>
4
+ <duet-checkbox formControlName="heritage" label="Valinta 3"></duet-checkbox>
5
+ <duet-checkbox formControlName="entrepreneurialIncome" label="Valinta 4"></duet-checkbox>
6
+ <duet-checkbox formControlName="assets" label="Valinta 5"></duet-checkbox>
7
+ <duet-checkbox formControlName="otherIncome" label="Valinta 6"></duet-checkbox>
8
+ <duet-checkbox label="Muu, mikä?" (duetChange)="handleExtrasChange($event)"></duet-checkbox>
9
+ <div *ngIf="hasExtras">
10
+ <duet-input formControlName="extras" label="Kerro sijoitettavien varojen muu alkuperä" label-hidden></duet-input>
11
+ </div>
12
+ </ng-container>
@@ -0,0 +1,35 @@
1
+ import { Component, OnInit, Input, ElementRef, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"
2
+ import { FormGroup, ReactiveFormsModule } from "@angular/forms"
3
+ import { BooleanValueAccessorDirective, TextValueAccessorDirective } from "../value-accessors"
4
+ import { NgIf } from "@angular/common"
5
+
6
+ @Component({
7
+ standalone: true,
8
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
9
+ selector: "app-investment-origin",
10
+ templateUrl: "./investment-origin.component.html",
11
+ imports: [
12
+ ReactiveFormsModule,
13
+ BooleanValueAccessorDirective,
14
+ TextValueAccessorDirective,
15
+ NgIf
16
+ ],
17
+ styleUrls: ["./investment-origin.component.scss"]
18
+ })
19
+ export class InvestmentOriginComponent implements OnInit {
20
+ @Input() form: FormGroup
21
+ hasExtras = false
22
+ extrasValue = ""
23
+
24
+ constructor() {}
25
+
26
+ ngOnInit(): void {}
27
+
28
+ handleExtrasChange(event: CustomEvent) {
29
+ this.hasExtras = event.detail.checked
30
+
31
+ if (!event.detail.checked) {
32
+ this.form.get("extras").setValue(null)
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,74 @@
1
+ <ng-container *ngIf="agreement">
2
+ <duet-input expand disabled label="Sopimus" [value]="agreement.label"></duet-input>
3
+ <duet-spacer></duet-spacer>
4
+ <duet-paragraph>Valitsemasi vaihtoehto jakautuu seuraavasti:</duet-paragraph>
5
+ <duet-table variation="plain">
6
+ <table>
7
+ <thead>
8
+ <tr>
9
+ <th>Sijoituskohde</th>
10
+ <th>Osuus</th>
11
+ <th class="duet-text-right">Summa</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <tr>
16
+ <td>
17
+ <duet-button
18
+ variation="plain"
19
+ margin="none"
20
+ padding="none"
21
+ url="https://www.duetds.com/assets/downloads/localtapiola-brand-guidelines.pdf"
22
+ external
23
+ >
24
+ Kohde 1<duet-spacer size="xx-small" direction="horizontal"></duet-spacer>
25
+ <duet-visually-hidden>, avautuu uuteen ikkunaan</duet-visually-hidden>
26
+ </duet-button>
27
+ </td>
28
+ <td>25%</td>
29
+ <td class="duet-text-right">{{ formatter.format(agreement.price * 0.25) }}</td>
30
+ </tr>
31
+ <tr>
32
+ <td>
33
+ <duet-button
34
+ variation="plain"
35
+ margin="none"
36
+ padding="none"
37
+ url="https://www.duetds.com/assets/downloads/localtapiola-brand-guidelines.pdf"
38
+ external
39
+ >
40
+ Kohde 2<duet-spacer size="xx-small" direction="horizontal"></duet-spacer>
41
+ <duet-visually-hidden>, avautuu uuteen ikkunaan</duet-visually-hidden>
42
+ </duet-button>
43
+ </td>
44
+ <td>25%</td>
45
+ <td class="duet-text-right">{{ formatter.format(agreement.price * 0.25) }}</td>
46
+ </tr>
47
+ <tr>
48
+ <td>
49
+ <duet-button
50
+ variation="plain"
51
+ margin="none"
52
+ padding="none"
53
+ url="https://www.duetds.com/assets/downloads/localtapiola-brand-guidelines.pdf"
54
+ external
55
+ >
56
+ Kohde 3<duet-spacer size="xx-small" direction="horizontal"></duet-spacer>
57
+ <duet-visually-hidden>, avautuu uuteen ikkunaan</duet-visually-hidden>
58
+ </duet-button>
59
+ </td>
60
+ <td>50%</td>
61
+ <td class="duet-text-right">{{ formatter.format(agreement.price * 0.5) }}</td>
62
+ </tr>
63
+ </tbody>
64
+ <tfoot>
65
+ <tr>
66
+ <td colspan="2" class="duet-font-weight-semi-bold">Sijoitettava summa</td>
67
+ <td class="duet-text-right duet-font-weight-semi-bold duet-font-size-large">
68
+ {{ formatter.format(agreement.price) }}
69
+ </td>
70
+ </tr>
71
+ </tfoot>
72
+ </table>
73
+ </duet-table>
74
+ </ng-container>
@@ -0,0 +1,24 @@
1
+ import { Component, OnInit, Input, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"
2
+ import { Agreement } from "../agreement.model"
3
+ import { CurrencyFormatterService } from "../currency-formatter.service"
4
+ import { TextValueAccessorDirective } from "../value-accessors"
5
+ import { NgIf } from "@angular/common"
6
+
7
+ @Component({
8
+ standalone: true,
9
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
10
+ imports: [
11
+ TextValueAccessorDirective,
12
+ NgIf
13
+ ],
14
+ selector: "app-summary",
15
+ templateUrl: "./summary.component.html",
16
+ styleUrls: ["./summary.component.scss"]
17
+ })
18
+ export class SummaryComponent implements OnInit {
19
+ @Input() agreement: Agreement
20
+
21
+ constructor(public formatter: CurrencyFormatterService) {}
22
+
23
+ ngOnInit(): void {}
24
+ }
@@ -0,0 +1,156 @@
1
+ /* eslint-disable @angular-eslint/directive-selector, @angular-eslint/no-host-metadata-property */
2
+
3
+ import { Directive, ElementRef, EventEmitter, HostListener, Input, Output } from "@angular/core"
4
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
5
+
6
+ @Directive({
7
+ standalone: true,
8
+ })
9
+ // eslint-disable-next-line @angular-eslint/directive-class-suffix
10
+ export class ValueAccessor implements ControlValueAccessor {
11
+ private onChange: (value: any) => void = () => {};
12
+ private onTouched: () => void = () => {};
13
+ protected lastValue: any;
14
+
15
+ constructor(protected el: ElementRef) {}
16
+
17
+ writeValue(value: any) {
18
+ this.el.nativeElement.value = this.lastValue = value == null ? '' : value;
19
+ }
20
+
21
+ handleChangeEvent(value: any) {
22
+ if (value !== this.lastValue) {
23
+ this.lastValue = value;
24
+ this.onChange(value);
25
+ }
26
+ }
27
+
28
+ @HostListener('focusout')
29
+ _handleBlurEvent() {
30
+ this.onTouched();
31
+ }
32
+
33
+ registerOnChange(fn: (value: any) => void) {
34
+ this.onChange = fn;
35
+ }
36
+ registerOnTouched(fn: () => void) {
37
+ this.onTouched = fn;
38
+ }
39
+
40
+ setDisabledState(disabled: boolean) {
41
+ this.el.nativeElement.disabled = disabled;
42
+ }
43
+ }
44
+
45
+ @Directive({
46
+ selector: "duet-input:not([type=number]), duet-textarea, duet-date-picker",
47
+ host: {
48
+ "(duetChange)": "handleChangeEvent($event.target.value)"
49
+ },
50
+ standalone: true,
51
+ providers: [
52
+ {
53
+ provide: NG_VALUE_ACCESSOR,
54
+ useExisting: TextValueAccessorDirective,
55
+ multi: true
56
+ }
57
+ ]
58
+ })
59
+ export class TextValueAccessorDirective extends ValueAccessor {
60
+ constructor(el: ElementRef) {
61
+ super(el);
62
+ }
63
+ }
64
+
65
+ @Directive({
66
+ /* tslint:disable-next-line:directive-selector */
67
+ selector: "duet-range-slider, duet-select, duet-radio-group, duet-choice-group",
68
+ host: {
69
+ "(duetChange)": "handleChangeEvent($event.target.value)"
70
+ },
71
+ standalone: true,
72
+ providers: [
73
+ {
74
+ provide: NG_VALUE_ACCESSOR,
75
+ useExisting: SelectValueAccessorDirective,
76
+ multi: true
77
+ }
78
+ ]
79
+ })
80
+ export class SelectValueAccessorDirective extends ValueAccessor {
81
+ constructor(el: ElementRef) {
82
+ super(el);
83
+ }
84
+ }
85
+
86
+ @Directive({
87
+ /* tslint:disable-next-line:directive-selector */
88
+ selector: 'duet-radio, duet-choice[type=radio]',
89
+ host: {
90
+ '(duetSelect)': 'handleChangeEvent($event.target.checked)'
91
+ },
92
+ standalone: true,
93
+ providers: [
94
+ {
95
+ provide: NG_VALUE_ACCESSOR,
96
+ useExisting: RadioValueAccessorDirective,
97
+ multi: true
98
+ }
99
+ ]
100
+ })
101
+ export class RadioValueAccessorDirective extends ValueAccessor {
102
+ constructor(el: ElementRef) {
103
+ super(el);
104
+ }
105
+ }
106
+
107
+ @Directive({
108
+ /* tslint:disable-next-line:directive-selector */
109
+ selector: "duet-input[type=number], duet-number-input",
110
+ host: {
111
+ "(duetChange)": "handleChangeEvent($event.target.value)"
112
+ },
113
+ standalone: true,
114
+ providers: [
115
+ {
116
+ provide: NG_VALUE_ACCESSOR,
117
+ useExisting: NumericValueAccessorDirective,
118
+ multi: true
119
+ }
120
+ ]
121
+ })
122
+ export class NumericValueAccessorDirective extends ValueAccessor {
123
+ constructor(el: ElementRef) {
124
+ super(el);
125
+ }
126
+ registerOnChange(fn: (_: number | null) => void) {
127
+ super.registerOnChange(value => {
128
+ fn(value === '' ? null : parseFloat(value));
129
+ });
130
+ }
131
+ }
132
+
133
+ @Directive({
134
+ /* tslint:disable-next-line:directive-selector */
135
+ selector: "duet-checkbox, duet-toggle, duet-choice[type=checkbox]",
136
+ host: {
137
+ "(duetChange)": "handleChangeEvent($event.target.checked)"
138
+ },
139
+ standalone: true,
140
+ providers: [
141
+ {
142
+ provide: NG_VALUE_ACCESSOR,
143
+ useExisting: BooleanValueAccessorDirective,
144
+ multi: true
145
+ }
146
+ ]
147
+ })
148
+ export class BooleanValueAccessorDirective extends ValueAccessor {
149
+ @Output() duetChange = new EventEmitter<CustomEvent<any>>()
150
+ constructor(el: ElementRef) {
151
+ super(el);
152
+ }
153
+ writeValue(value: any) {
154
+ this.el.nativeElement.checked = this.lastValue = value == null ? false : value;
155
+ }
156
+ }
@@ -0,0 +1,3 @@
1
+ export const environment = {
2
+ production: true
3
+ }
@@ -0,0 +1,16 @@
1
+ // This file can be replaced during build by using the `fileReplacements` array.
2
+ // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
3
+ // The list of file replacements can be found in `angular.json`.
4
+
5
+ export const environment = {
6
+ production: false
7
+ }
8
+
9
+ /*
10
+ * For easier debugging in development mode, you can import the following file
11
+ * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12
+ *
13
+ * This import should be commented out in production mode because it will have a negative impact
14
+ * on performance if an error is thrown.
15
+ */
16
+ // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="fi" class="duet-sticky-footer duet-bg-gradient">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <base href="/" />
6
+ <title>LähiTapiola</title>
7
+ <meta name="author" content="LähiTapiola" />
8
+ <meta name="viewport" content="width=device-width,initial-scale=1.0" />
9
+ <meta name="format-detection" content="telephone=no" />
10
+ <meta name="robots" content="noindex,nofollow" />
11
+ <link rel="apple-touch-icon" href="assets/img/apple-touch-icon-180x180.png" />
12
+ <link rel="manifest" href="manifest.json" />
13
+ <link
14
+ rel="stylesheet"
15
+ href="https://cdn.duetds.com/api/fonts/1.3.12/lib/localtapiola.css"
16
+ integrity="sha384-5JYmtSD7nykpUvSmTW1CHMoBDkBZUpUmG0vuh+NUVtZag3F75Kr7+/JU3J7JV6Wq"
17
+ crossorigin="anonymous"
18
+ />
19
+ <link rel="icon" type="image/x-icon" href="favicon.ico" />
20
+ </head>
21
+ <body>
22
+ <app-root class="duet-sticky-body"></app-root>
23
+ </body>
24
+ </html>
@@ -0,0 +1,35 @@
1
+ import { enableProdMode, NgZone } from "@angular/core"
2
+ import { applyPolyfills, defineCustomElements } from '@duetds/components/lib/loader'
3
+
4
+ import { environment } from "./environments/environment"
5
+ import { createApplication } from "@angular/platform-browser"
6
+ import { AppComponent } from "./app/app.component"
7
+ import { PreloadAllModules, provideRouter, withDebugTracing, withPreloading } from "@angular/router"
8
+ import { routes } from "./app/app-routing.module"
9
+
10
+ (async () => {
11
+
12
+ const app = await createApplication({
13
+ providers: [
14
+ provideRouter(routes,
15
+ withPreloading(PreloadAllModules),
16
+ withDebugTracing(),
17
+ ),
18
+ ],
19
+ });
20
+
21
+ if (environment.production) {
22
+ enableProdMode()
23
+ }
24
+
25
+ // Register Duet’s custom elements
26
+ applyPolyfills().then(() => {
27
+ defineCustomElements(window)
28
+ })
29
+
30
+ app.injector.get(NgZone).run(() => {
31
+ app.bootstrap(AppComponent);
32
+ });
33
+
34
+ })();
35
+
@@ -0,0 +1,19 @@
1
+ {
2
+ "icons": [
3
+ {
4
+ "src": "assets/img/apple-touch-icon-180x180.png",
5
+ "sizes": "180x180",
6
+ "type": "image/png"
7
+ },
8
+ {
9
+ "src": "assets/img/android-chrome-192x192.png",
10
+ "sizes": "192x192",
11
+ "type": "image/png"
12
+ },
13
+ {
14
+ "src": "assets/img/splash-screen-icon-512x512.png",
15
+ "sizes": "512x512",
16
+ "type": "image/png"
17
+ }
18
+ ]
19
+ }