@duetds/cli 4.0.51 → 4.1.1

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 (109) hide show
  1. package/package.json +2 -2
  2. package/templates/angular/13.2.4/src/tests/playwright/playwright.test.ts-snapshots/angular-5-chromium-darwin.png +0 -0
  3. package/templates/angular/14.2.12/src/tests/playwright/playwright.test.ts-snapshots/angular-5-chromium-darwin.png +0 -0
  4. package/templates/angular/15.0.4/src/tests/playwright/playwright.test.ts-snapshots/angular-5-chromium-darwin.png +0 -0
  5. package/templates/angular/16.2.0/package.file +1 -1
  6. package/templates/angular/16.2.0/src/tests/playwright/playwright.test.ts-snapshots/angular-5-chromium-darwin.png +0 -0
  7. package/templates/angular/17.0.0/package.file +2 -2
  8. package/templates/angular/17.0.0/src/app/app.module.ts +10 -1
  9. package/templates/angular/17.0.0/src/app/investment-amount/investment-amount.component.html +2 -0
  10. package/templates/angular/17.0.0/src/app/investment-amount/investment-amount.component.ts +2 -12
  11. package/templates/angular/17.0.0/src/app/investment-origin/investment-origin.component.html +8 -8
  12. package/templates/angular/17.0.0/src/app/investment-origin/investment-origin.component.ts +2 -21
  13. package/templates/angular/17.0.0/src/app/value-accessors.ts +147 -0
  14. package/templates/angular/17.0.0/src/tests/playwright/playwright.test.ts-snapshots/angular-5-chromium-darwin.png +0 -0
  15. package/templates/angular/{12.2.16 → 18.1.0}/.eslintrc.json +3 -2
  16. package/templates/angular/{12.2.16 → 18.1.0}/angular.json +16 -0
  17. package/templates/angular/18.1.0/package.file +59 -0
  18. package/templates/angular/{12.2.16 → 18.1.0}/src/app/app.component.html +1 -1
  19. package/templates/angular/{12.2.16 → 18.1.0}/src/app/app.module.ts +14 -5
  20. package/templates/angular/{12.2.16 → 18.1.0}/src/app/index-page/index-page.component.ts +1 -1
  21. package/templates/angular/{12.2.16 → 18.1.0}/src/app/investment-amount/investment-amount.component.ts +1 -1
  22. package/templates/angular/{12.2.16 → 18.1.0}/src/app/investment-origin/investment-origin.component.html +1 -1
  23. package/templates/angular/{12.2.16 → 18.1.0}/src/app/investment-origin/investment-origin.component.ts +2 -1
  24. package/templates/angular/18.1.0/src/app/value-accessors.ts +147 -0
  25. package/templates/angular/{12.2.16 → 18.1.0}/src/main.ts +6 -0
  26. package/templates/angular/{12.2.16 → 18.1.0}/src/polyfills.ts +1 -1
  27. package/templates/angular/{12.2.16 → 18.1.0}/src/styles.scss +2 -2
  28. package/templates/angular/18.1.0/src/tests/playwright/playwright.test.ts-snapshots/angular-5-chromium-darwin.png +0 -0
  29. package/templates/angular/18.1.0/tsconfig.json +9 -0
  30. package/templates/react/16.14.0/package.file +1 -1
  31. package/templates/react/19rc/LICENSE.md +29 -0
  32. package/templates/react/19rc/README.md +54 -0
  33. package/templates/react/19rc/package-lock.json +10713 -0
  34. package/templates/react/19rc/package.file +39 -0
  35. package/templates/react/19rc/playwright.config.mjs +26 -0
  36. package/templates/react/19rc/public/assets/img/android-chrome-192x192.png +0 -0
  37. package/templates/react/19rc/public/assets/img/apple-touch-icon-180x180.png +0 -0
  38. package/templates/react/19rc/public/assets/img/splash-screen-icon-512x512.png +0 -0
  39. package/templates/react/19rc/public/favicon.ico +0 -0
  40. package/templates/react/19rc/public/index.html +48 -0
  41. package/templates/react/19rc/public/manifest.json +19 -0
  42. package/templates/react/19rc/src/App.js +140 -0
  43. package/templates/react/19rc/src/components/Footer.js +23 -0
  44. package/templates/react/19rc/src/components/Header.js +6 -0
  45. package/templates/react/19rc/src/components/InvestmentAmount.js +129 -0
  46. package/templates/react/19rc/src/components/InvestmentOrigin.js +88 -0
  47. package/templates/react/19rc/src/components/Summary.js +87 -0
  48. package/templates/react/19rc/src/index.js +17 -0
  49. package/templates/react/19rc/src/index.scss +2 -0
  50. package/templates/react/19rc/src/serviceWorker.js +141 -0
  51. package/templates/react/19rc/src/tests/playwright/playwright.test.mjs +54 -0
  52. package/templates/react/19rc/src/tests/playwright/playwright.test.mjs-snapshots/app-1-chromium-darwin.png +0 -0
  53. package/templates/react/19rc/src/tests/playwright/playwright.test.mjs-snapshots/app-2-chromium-darwin.png +0 -0
  54. package/templates/react/19rc/src/tests/playwright/playwright.test.mjs-snapshots/app-3-chromium-darwin.png +0 -0
  55. package/templates/react/19rc/src/tests/playwright/playwright.test.mjs-snapshots/app-4-chromium-darwin.png +0 -0
  56. package/templates/{angular/12.2.16/src/tests/playwright/playwright.test.ts-snapshots/angular-5-chromium-darwin.png → react/19rc/src/tests/playwright/playwright.test.mjs-snapshots/app-5-chromium-darwin.png} +0 -0
  57. package/templates/react/19rc/src/tests/playwright/playwright.test.mjs-snapshots/code-chromium-darwin.json +16 -0
  58. package/templates/angular/12.2.16/package.file +0 -58
  59. package/templates/angular/12.2.16/tsconfig.json +0 -8
  60. package/templates/angular/12.2.16/tslint.json +0 -92
  61. /package/templates/angular/{12.2.16 → 18.1.0}/.browserlistrc +0 -0
  62. /package/templates/angular/{12.2.16 → 18.1.0}/.depcheckrc +0 -0
  63. /package/templates/angular/{12.2.16 → 18.1.0}/.editorconfig +0 -0
  64. /package/templates/angular/{12.2.16 → 18.1.0}/.prettierignore +0 -0
  65. /package/templates/angular/{12.2.16 → 18.1.0}/.prettierrc +0 -0
  66. /package/templates/angular/{12.2.16 → 18.1.0}/LICENSE.md +0 -0
  67. /package/templates/angular/{12.2.16 → 18.1.0}/README.md +0 -0
  68. /package/templates/angular/{12.2.16 → 18.1.0}/config/jest.base.ts +0 -0
  69. /package/templates/angular/{12.2.16 → 18.1.0}/config/jest.setup.ts +0 -0
  70. /package/templates/angular/{12.2.16 → 18.1.0}/playwright.config.ts +0 -0
  71. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/agreement.model.ts +0 -0
  72. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/app-routing.module.ts +0 -0
  73. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/app.component.scss +0 -0
  74. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/app.component.ts +0 -0
  75. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/currency-formatter.service.ts +0 -0
  76. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/footer/footer.component.html +0 -0
  77. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/footer/footer.component.scss +0 -0
  78. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/footer/footer.component.ts +0 -0
  79. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/header/header.component.html +0 -0
  80. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/header/header.component.scss +0 -0
  81. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/header/header.component.ts +0 -0
  82. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/index-page/index-page.component.html +0 -0
  83. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/index-page/index-page.component.scss +0 -0
  84. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/investment-amount/investment-amount.component.html +0 -0
  85. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/investment-amount/investment-amount.component.scss +0 -0
  86. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/investment-origin/investment-origin.component.scss +0 -0
  87. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/summary/summary.component.html +0 -0
  88. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/summary/summary.component.scss +0 -0
  89. /package/templates/angular/{12.2.16 → 18.1.0}/src/app/summary/summary.component.ts +0 -0
  90. /package/templates/angular/{12.2.16 → 18.1.0}/src/assets/.gitkeep +0 -0
  91. /package/templates/angular/{12.2.16 → 18.1.0}/src/assets/img/android-chrome-192x192.png +0 -0
  92. /package/templates/angular/{12.2.16 → 18.1.0}/src/assets/img/apple-touch-icon-180x180.png +0 -0
  93. /package/templates/angular/{12.2.16 → 18.1.0}/src/assets/img/splash-screen-icon-512x512.png +0 -0
  94. /package/templates/angular/{12.2.16 → 18.1.0}/src/environments/environment.prod.ts +0 -0
  95. /package/templates/angular/{12.2.16 → 18.1.0}/src/environments/environment.ts +0 -0
  96. /package/templates/angular/{12.2.16 → 18.1.0}/src/favicon.ico +0 -0
  97. /package/templates/angular/{12.2.16 → 18.1.0}/src/index.html +0 -0
  98. /package/templates/angular/{12.2.16 → 18.1.0}/src/manifest.json +0 -0
  99. /package/templates/angular/{12.2.16 → 18.1.0}/src/tests/app.test.ts +0 -0
  100. /package/templates/angular/{12.2.16 → 18.1.0}/src/tests/playwright/playwright.test.ts +0 -0
  101. /package/templates/angular/{12.2.16 → 18.1.0}/src/tests/playwright/playwright.test.ts-snapshots/angular-1-chromium-darwin.png +0 -0
  102. /package/templates/angular/{12.2.16 → 18.1.0}/src/tests/playwright/playwright.test.ts-snapshots/angular-2-chromium-darwin.png +0 -0
  103. /package/templates/angular/{12.2.16 → 18.1.0}/src/tests/playwright/playwright.test.ts-snapshots/angular-3-chromium-darwin.png +0 -0
  104. /package/templates/angular/{12.2.16 → 18.1.0}/src/tests/playwright/playwright.test.ts-snapshots/angular-4-chromium-darwin.png +0 -0
  105. /package/templates/angular/{12.2.16 → 18.1.0}/src/tests/playwright/playwright.test.ts-snapshots/code-chromium-darwin.json +0 -0
  106. /package/templates/angular/{12.2.16 → 18.1.0}/src/utils/string.utils.ts +0 -0
  107. /package/templates/angular/{12.2.16 → 18.1.0}/tsconfig.app.json +0 -0
  108. /package/templates/angular/{12.2.16 → 18.1.0}/tsconfig.base.json +0 -0
  109. /package/templates/angular/{12.2.16 → 18.1.0}/tsconfig.spec.json +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duetds/cli",
