1/**
2 * Copyright (c) 2024, The Linux Foundation.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6function toggleDisplayMode(btn) {
7  const catalog = document.getElementById("catalog");
8  catalog.classList.toggle("compact");
9  btn.classList.toggle("fa-bars");
10  btn.classList.toggle("fa-th");
11  btn.textContent = catalog.classList.contains("compact")
12    ? " Switch to Card View"
13    : " Switch to Compact View";
14}
15
16function populateFormFromURL() {
17  const params = ["name", "arch", "vendor", "soc"];
18  const hashParams = new URLSearchParams(window.location.hash.slice(1));
19  params.forEach((param) => {
20    const element = document.getElementById(param);
21    if (hashParams.has(param)) {
22      const value = hashParams.get(param);
23      if (param === "soc") {
24        value.split(",").forEach(soc =>
25          element.querySelector(`option[value="${soc}"]`).selected = true);
26      } else {
27        element.value = value;
28      }
29    }
30  });
31
32  filterBoards();
33}
34
35function updateURL() {
36  const params = ["name", "arch", "vendor", "soc"];
37  const hashParams = new URLSearchParams(window.location.hash.slice(1));
38
39  params.forEach((param) => {
40    const element = document.getElementById(param);
41    if (param === "soc") {
42      const selectedSocs = [...element.selectedOptions].map(({ value }) => value);
43      selectedSocs.length ? hashParams.set(param, selectedSocs.join(",")) : hashParams.delete(param);
44    }
45    else {
46      element.value ? hashParams.set(param, element.value) : hashParams.delete(param);
47    }
48  });
49
50  window.history.replaceState({}, "", `#${hashParams.toString()}`);
51}
52
53function fillSocFamilySelect() {
54  const socFamilySelect = document.getElementById("family");
55
56  Object.keys(socs_data).sort().forEach(f => {
57    socFamilySelect.add(new Option(f));
58  });
59}
60
61function fillSocSeriesSelect(families, selectOnFill = false) {
62  const socSeriesSelect = document.getElementById("series");
63
64  families = families?.length ? families : Object.keys(socs_data);
65  let allSeries = [...new Set(families.flatMap(f => Object.keys(socs_data[f])))];
66
67  socSeriesSelect.innerHTML = "";
68  allSeries.sort().map(s => {
69    const option = new Option(s, s, selectOnFill, selectOnFill);
70    socSeriesSelect.add(option);
71  });
72}
73
74function fillSocSocSelect(families, series = undefined, selectOnFill = false) {
75  const socSocSelect = document.getElementById("soc");
76
77  families = families?.length ? families : Object.keys(socs_data);
78  series = series?.length ? series : families.flatMap(f => Object.keys(socs_data[f]));
79  matchingSocs = [...new Set(families.flatMap(f => series.flatMap(s => socs_data[f][s] || [])))];
80
81  socSocSelect.innerHTML = "";
82  matchingSocs.sort().forEach((soc) => {
83    socSocSelect.add(new Option(soc, soc, selectOnFill, selectOnFill));
84  });
85}
86
87document.addEventListener("DOMContentLoaded", function () {
88  const form = document.querySelector(".filter-form");
89
90  // sort vendors alphabetically
91  vendorSelect = document.getElementById("vendor");
92  vendorOptions = Array.from(vendorSelect.options).slice(1);
93  vendorOptions.sort((a, b) => a.text.localeCompare(b.text));
94  while (vendorSelect.options.length > 1) {
95    vendorSelect.remove(1);
96  }
97  vendorOptions.forEach((option) => {
98    vendorSelect.appendChild(option);
99  });
100
101  fillSocFamilySelect();
102  fillSocSeriesSelect();
103  fillSocSocSelect();
104
105  populateFormFromURL();
106
107  socFamilySelect = document.getElementById("family");
108  socFamilySelect.addEventListener("change", () => {
109    const selectedFamilies = [...socFamilySelect.selectedOptions].map(({ value }) => value);
110    fillSocSeriesSelect(selectedFamilies, true);
111    fillSocSocSelect(selectedFamilies, undefined, true);
112    filterBoards();
113  });
114
115  socSeriesSelect = document.getElementById("series");
116  socSeriesSelect.addEventListener("change", () => {
117    const selectedFamilies = [...socFamilySelect.selectedOptions].map(({ value }) => value);
118    const selectedSeries = [...socSeriesSelect.selectedOptions].map(({ value }) => value);
119    fillSocSocSelect(selectedFamilies, selectedSeries, true);
120    filterBoards();
121  });
122
123  socSocSelect = document.getElementById("soc");
124  socSocSelect.addEventListener("change", () => {
125    filterBoards();
126  });
127
128  form.addEventListener("input", function () {
129    filterBoards();
130  });
131
132  form.addEventListener("submit", function (event) {
133    event.preventDefault();
134  });
135
136  filterBoards();
137});
138
139function resetForm() {
140  const form = document.querySelector(".filter-form");
141  form.reset();
142  fillSocFamilySelect();
143  fillSocSeriesSelect();
144  fillSocSocSelect();
145  filterBoards();
146}
147
148function updateBoardCount() {
149  const boards = document.getElementsByClassName("board-card");
150  const visibleBoards = Array.from(boards).filter(
151    (board) => !board.classList.contains("hidden")
152  ).length;
153  const totalBoards = boards.length;
154  document.getElementById("nb-matches").textContent = `Showing ${visibleBoards} of ${totalBoards}`;
155}
156
157function filterBoards() {
158  const nameInput = document.getElementById("name").value.toLowerCase();
159  const archSelect = document.getElementById("arch").value;
160  const vendorSelect = document.getElementById("vendor").value;
161  const socSocSelect = document.getElementById("soc");
162
163  const resetFiltersBtn = document.getElementById("reset-filters");
164  if (nameInput || archSelect || vendorSelect || socSocSelect.selectedOptions.length) {
165    resetFiltersBtn.classList.remove("btn-disabled");
166  } else {
167    resetFiltersBtn.classList.add("btn-disabled");
168  }
169
170  const boards = document.getElementsByClassName("board-card");
171
172  Array.from(boards).forEach(function (board) {
173    const boardName = board.getAttribute("data-name").toLowerCase();
174    const boardArchs = board.getAttribute("data-arch").split(" ");
175    const boardVendor = board.getAttribute("data-vendor");
176    const boardSocs = board.getAttribute("data-socs").split(" ");
177
178    let matches = true;
179
180    const selectedSocs = [...socSocSelect.selectedOptions].map(({ value }) => value);
181
182    matches =
183      !(nameInput && !boardName.includes(nameInput)) &&
184      !(archSelect && !boardArchs.includes(archSelect)) &&
185      !(vendorSelect && boardVendor !== vendorSelect) &&
186      (selectedSocs.length === 0 || selectedSocs.some((soc) => boardSocs.includes(soc)));
187
188    board.classList.toggle("hidden", !matches);
189  });
190
191  updateURL();
192  updateBoardCount();
193}
194