• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cnr-ibba / SMARTER-frontend / 9712764930

28 Jun 2024 12:27PM CUT coverage: 69.463%. Remained the same
9712764930

Pull #33

github

web-flow
Merge 5dd1263b0 into abfc12e88
Pull Request #33: ⬆️ Bump ws and socket.io

108 of 192 branches covered (56.25%)

Branch coverage included in aggregate %.

422 of 571 relevant lines covered (73.91%)

4.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.28
/src/app/samples/samples.component.ts
1

2
import { Component, OnInit, AfterViewInit, ViewChild, OnDestroy } from '@angular/core';
3
import { AbstractControl, FormControl, FormGroup, ValidationErrors } from '@angular/forms';
4

5
import { merge, of as observableOf, Subscription, Subject, Observable } from 'rxjs';
6
import { catchError, delay, map, startWith, switchMap } from 'rxjs/operators';
7
import { MatTableDataSource } from '@angular/material/table';
8
import { MatSort, SortDirection } from '@angular/material/sort';
9
import { MatPaginator } from '@angular/material/paginator';
10
import { ActivatedRoute, Router } from '@angular/router';
11

12
import { Sample, SamplesSearch, Country } from './samples.model';
13
import { SamplesService } from './samples.service';
14
import { UIService } from '../shared/ui.service';
15
import { PaginationParams } from '../shared/shared.model';
16

17
interface QueryParams extends PaginationParams {
18
  species?: string;
19
  smarter_id?: string;
20
  original_id?: string;
21
  dataset?: string;
22
  breed?: string;
23
  breed_code?: string;
24
  country?: string;
25
}
26

