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 { Build } from '../../model/build';
21import { BuildService } from './build.service';
22import { FilterComponent } from '../../shared/filter/filter.component';
23import { FilterItem } from '../../model/filter_item';
24import { MenuBaseClass } from '../menu_base';
25
26
27/** Component that handles build menu. */
28@Component({
29  selector: 'app-build',
30  templateUrl: './build.component.html',
31  providers: [ BuildService ],
32  styleUrls: ['./build.component.scss'],
33})
34export class BuildComponent extends MenuBaseClass implements OnInit {
35  columnTitles = [
36    '_index',
37    'artifact_type',
38    'manifest_branch',
39    'build_id',
40    'build_target',
41    'build_type',
42    'signed'];
43  dataSource = new MatTableDataSource<Build>();
44  pageEvent: PageEvent;
45  appliedFilters: FilterItem[];
46
47  @ViewChild(FilterComponent) filterComponent: FilterComponent;
48
49  constructor(private buildService: BuildService,
50              appService: AppService,
51              snackBar: MatSnackBar) {
52    super(appService, snackBar);
53  }
54
55  ngOnInit(): void {
56    this.filterComponent.setSelectorList(Build);
57    this.getCount();
58    this.getBuilds(this.pageSize, this.pageSize * this.pageIndex);
59  }
60
61  /** Gets a total count of builds. */
62  getCount(observer = this.getDefaultCountObservable()) {
63    const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
64    this.buildService.getCount(filterJSON).subscribe(observer);
65  }
66
67  /** Gets builds.
68   * @param size A number, at most this many results will be returned.
69   * @param offset A Number of results to skip.
70   */
71  getBuilds(size = 0, offset = 0) {
72    this.loading = true;
73    const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
74    this.buildService.getBuilds(size, offset, filterJSON, '', '')
75      .subscribe(
76        (response) => {
77          this.loading = false;
78          if (this.count >= 0) {
79            let length = 0;
80            if (response.builds) {
81              length = response.builds.length;
82            }
83            const total = length + offset;
84            if (response.has_next) {
85              if (length !== this.pageSize) {
86                this.showSnackbar('Received unexpected number of entities.');
87              } else if (this.count <= total) {
88                this.getCount();
89              }
90            } else {
91              if (this.count !== total) {
92                if (length !== this.count) {
93                  this.getCount();
94                } else if (this.count > total) {
95                  const countObservable = this.getDefaultCountObservable([
96                    () => {
97                      this.pageIndex = Math.floor(this.count / this.pageSize);
98                      this.getBuilds(this.pageSize, this.pageSize * this.pageIndex);
99                    }
100                  ]);
101                  this.getCount(countObservable);
102                }
103              }
104            }
105          }
106          this.dataSource.data = response.builds;
107        },
108        (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
109      );
110  }
111
112  /** Hooks a page event and handles properly. */
113  onPageEvent(event: PageEvent) {
114    this.pageSize = event.pageSize;
115    this.pageIndex = event.pageIndex;
116    this.getBuilds(this.pageSize, this.pageSize * this.pageIndex);
117    return event;
118  }
119
120  /** Applies a filter and get entities with it. */
121  applyFilters(filters) {
122    this.pageIndex = 0;
123    this.appliedFilters = filters;
124    this.getCount();
125    this.getBuilds(this.pageSize, this.pageSize * this.pageIndex);
126  }
127}
128