3
- "version": "4.0.51",
3
+ "version": "4.1.1",
4
4
  "description": "This package includes Duet Design System CLI.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "LocalTapiola Services Ltd <duetdesignsystem@lahitapiola.fi>",
@@ -33,5 +33,5 @@
33
33
  "publishConfig": {
34
34
  "access": "public"
35
35
  },
36
- "gitHead": "cb52b4d9fcf70d2289749fa3087b39ac1bb75df3"
36
+ "gitHead": "45d1ef810b411d30818cdfdd5ae84674f8027641"
37
37
  }
@@ -54,6 +54,6 @@
54
54
  "eslint-plugin-unused-imports": "2.0.0",
55
55
  "jest": "^29.5.0",
56
56
  "ts-node": "10.9.0",
57
- "typescript": "^5.1.0"
57
+ "typescript": "5.1.3"
58
58
  }
59
59
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "duet-angular-template",
3
- "version": "16.2.0",
3
+ "version": "17.0.0",
4
4
  "scripts": {
5
5
  "ng": "ng",
6
6
  "start": "ng lint; npm run serve",
@@ -54,6 +54,6 @@
54
54
  "eslint-plugin-unused-imports": "3.0.0",
55
55
  "jest": "^29.5.0",
56
56
  "ts-node": "10.9.0",
57
- "typescript": "^5.2.2"
57
+ "typescript": "5.2.2"
58
58
  }
59
59
  }
@@ -10,9 +10,18 @@ import { FooterComponent } from "./footer/footer.component"
10
10
  import { InvestmentAmountComponent } from './investment-amount/investment-amount.component';
11
11
  import { InvestmentOriginComponent } from './investment-origin/investment-origin.component';
12
12
  import { SummaryComponent } from './summary/summary.component'
13
+ import {
14
+ BooleanValueAccessorDirective, NumericValueAccessorDirective,
15
+ SelectValueAccessorDirective, TextValueAccessorDirective
16
+ } from "./value-accessors"
13
17
 
14
18
  @NgModule({
15
- declarations: [AppComponent, IndexPageComponent, HeaderComponent, FooterComponent, InvestmentAmountComponent, InvestmentOriginComponent, SummaryComponent],
19
+ declarations: [
20
+ AppComponent, IndexPageComponent, HeaderComponent, FooterComponent,
21
+ InvestmentAmountComponent, InvestmentOriginComponent, SummaryComponent,
22
+ BooleanValueAccessorDirective, NumericValueAccessorDirective,
23
+ SelectValueAccessorDirective, TextValueAccessorDirective,
24
+ ],
16
25
  imports: [BrowserModule, FormsModule, ReactiveFormsModule, AppRoutingModule],
17
26
  providers: [],
18
27
  bootstrap: [AppComponent],
@@ -1,5 +1,6 @@
1
1
  <ng-container [formGroup]="form">
2
2
  <duet-select
3
+ formControlName="agreement"
3
4
  expand
4
5
  label="Valitse sopimus"
5
6
  placeholder="Valitse…"
@@ -74,6 +75,7 @@
74
75
  <duet-spacer></duet-spacer>
75
76
  <duet-card variation="plain" background="gray-lighter">
76
77
  <duet-input
78
+ formControlName="additionalInvestment"
77
79
  numeric-keyboard
78
80
  expand
79
81
  label="Syötä summa"
@@ -12,19 +12,9 @@ export class InvestmentAmountComponent implements OnInit {
12
12
  @Input() agreements: Record<number, Agreement>
13
13
  @Input() form: FormGroup
14
14
 
15
- constructor(public formatter: CurrencyFormatterService, private myElement: ElementRef) {}
15
+ constructor(public formatter: CurrencyFormatterService) {}
16
16
 
17
- ngOnInit(): void {
18
- const element = this.myElement.nativeElement as Element
19
- const select = element.querySelector("duet-select") as HTMLDuetSelectElement
20
- const input = element.querySelector("duet-input") as HTMLDuetInputElement
21
- select.addEventListener("duetChange", (e: CustomEvent<{value: number}>) => {
22
- this.form.controls['agreement'].setValue(e.detail.value)
23
- })
24
- input.addEventListener("duetChange", (e: CustomEvent<{value: string}>) => {
25
- this.form.controls['additionalInvestment'].setValue(Number(e.detail.value))
26
- })
27
- }
17
+ ngOnInit(): void {}
28
18
 
29
19
  get selectedAgreement() {
30
20
  return this.agreements[this.form.value.agreement]
@@ -1,12 +1,12 @@
1
1
  <ng-container [formGroup]="form">
2
- <duet-checkbox label="Valinta 1"></duet-checkbox>
3
- <duet-checkbox label="Valinta 2"></duet-checkbox>
4
- <duet-checkbox label="Valinta 3"></duet-checkbox>
5
- <duet-checkbox label="Valinta 4"></duet-checkbox>
6
- <duet-checkbox label="Valinta 5"></duet-checkbox>
7
- <duet-checkbox label="Valinta 6"></duet-checkbox>
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
8
  <duet-checkbox label="Muu, mikä?" (duetChange)="handleExtrasChange($event)"></duet-checkbox>
9
9
  <div *ngIf="hasExtras">
10
- <duet-input label="Kerro sijoitettavien varojen muu alkuperä" label-hidden (duetChange)="handleExtrasValueChange($event)"></duet-input>
10
+ <duet-input formControlName="extras" label="Kerro sijoitettavien varojen muu alkuperä" label-hidden></duet-input>
11
11
  </div>
12
- </ng-container>
12
+ </ng-container>
@@ -11,23 +11,9 @@ export class InvestmentOriginComponent implements OnInit {
11
11
  hasExtras = false
12
12
  extrasValue = ""
13
13
 
14
- constructor(private myElement: ElementRef) {}
14
+ constructor() {}
15
15
 
16
- ngOnInit(): void {
17
- const element = this.myElement.nativeElement as Element
18
- function listenCheckboxEvents(form: FormGroup, selector: string, control: string) {
19
- const checkbox = element.querySelector(`duet-checkbox[label='${selector}']`) as HTMLDuetSelectElement
20
- checkbox.addEventListener("duetChange", (e: CustomEvent<{checked: boolean}>) => {
21
- form.controls[control].setValue(e.detail.checked)
22
- })
23
- }
24
- listenCheckboxEvents(this.form, 'Valinta 1', 'salary')
25
- listenCheckboxEvents(this.form, 'Valinta 2', 'gift')
26
- listenCheckboxEvents(this.form, 'Valinta 3', 'heritage')
27
- listenCheckboxEvents(this.form, 'Valinta 4', 'entrepreneurialIncome')
28
- listenCheckboxEvents(this.form, 'Valinta 5', 'assets')
29
- listenCheckboxEvents(this.form, 'Valinta 6', 'otherIncome')
30
- }
16
+ ngOnInit(): void {}
31
17
 
32
18
  handleExtrasChange(event: CustomEvent) {
33
19
  this.hasExtras = event.detail.checked
@@ -36,9 +22,4 @@ export class InvestmentOriginComponent implements OnInit {
36
22
  this.form.get("extras").setValue(null)
37
23
  }
38
24
  }
39
-
40
- handleExtrasValueChange(event: CustomEvent) {
41
- this.extrasValue = event.detail.value
42
- this.form.get("extras").setValue(this.extrasValue)
43
- }
44
25
  }
@@ -0,0 +1,147 @@
1
+ /* eslint-disable @angular-eslint/directive-selector, @angular-eslint/no-host-metadata-property */
2
+
3
+ import { Directive, ElementRef, HostListener } from "@angular/core";
4
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
5
+
6
+ @Directive({})
7
+ export class ValueAccessor implements ControlValueAccessor {
8
+ private onChange: (value: any) => void = () => {};
9
+ private onTouched: () => void = () => {};
10
+ protected lastValue: any;
11
+
12
+ constructor(protected el: ElementRef) {}
13
+
14
+ writeValue(value: any) {
15
+ this.el.nativeElement.value = this.lastValue = value == null ? '' : value;
16
+ }
17
+
18
+ handleChangeEvent(value: any) {
19
+ if (value !== this.lastValue) {
20
+ this.lastValue = value;
21
+ this.onChange(value);
22
+ }
23
+ }
24
+
25
+ @HostListener('focusout')
26
+ _handleBlurEvent() {
27
+ this.onTouched();
28
+ }
29
+
30
+ registerOnChange(fn: (value: any) => void) {
31
+ this.onChange = fn;
32
+ }
33
+ registerOnTouched(fn: () => void) {
34
+ this.onTouched = fn;
35
+ }
36
+
37
+ setDisabledState(disabled: boolean) {
38
+ this.el.nativeElement.disabled = disabled;
39
+ }
40
+ }
41
+
42
+ @Directive({
43
+ selector: 'duet-input:not([type=number]), duet-textarea, duet-date-picker',
44
+ host: {
45
+ '(duetChange)': 'handleChangeEvent($event.target.value)'
46
+ },
47
+ providers: [
48
+ {
49
+ provide: NG_VALUE_ACCESSOR,
50
+ useExisting: TextValueAccessorDirective,
51
+ multi: true
52
+ }
53
+ ]
54
+ })
55
+ export class TextValueAccessorDirective extends ValueAccessor {
56
+ constructor(el: ElementRef) {
57
+ super(el);
58
+ }
59
+ }
60
+
61
+ @Directive({
62
+ /* tslint:disable-next-line:directive-selector */
63
+ selector: 'duet-range-slider, duet-select, duet-radio-group, duet-choice-group',
64
+ host: {
65
+ '(duetChange)': 'handleChangeEvent($event.target.value)'
66
+ },
67
+ providers: [
68
+ {
69
+ provide: NG_VALUE_ACCESSOR,
70
+ useExisting: SelectValueAccessorDirective,
71
+ multi: true
72
+ }
73
+ ]
74
+ })
75
+ export class SelectValueAccessorDirective extends ValueAccessor {
76
+ constructor(el: ElementRef) {
77
+ super(el);
78
+ }
79
+ }
80
+
81
+ @Directive({
82
+ /* tslint:disable-next-line:directive-selector */
83
+ selector: 'duet-radio, duet-choice[type=radio]',
84
+ host: {
85
+ '(duetSelect)': 'handleChangeEvent($event.target.checked)'
86
+ },
87
+ providers: [
88
+ {
89
+ provide: NG_VALUE_ACCESSOR,
90
+ useExisting: RadioValueAccessorDirective,
91
+ multi: true
92
+ }
93
+ ]
94
+ })
95
+ export class RadioValueAccessorDirective extends ValueAccessor {
96
+ constructor(el: ElementRef) {
97
+ super(el);
98
+ }
99
+ }
100
+
101
+ @Directive({
102
+ /* tslint:disable-next-line:directive-selector */
103
+ selector: 'duet-input[type=number], duet-number-input',
104
+ host: {
105
+ '(duetChange)': 'handleChangeEvent($event.target.value)'
106
+ },
107
+ providers: [
108
+ {
109
+ provide: NG_VALUE_ACCESSOR,
110
+ useExisting: NumericValueAccessorDirective,
111
+ multi: true
112
+ }
113
+ ]
114
+ })
115
+ export class NumericValueAccessorDirective extends ValueAccessor {
116
+ constructor(el: ElementRef) {
117
+ super(el);
118
+ }
119
+ registerOnChange(fn: (_: number | null) => void) {
120
+ super.registerOnChange(value => {
121
+ fn(value === '' ? null : parseFloat(value));
122
+ });
123
+ }
124
+ }
125
+
126
+ @Directive({
127
+ /* tslint:disable-next-line:directive-selector */
128
+ selector: 'duet-checkbox, duet-toggle, duet-choice[type=checkbox]',
129
+ host: {
130
+ '(duetChange)': 'handleChangeEvent($event.target.checked)'
131
+ },
132
+ providers: [
133
+ {
134
+ provide: NG_VALUE_ACCESSOR,
135
+ useExisting: BooleanValueAccessorDirective,
136
+ multi: true
137
+ }
138
+ ]
139
+ })
140
+ export class BooleanValueAccessorDirective extends ValueAccessor {
141
+ constructor(el: ElementRef) {
142
+ super(el);
143
+ }
144
+ writeValue(value: any) {
145
+ this.el.nativeElement.checked = this.lastValue = value == null ? false : value;
146
+ }
147
+ }
@@ -9,8 +9,9 @@
9
9
  "*.ts"
10
10
  ],
11
11
  "parserOptions": {
12
+ "parser": "@typescript-eslint/parser",
12
13
  "project": [
13
- "tsconfig.json"
14
+ "./tsconfig.json"
14
15
  ],
15
16
  "createDefaultProgram": true
16
17
  },
@@ -48,4 +49,4 @@
48
49
  "rules": {}
49
50
  }
50
51
  ]
51
- }
52
+ }
@@ -2,6 +2,11 @@
2
2
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
3
  "version": 1,
4
4
  "newProjectRoot": "projects",
5
+ "cli": {
6
+ "cache": {
7
+ "enabled": false
8
+ }
9
+ },
5
10
  "projects": {
6
11
  "duet-angular-template": {
7
12
  "projectType": "application",
@@ -77,6 +82,14 @@
77
82
  "maximumError": "10kb"
78
83
  }
79
84
  ]
85
+ },
86
+ "development": {
87
+ "buildOptimizer": false,
88
+ "optimization": false,
89
+ "vendorChunk": true,
90
+ "extractLicenses": false,
91
+ "sourceMap": true,
92
+ "namedChunks": true
80
93
  }
81
94
  }
82
95
  },
@@ -89,6 +102,9 @@
89
102
  "configurations": {
90
103
  "production": {
91
104
  "browserTarget": "duet-angular-template:build:production"
105
+ },
106
+ "development": {
107
+ "browserTarget": "duet-angular-template:build:development"
92
108
  }
93
109
  }
94
110
  },
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "duet-angular-template",
3
+ "version": "18.1.0",
4
+ "scripts": {
5
+ "ng": "ng",
6
+ "start": "ng lint; npm run serve",
7
+ "serve": "ng serve --host=0.0.0.0 --poll 500 -c development",
8
+ "serve:daemon": "ng serve --host=0.0.0.0 --poll 500 &",
9
+ "build": "ng build",
10
+ "test": "ng test --watch=true",
11
+ "test:ci": "DEBUG=pw:webserver npx playwright test",
12
+ "lint": "ng lint"
13
+ },
14
+ "private": true,
15
+ "dependencies": {
16
+ "@angular/animations": "^18.1.0",
17
+ "@angular/common": "^18.1.0",
18
+ "@angular/compiler": "^18.1.0",
19
+ "@angular/core": "^18.1.0",
20
+ "@angular/forms": "^18.1.0",
21
+ "@angular/platform-browser": "^18.1.0",
22
+ "@angular/platform-browser-dynamic": "^18.1.0",
23
+ "@angular/router": "^18.1.0",
24
+ "@duetds/components": "latest",
25
+ "@duetds/css": "latest",
26
+ "@duetds/icons": "latest",
27
+ "@duetds/tokens": "latest",
28
+ "rxjs": "~7.8.0",
29
+ "tslib": "^2.3.0",
30
+ "zone.js": "~0.14.2"
31
+ },
32
+ "devDependencies": {
33
+ "@angular-builders/jest": "18.0.0",
34
+ "@angular-devkit/build-angular": "^18.1.0",
35
+ "@angular-eslint/builder": "^18.1.0",
36
+ "@angular-eslint/eslint-plugin": "^18.1.0",
37
+ "@angular-eslint/eslint-plugin-template": "^18.1.0",
38
+ "@angular-eslint/schematics": "^18.1.0",
39
+ "@angular-eslint/template-parser": "^18.1.0",
40
+ "@angular/cli": "^18.1.0",
41
+ "@angular/compiler-cli": "^18.1.0",
42
+ "@playwright/test": "1.25.0",
43
+ "@types/jest": "^29.5.0",
44
+ "@types/node": "18.11.9",
45
+ "@typescript-eslint/eslint-plugin": "6.13.2",
46
+ "@typescript-eslint/parser": "6.13.2",
47
+ "angular-eslint": "0.0.1-alpha.0",
48
+ "codelyzer": "6.0.2",
49
+ "eslint": "8.57.0",
50
+ "eslint-config-prettier": "8.5.0",
51
+ "eslint-plugin-import": "2.26.0",
52
+ "eslint-plugin-prefer-arrow": "1.2.3",
53
+ "eslint-plugin-prettier": "4.2.1",
54
+ "eslint-plugin-unused-imports": "3.0.0",
55
+ "jest": "^29.5.0",
56
+ "ts-node": "10.9.0",
57
+ "typescript": "5.5.4"
58
+ }
59
+ }
@@ -2,4 +2,4 @@
2
2
  <div class="duet-sticky-content">
3
3
  <router-outlet></router-outlet>
4
4
  </div>
5
- <app-footer></app-footer>
5
+ <app-footer></app-footer>
@@ -1,6 +1,5 @@
1
1
  import { BrowserModule } from "@angular/platform-browser"
2
- import { NgModule } from "@angular/core"
3
- import { DuetComponents } from "@duetds/angular"
2
+ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core"
4
3
 
5
4
  import { AppRoutingModule } from "./app-routing.module"
6
5
  import { AppComponent } from "./app.component"
@@ -11,11 +10,21 @@ import { FooterComponent } from "./footer/footer.component"
11
10
  import { InvestmentAmountComponent } from './investment-amount/investment-amount.component';
12
11
  import { InvestmentOriginComponent } from './investment-origin/investment-origin.component';
13
12
  import { SummaryComponent } from './summary/summary.component'
13
+ import {
14
+ BooleanValueAccessorDirective, NumericValueAccessorDirective,
15
+ SelectValueAccessorDirective, TextValueAccessorDirective
16
+ } from "./value-accessors"
14
17
 
15
18
  @NgModule({
16
- declarations: [AppComponent, IndexPageComponent, HeaderComponent, FooterComponent, InvestmentAmountComponent, InvestmentOriginComponent, SummaryComponent],
17
- imports: [BrowserModule, FormsModule, ReactiveFormsModule, DuetComponents, AppRoutingModule],
19
+ declarations: [
20
+ AppComponent, IndexPageComponent, HeaderComponent, FooterComponent,
21
+ InvestmentAmountComponent, InvestmentOriginComponent, SummaryComponent,
22
+ BooleanValueAccessorDirective, NumericValueAccessorDirective,
23
+ SelectValueAccessorDirective, TextValueAccessorDirective,
24
+ ],
25
+ imports: [BrowserModule, FormsModule, ReactiveFormsModule, AppRoutingModule],
18
26
  providers: [],
19
- bootstrap: [AppComponent]
27
+ bootstrap: [AppComponent],
28
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
20
29
  })