27
@Component({
28
  selector: 'app-samples',
29
  templateUrl: './samples.component.html',
30
  styleUrls: ['./samples.component.scss']
31
})
32
export class SamplesComponent implements OnInit, AfterViewInit, OnDestroy {
1✔
33
  displayedColumns = ['smarter_id', 'original_id', 'breed', 'breed_code', 'country', 'species'];
1✔
34
  dataSource = new MatTableDataSource<Sample>();
1✔
35
  private sortSubscription!: Subscription;
36
  private mergeSubscription!: Subscription;
37
  private speciesSubscription!: Subscription;
38
  private countryStateSubscription!: Subscription;
39
  private breedStateSubscription!: Subscription;
40

41
  @ViewChild(MatSort) sort!: MatSort;
42
  @ViewChild(MatPaginator) paginator!: MatPaginator;
43

44
  resultsLength = 0;
1✔
45
  isLoading = false;
1✔
46
  speciesControl!: FormControl;
47

48
  // control samples query parameters
49
  samplesForm!: FormGroup;
50
  formChanged = new Subject<void>();
1✔
51

52
  // track query params
53
  pageIndex = 0;
1✔
54
  pageSize = 10;
1✔
55
  sortActive = '';
1✔
56
  sortDirection: SortDirection = "desc";
1✔
57
  samplesSearch: SamplesSearch = {};
1✔
58

59
  // used by autocomplete forms
60
  filteredCountries!: Observable<string[]>;
61
  filteredBreeds!: Observable<string[]>;
62
  filteredCodes!: Observable<string[]>;
63

64
  constructor(
65
    private samplesService: SamplesService,
1✔
66
    private uiService: UIService,
1✔
67
    private route: ActivatedRoute,
1✔
68
    private router: Router
1✔
69
  ) {
70
    this.pageSize = this.samplesService.pageSize;
1✔
71
  }
72

73
  noWhiteSpaceValidator(control: AbstractControl): ValidationErrors | null {
74
    if (control.value) {
18!
75
      if (control.value.startsWith(" ") || control.value.endsWith(" ")) {
×
76
        return {"noWhiteSpaces": true};
×
77
      }
78
    }
79
    return null;
18✔
80
  }
81

82
  ngOnInit(): void {
83
    // get parameters from url
84
    this.route.queryParams.subscribe((params: QueryParams) => {
1✔
85
      // condition ? true_expression : false_expression
86
      params['page'] ? this.pageIndex = +params['page'] : null;
1!
87
      params['size'] ? this.pageSize = +params['size'] : null;
1!
88
      params['sort'] ? this.sortActive = params['sort'] : null;
1!
89
      params['order'] ? this.sortDirection = params['order'] : null;
1!
90
      params['species'] ? this.samplesService.selectedSpecie = params['species'] : null;
1!
91
      params['smarter_id'] ? this.samplesSearch.smarter_id = params['smarter_id'] : null;
1!
92
      params['original_id'] ? this.samplesSearch.original_id = params['original_id'] : null;
1!
93
      params['dataset'] ? this.samplesSearch.dataset = params['dataset'] : null;
1!
94
      params['breed'] ? this.samplesSearch.breed = params['breed'] : null;
1!
95
      params['breed_code'] ? this.samplesSearch.breed_code = params['breed_code'] : null;
1!
96
      params['country'] ? this.samplesSearch.country = params['country'] : null;
1!
97
    });
98

99
    this.speciesControl = new FormControl(this.samplesService.selectedSpecie);
1✔
100

101
    this.samplesForm = new FormGroup({
1✔
102
      original_id: new FormControl(null, [this.noWhiteSpaceValidator]),
103
      smarter_id: new FormControl(null, [this.noWhiteSpaceValidator]),
104
      dataset: new FormControl(null, [this.noWhiteSpaceValidator]),
105
      breed: new FormControl(null, [this.noWhiteSpaceValidator]),
106
      breed_code: new FormControl(null, [this.noWhiteSpaceValidator]),
107
      country: new FormControl(null, [this.noWhiteSpaceValidator]),
108
    });
109

110
    this.samplesForm.patchValue(this.samplesSearch);
1✔
111

112
    // get all countries and breeds
113
    this.samplesService.getCountries();
1✔
114
    this.samplesService.getBreeds();
1✔
115
  }
116

117
  ngAfterViewInit() {
118
    this.router.navigate(
1✔
119
      ["/samples"],
120
      {
121
        queryParams: this.getQueryParams()
122
      }
123
    );
124

125
    // If the user changes the sort order, reset back to the first page.
126
    this.sortSubscription = this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
1✔
127

128
    // reset pagination and forms
129
    this.speciesSubscription = this.speciesControl.valueChanges.subscribe(() => {
1✔
130
      // reset specie in services
131
      this.samplesService.selectedSpecie = this.speciesControl.value;
×
132

133
      // reload countries and breeds
134
      this.samplesService.getCountries();
×
135
      this.samplesService.getBreeds();
×
136

137
      // reset page stuff and navigation
138
      this.paginator.pageIndex = 0;
×
139
      this.samplesForm.reset();
×
140
      this.samplesSearch = this.samplesForm.value;
×
141
      this.router.navigate(
×
142
        ["/samples"],
143
        {
144
          queryParams: this.getQueryParams()
145
        }
146
      );
147
    });
148

149
    this.mergeSubscription = merge(
1✔
150
      this.sort.sortChange,
151
      this.paginator.page,
152
      this.speciesControl.valueChanges,
153
      this.formChanged
154
      ).pipe(
155
        startWith({}),
156
        // delay(0) is required to solve the ExpressionChangedAfterItHasBeenCheckedError:
157
        // Expression has changed after it was checked. See https://blog.angular-university.io/angular-debugging/
158
        delay(0),
159
        switchMap(() => {
160
          this.isLoading = true;
×
161

162
          // update values
163
          this.sortActive = this.sort.active;
×
164
          this.sortDirection = this.sort.direction;
×
165
          this.pageIndex = this.paginator.pageIndex;
×
166
          this.pageSize = this.paginator.pageSize;
×
167

168
          return this.samplesService.getSamples(
×
169
              this.sortActive,
170
              this.sortDirection,
171
              this.pageIndex,
172
              this.pageSize,
173
              this.samplesSearch)
174
            .pipe(catchError((error) => {
175
              console.log(error);
×
176
              this.uiService.showSnackbar("Error while fetching data. Please, try again later", "Dismiss");
×
177
              return observableOf(null)
×
178
            })
179
          );
180
        }),
181
        map(data => {
182
          this.router.navigate(
×
183
            ["/samples"],
184
            {
185
              queryParams: this.getQueryParams()
186
            }
187
          );
188

189
          // Flip flag to show that loading has finished.
190
          this.isLoading = false;
×
191

192
          if (data === null) {
×
193
            return [];
×
194
          }
195

196
          // Only refresh the result length if there is new data. In case of rate
197
          // limit errors, we do not want to reset the paginator to zero, as that
198
          // would prevent users from re-triggering requests.
199
          this.resultsLength = data.total;
×
200
          return data.items;
×
201
        })
202
      ).subscribe(data => this.dataSource.data = data);
×
203

204
    // subscribe to see when request are performed by the server
205
    this.countryStateSubscription = this.samplesService.countryStateChanged.subscribe(() => {
1✔
206
      this.filteredCountries = this.samplesForm.controls['country'].valueChanges.pipe(
×
207
        startWith(''),
208
        map(value => this._filterCountry(value || '')),
×
209
      );
210
    });
211

212
    this.breedStateSubscription = this.samplesService.breedStateChanged.subscribe(() => {
1✔
213
      this.filteredBreeds = this.samplesForm.controls['breed'].valueChanges.pipe(
×
214
        startWith(''),
215
        map(value => this._filterBreed(value || '')),
×
216
      );
217

218
      this.filteredCodes = this.samplesForm.controls['breed_code'].valueChanges.pipe(
×
219
        startWith(''),
220
        map(value => this._filterCode(value || '')),
×
221
      );
222
    });
223
  }
224

225
  onSubmit() {
226
    // copy form values into my private instance of SampleSearch
227
    this.samplesSearch = this.samplesForm.value;
×
228
    this.paginator.pageIndex = 0
×
229
    this.formChanged.next();
×
230
  }
231

232
  onReset(): void {
233
    this.samplesForm.reset();
×
234
    this.samplesSearch = this.samplesForm.value;
×
235
    this.paginator.pageIndex = 0;
×
236
    this.formChanged.next();
×
237
    this.router.navigate(
×
238
      ["/samples"],
239
      {
240
        queryParams: this.getQueryParams()
241
      }
242
    );
243
  }
244

245
  getQueryParams(): Object {
246
    let queryParams: QueryParams = {};
1✔
247

248
    // this value is always defined
249
    queryParams['species'] = this.samplesService.selectedSpecie;
1✔
250

251
    // condition ? true_expression : false_expression
252
    this.pageIndex ? queryParams['page'] = this.pageIndex : null;
1!
253
    this.sortActive ? queryParams['sort'] = this.sortActive : null;
1!
254
    this.sortDirection && this.sortActive ? queryParams['order'] = this.sortDirection : null;
1!
255
    this.samplesSearch.smarter_id ? queryParams['smarter_id'] = this.samplesSearch.smarter_id : null;
1!
256
    this.samplesSearch.original_id ? queryParams['original_id'] = this.samplesSearch.original_id : null;
1!
257
    this.samplesSearch.dataset ? queryParams['dataset'] = this.samplesSearch.dataset : null;
1!
258
    this.samplesSearch.breed ? queryParams['breed'] = this.samplesSearch.breed : null;
1!
259
    this.samplesSearch.breed_code ? queryParams['breed_code'] = this.samplesSearch.breed_code : null;
1!
260
    this.samplesSearch.country ? queryParams['country'] = this.samplesSearch.country : null;
1!
261

262
    return queryParams;
1✔
263
  }
264

265
  private _filterCountry(value: string): string[] {
266
    // console.log(this.samplesService.countries);
267
    const filterValue = value.toLowerCase();
×
268
    return this.samplesService.countries.filter(country => country.toLowerCase().includes(filterValue)).sort();
×
269
  }
270

271
  private _filterBreed(value: string): string[] {
272
    // console.log(this.samplesService.breeds);
273
    const filterValue = value.toLowerCase();
×
274
    return this.samplesService.breeds.filter(breed => breed.toLowerCase().includes(filterValue)).sort();
×
275
  }
276

277
  private _filterCode(value: string): string[] {
278
    // console.log(this.samplesService.breed_codes);
279
    const filterValue = value.toLowerCase();
×
280
    return this.samplesService.breed_codes.filter(code => code.toLowerCase().includes(filterValue)).sort();
×
281
  }
282

283
  ngOnDestroy() {
284
    this.sortSubscription.unsubscribe();
1✔
285
    this.mergeSubscription.unsubscribe();
1✔
286
    this.speciesSubscription.unsubscribe();
1✔
287
    this.countryStateSubscription.unsubscribe();
1✔
288
    this.breedStateSubscription.unsubscribe();
1✔
289
  }
290

291
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc