summaryrefslogtreecommitdiffstats
path: root/tools/tryselect/selectors/chooser/static/filter.js
blob: 2d8731e61fde9b83de346316b0b52f54a77c38c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const selection = $("#selection")[0];
const count = $("#selection-count")[0];
const pluralize = (count, noun, suffix = "s") =>
  `${count} ${noun}${count !== 1 ? suffix : ""}`;

var selected = [];

var updateLabels = () => {
  $(".tab-pane.active > .filter-label").each(function (index) {
    let box = $("#" + this.htmlFor)[0];
    let method = box.checked ? "add" : "remove";
    $(this)[method + "Class"]("is-checked");
  });
};

var apply = () => {
  let filters = {};
  let kinds = [];

  $(".filter:checked").each(function (index) {
    for (let kind of this.name.split(",")) {
      if (!kinds.includes(kind)) {
        kinds.push(kind);
      }
    }

    // Checkbox element values are generated by Section.get_context() in app.py
    let attrs = JSON.parse(this.value);
    for (let attr in attrs) {
      if (!(attr in filters)) {
        filters[attr] = [];
      }

      let values = attrs[attr];
      filters[attr] = filters[attr].concat(values);
    }
  });
  updateLabels();

  if (
    !Object.keys(filters).length ||
    (Object.keys(filters).length == 1 && "build_type" in filters)
  ) {
    selection.value = "";
    count.innerHTML = "0 tasks selected";
    return;
  }

  var taskMatches = label => {
    let task = tasks[label];

    // If no box for the given kind has been checked, this task is
    // automatically not selected.
    if (!kinds.includes(task.kind)) {
      return false;
    }

    for (let attr in filters) {
      let values = filters[attr];
      if (!(attr in task) || values.includes(task[attr])) {
        continue;
      }
      return false;
    }
    return true;
  };

  selected = Object.keys(tasks).filter(taskMatches);
  applyChunks();
};

var applyChunks = () => {
  // For tasks that have a chunk filter applied, we handle that here.
  let filters = {};
  $(".filter:text").each(function (index) {
    let value = $(this).val();
    if (value === "") {
      return;
    }

    let attrs = JSON.parse(this.name);
    let key = `${attrs.unittest_suite}-${attrs.unittest_flavor}`;
    if (!(key in filters)) {
      filters[key] = [];
    }

    // Parse the chunk strings. These are formatted like printer page setups, e.g: "1,4-6,9"
    for (let item of value.split(",")) {
      if (!item.includes("-")) {
        filters[key].push(parseInt(item));
        continue;
      }

      let [start, end] = item.split("-");
      for (let i = parseInt(start); i <= parseInt(end); ++i) {
        filters[key].push(i);
      }
    }
  });

  let chunked = selected.filter(function (label) {
    let task = tasks[label];
    let key = task.unittest_suite + "-" + task.unittest_flavor;
    if (key in filters && !filters[key].includes(parseInt(task.test_chunk))) {
      return false;
    }
    return true;
  });

  selection.value = chunked.join("\n");
  count.innerText = pluralize(chunked.length, "task") + " selected";
};