21
30
  export class AppModule {}
@@ -38,7 +38,7 @@ export class IndexPageComponent {
38
38
  }
39
39
 
40
40
  get selectedAgreement() {
41
- return this.agreements[this.form.value.investmentAmount.agreement]
41
+ return this.agreements[this.form.value.investmentAmount.agreement ?? 1]
42
42
  }
43
43
 
44
44
  formatNumber(value: number) {
@@ -1,4 +1,4 @@
1
- import { Component, OnInit, Input } from "@angular/core"
1
+ import { Component, OnInit, Input, ElementRef } from "@angular/core"
2
2
  import { FormGroup } from "@angular/forms"
3
3
  import { Agreement } from "../agreement.model"
4
4
  import { CurrencyFormatterService } from "../currency-formatter.service"
@@ -9,4 +9,4 @@
9
9
  <div *ngIf="hasExtras">
10
10
  <duet-input formControlName="extras" label="Kerro sijoitettavien varojen muu alkuperä" label-hidden></duet-input>
11
11
  </div>
12
- </ng-container>
12
+ </ng-container>
@@ -1,4 +1,4 @@
1
- import { Component, OnInit, Input } from "@angular/core"
1
+ import { Component, OnInit, Input, ElementRef } from "@angular/core"
2
2
  import { FormGroup } from "@angular/forms"
3
3
 
4
4
  @Component({
@@ -9,6 +9,7 @@ import { FormGroup } from "@angular/forms"
9
9
  export class InvestmentOriginComponent implements OnInit {
10
10
  @Input() form: FormGroup
11
11
  hasExtras = false
12
+ extrasValue = ""
12
13
 
13
14
  constructor() {}
14
15
 
@@ -0,0 +1,147 @@
1
+ /* eslint-disable @angular-eslint/directive-selector, @angular-eslint/no-host-metadata-property */
2
+
3
+ import { Directive, ElementRef, HostListener } from "@angular/core";
4
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
5
+
6
+ @Directive({})
7
+ export class ValueAccessor implements ControlValueAccessor {
8
+ private onChange: (value: any) => void = () => {};
9
+ private onTouched: () => void = () => {};
10
+ protected lastValue: any;
11
+
12
+ constructor(protected el: ElementRef) {}
13
+
14
+ writeValue(value: any) {
15
+ this.el.nativeElement.value = this.lastValue = value == null ? '' : value;
16
+ }
17
+
18
+ handleChangeEvent(value: any) {
19
+ if (value !== this.lastValue) {
20
+ this.lastValue = value;
21
+ this.onChange(value);
22
+ }
23
+ }
24
+
25
+ @HostListener('focusout')
26
+ _handleBlurEvent() {
27
+ this.onTouched();
28
+ }
29
+
30
+ registerOnChange(fn: (value: any) => void) {
31
+ this.onChange = fn;
32
+ }
33
+ registerOnTouched(fn: () => void) {
34
+ this.onTouched = fn;
35
+ }
36
+
37
+ setDisabledState(disabled: boolean) {
38
+ this.el.nativeElement.disabled = disabled;
39
+ }
40
+ }
41
+
42
+ @Directive({
43
+ selector: 'duet-input:not([type=number]), duet-textarea, duet-date-picker',
44
+ host: {
45
+ '(duetChange)': 'handleChangeEvent($event.target.value)'
46
+ },
47
+ providers: [
48
+ {
49
+ provide: NG_VALUE_ACCESSOR,
50
+ useExisting: TextValueAccessorDirective,
51
+ multi: true
52
+ }
53
+ ]
54
+ })
55
+ export class TextValueAccessorDirective extends ValueAccessor {
56
+ constructor(el: ElementRef) {
57
+ super(el);
58
+ }
59
+ }
60
+
61
+ @Directive({
62
+ /* tslint:disable-next-line:directive-selector */
63
+ selector: 'duet-range-slider, duet-select, duet-radio-group, duet-choice-group',
64
+ host: {
65
+ '(duetChange)': 'handleChangeEvent($event.target.value)'
66
+ },
67
+ providers: [
68
+ {
69
+ provide: NG_VALUE_ACCESSOR,
70
+ useExisting: SelectValueAccessorDirective,
71
+ multi: true
72
+ }
73
+ ]
74
+ })
75
+ export class SelectValueAccessorDirective extends ValueAccessor {
76
+ constructor(el: ElementRef) {
77
+ super(el);
78
+ }
79
+ }
80
+
81
+ @Directive({
82
+ /* tslint:disable-next-line:directive-selector */
83
+ selector: 'duet-radio, duet-choice[type=radio]',
84
+ host: {
85
+ '(duetSelect)': 'handleChangeEvent($event.target.checked)'
86
+ },
87
+ providers: [
88
+ {
89
+ provide: NG_VALUE_ACCESSOR,
90
+ useExisting: RadioValueAccessorDirective,
91
+ multi: true
92
+ }
93
+ ]
94
+ })
95
+ export class RadioValueAccessorDirective extends ValueAccessor {
96
+ constructor(el: ElementRef) {
97
+ super(el);
98
+ }
99
+ }
100
+
101
+ @Directive({
102
+ /* tslint:disable-next-line:directive-selector */
103
+ selector: 'duet-input[type=number], duet-number-input',
104
+ host: {
105
+ '(duetChange)': 'handleChangeEvent($event.target.value)'
106
+ },
107
+ providers: [
108
+ {
109
+ provide: NG_VALUE_ACCESSOR,
110
+ useExisting: NumericValueAccessorDirective,
111
+ multi: true
112
+ }
113
+ ]
114
+ })
115
+ export class NumericValueAccessorDirective extends ValueAccessor {
116
+ constructor(el: ElementRef) {
117
+ super(el);
118
+ }
119
+ registerOnChange(fn: (_: number | null) => void) {
120
+ super.registerOnChange(value => {
121
+ fn(value === '' ? null : parseFloat(value));
122
+ });
123
+ }
124
+ }
125
+
126
+ @Directive({
127
+ /* tslint:disable-next-line:directive-selector */
128
+ selector: 'duet-checkbox, duet-toggle, duet-choice[type=checkbox]',
129
+ host: {
130
+ '(duetChange)': 'handleChangeEvent($event.target.checked)'
131
+ },
132
+ providers: [
133
+ {
134
+ provide: NG_VALUE_ACCESSOR,
135
+ useExisting: BooleanValueAccessorDirective,
136
+ multi: true
137
+ }
138
+ ]
139
+ })
140
+ export class BooleanValueAccessorDirective extends ValueAccessor {
141
+ constructor(el: ElementRef) {
142
+ super(el);
143
+ }
144
+ writeValue(value: any) {
145
+ this.el.nativeElement.checked = this.lastValue = value == null ? false : value;
146
+ }
147
+ }