1/**
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import { Component, OnInit, ViewChild } from '@angular/core';
17import { MatSnackBar, MatTableDataSource, PageEvent } from '@angular/material';
18
19import { AppService } from '../../appservice';
20import { Device } from '../../model/device';
21import { DeviceService } from './device.service';
22import { DeviceStatus, SchedulingStatus } from '../../shared/vtslab_status';
23import { FilterComponent } from '../../shared/filter/filter.component';
24import { FilterItem } from '../../model/filter_item';
25import { MenuBaseClass } from '../menu_base';
26
27
28/** Component that handles device menu. */
29@Component({
30  selector: 'app-device',
31  templateUrl: './device.component.html',
32  providers: [ DeviceService ],
33  styleUrls: ['./device.component.scss'],
34})
35export class DeviceComponent extends MenuBaseClass implements OnInit {
36  columnTitles = [
37    '_index',
38    'hostname',
39    'product',
40    'serial',
41    'status',
42    'scheduling_status',
43    'device_equipment',
44    'timestamp',
45  ];
46  dataSource = new MatTableDataSource<Device>();
47  pageEvent: PageEvent;
48  deviceStatusEnum = DeviceStatus;
49  schedulingStatusEnum = SchedulingStatus;
50  appliedFilters: FilterItem[];
51
52  sort = '';
53  sortDirection = '';
54
55  @ViewChild(FilterComponent) filterComponent: FilterComponent;
56
57  constructor(private deviceService: DeviceService,
58              appService: AppService,
59              snackBar: MatSnackBar) {
60    super(appService, snackBar);
61  }
62
63  ngOnInit(): void {
64    this.sort = 'hostname';
65    this.sortDirection = 'asc';
66
67    this.filterComponent.setSelectorList(Device);
68    this.getCount();
69    this.getDevices(this.pageSize, this.pageSize * this.pageIndex);
70  }
71
72  /** Gets a total count of devices. */
73  getCount(observer = this.getDefaultCountObservable()) {
74    const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
75    this.deviceService.getCount(filterJSON).subscribe(observer);
76  }
77
78  /** Gets devices.
79   * @param size A number, at most this many results will be returned.
80   * @param offset A Number of results to skip.
81   */
82  getDevices(size = 0, offset = 0) {
83    this.loading = true;
84    const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
85    this.deviceService.getDevices(size, offset, filterJSON, this.sort, this.sortDirection)
86      .subscribe(
87        (response) => {
88          this.loading = false;
89          if (this.count >= 0) {
90            let length = 0;
91            if (response.devices) {
92              length = response.devices.length;
93            }
94            const total = length + offset;
95            if (response.has_next) {
96              if (length !== this.pageSize) {
97                this.showSnackbar('Received unexpected number of entities.');
98              } else if (this.count <= total) {
99                this.getCount();
100              }
101            } else {
102              if (this.count !== total) {
103                if (length !== this.count) {
104                  this.getCount();
105                } else if (this.count > total) {
106                  const countObservable = this.getDefaultCountObservable([
107                    () => {
108                      this.pageIndex = Math.floor(this.count / this.pageSize);
109                      this.getDevices(this.pageSize, this.pageSize * this.pageIndex);
110                    }
111                  ]);
112                  this.getCount(countObservable);
113                }
114              }
115            }
116          }
117          this.dataSource.data = response.devices;
118        },
119        (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
120      );
121  }
122
123  /** Hooks a page event and handles properly. */
124  onPageEvent(event: PageEvent) {
125    this.pageSize = event.pageSize;
126    this.pageIndex = event.pageIndex;
127    this.getDevices(this.pageSize, this.pageSize * this.pageIndex);
128    return event;
129  }
130
131  /** Applies a filter and get entities with it. */
132  applyFilters(filters) {
133    this.pageIndex = 0;
134    this.appliedFilters = filters;
135    this.getCount();
136    this.getDevices(this.pageSize, this.pageSize * this.pageIndex);
137  }
138}
139