Skip to content

Commit ef2ea56

Browse files
committed
Settings: Progress definition: Cancel edit mode
1 parent 6e75fe3 commit ef2ea56

3 files changed

Lines changed: 112 additions & 83 deletions

File tree

src/app/pages/settings/settings.component.css

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,19 @@
22
margin-top: 1em;
33
}
44

5-
.progress-definition-row:hover {
6-
background-color: #f5f5f5;
5+
.mat-slider-horizontal {
6+
max-width: 100px;
7+
width: 100px;
8+
min-width: 80px;
79
}
810

9-
.progress-definitions-grid ::ng-deep .mat-form-field-wrapper {
10-
padding-bottom: 0;
11-
}
12-
1311
.date-format-container {
1412
display: flex;
1513
align-items: center;
1614
gap: 0.2em;
1715
width: 25em;
1816
}
1917

20-
.progress-definitions-section {
21-
margin-top: 1em;
22-
}
23-
2418

2519
.progress-definitions-grid {
2620
display: grid;
@@ -44,6 +38,15 @@
4438
text-align: right;
4539
padding-right: 0.5em;
4640
}
41+
input.progress-score::-webkit-outer-spin-button,
42+
input.progress-score::-webkit-inner-spin-button {
43+
-webkit-appearance: none;
44+
/* margin: 0; */
45+
}
46+
input.progress-score {
47+
-moz-appearance: textfield;
48+
/* text-align: right; */
49+
}
4750

4851
.grid-cell.action-buttons,
4952
.grid-cell.progress-definition {

src/app/pages/settings/settings.component.html

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ <h2>Progress Definitions</h2>
6161
</span>
6262
</div>
6363

64-
<div class="progress-definitions-grid">
64+
<div class="progress-definitions-grid" [formGroup]="progressDefinitionsForm">
6565
<ng-container
6666
*ngIf="
6767
editingProgressDefinitions;
@@ -82,48 +82,53 @@ <h2>Progress Definitions</h2>
8282
</ng-container>
8383
</ng-template>
8484
<ng-template #editProgress>
85-
<ng-container *ngFor="let definition of definitionsFormArray.controls; let i = index">
86-
<mat-form-field appearance="outline" class="grid-cell progress-key edit">
87-
<mat-label>Name</mat-label>
88-
<input matInput [value]="getFormGroupValue(definition, 'key')" />
89-
</mat-form-field>
85+
<ng-container formArrayName="definitions">
86+
<ng-container *ngFor="let definition of definitionsFormArray.controls; let i = index">
87+
<ng-container [formGroup]="getDefinitionGroup(i)">
88+
<mat-form-field appearance="outline" class="grid-cell progress-key edit">
89+
<mat-label>Name</mat-label>
90+
<input matInput formControlName="key" />
91+
</mat-form-field>
9092

91-
<mat-form-field appearance="outline" class="grid-cell progress-score edit">
92-
<mat-label>Score</mat-label>
93-
<input
94-
matInput
95-
class="progress-score"
96-
[value]="getFormGroupValue(definition, 'score')"
97-
[disabled]="getFormGroupValue(definition, 'mandatory')" />
98-
<span matSuffix>%</span>
99-
</mat-form-field>
93+
<mat-form-field appearance="outline" class="grid-cell progress-score edit">
94+
<mat-label>Score</mat-label>
95+
<input
96+
matInput
97+
type="number"
98+
class="progress-score"
99+
formControlName="score"
100+
[disabled]="getDefinitionGroup(i).get('mandatory')?.value" />
101+
<span matSuffix>%</span>
102+
</mat-form-field>
100103

101-
<mat-form-field appearance="outline" class="grid-cell progress-definition edit">
102-
<mat-label>Definition</mat-label>
103-
<textarea
104-
matInput
105-
cdkTextareaAutosize
106-
cdkAutosizeMinRows="1"
107-
cdkAutosizeMaxRows="5"
108-
[value]="getFormGroupValue(definition, 'definition')"></textarea>
109-
</mat-form-field>
104+
<mat-form-field appearance="outline" class="grid-cell progress-definition edit">
105+
<mat-label>Definition</mat-label>
106+
<textarea
107+
matInput
108+
formControlName="definition"
109+
cdkTextareaAutosize
110+
cdkAutosizeMinRows="1"
111+
cdkAutosizeMaxRows="5"></textarea>
112+
</mat-form-field>
110113

111-
<div class="grid-cell action-buttons edit">
112-
<mat-icon
113-
title="You cannot remove this definition"
114-
*ngIf="definition.get('mandatory')?.value"
115-
class="material-icons-outlined mandatory-icon"
116-
>lock</mat-icon
117-
>
118-
<button
119-
title="Delete"
120-
*ngIf="!definition.get('mandatory')?.value"
121-
mat-icon-button
122-
(click)="removeProgressDefinition(i)"
123-
title="Delete definition">
124-
<mat-icon class="material-icons-outlined">delete</mat-icon>
125-
</button>
126-
</div>
114+
<div class="grid-cell action-buttons edit">
115+
<mat-icon
116+
title="You cannot remove this definition"
117+
*ngIf="getDefinitionGroup(i).get('mandatory')?.value"
118+
class="material-icons-outlined mandatory-icon"
119+
>lock</mat-icon
120+
>
121+
<button
122+
title="Delete"
123+
*ngIf="!getDefinitionGroup(i).get('mandatory')?.value"
124+
mat-icon-button
125+
(click)="removeProgressDefinition(i)"
126+
title="Delete definition">
127+
<mat-icon class="material-icons-outlined">delete</mat-icon>
128+
</button>
129+
</div>
130+
</ng-container>
131+
</ng-container>
127132
</ng-container>
128133
</ng-template>
129134
</div>

src/app/pages/settings/settings.component.ts

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ import { FormBuilder, FormGroup, FormArray, AbstractControl } from '@angular/for
33
import { SettingsService } from '../../service/settings/settings.service';
44
import { LoaderService } from 'src/app/service/loader/data-loader.service';
55
import { DataStore } from 'src/app/model/data-store';
6-
import { MetaStore } from 'src/app/model/meta-store';
76
import { ProgressDefinitions } from 'src/app/model/types';
87
import {
98
DialogInfo,
109
ModalMessageComponent,
1110
} from 'src/app/component/modal-message/modal-message.component';
12-
import { dateStr } from 'src/app/util/util';
11+
import { dateStr, deepCopy } from 'src/app/util/util';
12+
import { MetaStore } from 'src/app/model/meta-store';
1313

1414
@Component({
1515
selector: 'app-settings',
1616
templateUrl: './settings.component.html',
1717
styleUrls: ['./settings.component.css'],
1818
})
1919
export class SettingsComponent implements OnInit {
20+
meta!: MetaStore;
2021
dataStoreMaxLevel!: number;
2122
selectedMaxLevel!: number;
2223
selectedMaxLevelCaption: String = '';
2324
progressDefinitionsForm!: FormGroup;
24-
progressDefinitions: ProgressDefinitions = {};
25+
tempProgressDefinitions: ProgressDefinitions = {};
2526
editingProgressDefinitions: boolean = false;
2627

2728
private BROWSER_LOCALE = 'BROWSER';
@@ -42,36 +43,16 @@ export class SettingsComponent implements OnInit {
4243
private settingsService: SettingsService,
4344
private formBuilder: FormBuilder,
4445
public modal: ModalMessageComponent
45-
) {
46-
this.initProgressDefinitionsForm();
47-
}
46+
) {}
4847

4948
ngOnInit(): void {
49+
this.initialize();
50+
this.initProgressDefinitionsForm();
5051
this.loader
5152
.load()
5253
.then((dataStore: DataStore) => {
53-
this.dataStoreMaxLevel = dataStore.getMaxLevel();
54-
this.selectedMaxLevel = this.settingsService.getMaxLevel() || this.dataStoreMaxLevel;
55-
this.updateMaxLevelCaption();
56-
57-
// Load progress definitions
58-
if (dataStore.meta) {
59-
this.progressDefinitions = dataStore.meta.progressDefinition;
60-
this.updateProgressDefinitionsForm();
61-
}
62-
63-
this.selectedDateFormat = this.settingsService.getDateFormat() || this.BROWSER_LOCALE;
64-
65-
// Init dates
66-
let date: Date = new Date();
67-
date = new Date(date.getFullYear(), 0, 31); // 31 Jan current year
68-
for (let format of this.dateFormats) {
69-
if (format.value === this.BROWSER_LOCALE) {
70-
format.label += ` (${dateStr(date)})`;
71-
} else {
72-
if (!format.label) format.label = dateStr(date, format.value);
73-
}
74-
}
54+
this.setYamlData(dataStore);
55+
this.updateProgressDefinitionsForm();
7556
})
7657
.catch(err => {
7758
this.modal.openDialog(new DialogInfo(err.message, 'An error occurred'));
@@ -81,6 +62,33 @@ export class SettingsComponent implements OnInit {
8162
});
8263
}
8364

65+
initialize(): void {
66+
this.selectedDateFormat = this.settingsService.getDateFormat() || this.BROWSER_LOCALE;
67+
68+
// Init dates
69+
let date: Date = new Date();
70+
date = new Date(date.getFullYear(), 0, 31); // 31 Jan current year
71+
for (let format of this.dateFormats) {
72+
if (format.value === this.BROWSER_LOCALE) {
73+
format.label += ` (${dateStr(date)})`;
74+
} else {
75+
if (!format.label) format.label = dateStr(date, format.value);
76+
}
77+
}
78+
}
79+
80+
setYamlData(dataStore: DataStore): void {
81+
this.dataStoreMaxLevel = dataStore.getMaxLevel();
82+
this.selectedMaxLevel = this.settingsService.getMaxLevel() || this.dataStoreMaxLevel;
83+
this.updateMaxLevelCaption();
84+
85+
// Load progress definitions
86+
if (dataStore.meta) {
87+
this.meta = dataStore.meta;
88+
this.tempProgressDefinitions = deepCopy(this.meta.progressDefinition);
89+
}
90+
}
91+
8492
onDateFormatChange(): void {
8593
let value: any = this.selectedDateFormat == 'null' ? null : this.selectedDateFormat;
8694
this.settingsService.setDateFormat(value);
@@ -97,6 +105,7 @@ export class SettingsComponent implements OnInit {
97105
this.updateMaxLevelCaption();
98106
}
99107

108+
// === Max Level ===
100109
updateMaxLevelCaption(): void {
101110
if (this.selectedMaxLevel == this.dataStoreMaxLevel) {
102111
this.selectedMaxLevelCaption = 'All maturity levels';
@@ -106,20 +115,26 @@ export class SettingsComponent implements OnInit {
106115
}
107116
}
108117

118+
// === Progress Definitions ===
109119
private initProgressDefinitionsForm(): void {
110120
this.progressDefinitionsForm = this.formBuilder.group({
111121
definitions: this.formBuilder.array([]),
112122
});
113123
}
114124

115-
get definitionsFormArray() {
125+
get definitionsFormArray(): FormArray {
116126
return this.progressDefinitionsForm.get('definitions') as FormArray;
117127
}
118128

129+
// Return the FormGroup for a specific index in the definitions FormArray.
130+
getDefinitionGroup(index: number): FormGroup {
131+
return this.definitionsFormArray.at(index) as FormGroup;
132+
}
133+
119134
private updateProgressDefinitionsForm(): void {
120135
this.definitionsFormArray.clear();
121136

122-
Object.entries(this.progressDefinitions).forEach(([key, progDef]) => {
137+
Object.entries(this.tempProgressDefinitions).forEach(([key, progDef]) => {
123138
this.definitionsFormArray.push(
124139
this.formBuilder.group({
125140
key: [key],
@@ -132,18 +147,22 @@ export class SettingsComponent implements OnInit {
132147
}
133148

134149
addProgressDefinition(): void {
135-
this.definitionsFormArray.push(
150+
let index: number = this.definitionsFormArray.length - 1;
151+
let score: number = this.getFormGroupValue(this.definitionsFormArray.at(index - 1), 'score');
152+
score = Math.trunc((score + 100) / 2);
153+
154+
this.definitionsFormArray.insert(
155+
index,
136156
this.formBuilder.group({
137157
key: [''],
138-
score: [0],
158+
score: [score],
139159
definition: [''],
140160
})
141161
);
142162
}
143163

144164
removeProgressDefinition(index: number): void {
145165
this.definitionsFormArray.removeAt(index);
146-
this.saveProgressDefinitions();
147166
}
148167

149168
saveProgressDefinitions(): void {
@@ -176,7 +195,9 @@ export class SettingsComponent implements OnInit {
176195
// this.updateProgressDefinitionsForm();
177196
// }
178197
// });
198+
this.tempProgressDefinitions = deepCopy(this.meta.progressDefinition);
179199
this.editingProgressDefinitions = false;
200+
this.updateProgressDefinitionsForm();
180201
}
181202

182203
toggleProgressDefinitionsEdit(): void {

0 commit comments

Comments
 (0)