• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2024 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import m from 'mithril';
16import {ProbeSetting} from '../../config/config_interfaces';
17import {MultiSelect, MultiSelectDiff} from '../../../../widgets/multiselect';
18
19export interface CheckboxesAttrs<T> {
20  title?: string;
21  options: Map<string, T>;
22  onChange?: (options: string[]) => void;
23}
24
25export class TypedMultiselect<T> implements ProbeSetting {
26  private _selectedKeys = new Set<string>();
27
28  constructor(readonly attrs: CheckboxesAttrs<T>) {}
29
30  setEnabled(key: string, enabled: boolean) {
31    if (enabled) {
32      this._selectedKeys.add(key);
33    } else {
34      this._selectedKeys.delete(key);
35    }
36  }
37
38  selectedKeys(): string[] {
39    return Array.from(this._selectedKeys);
40  }
41
42  selectedValues(): T[] {
43    const values = [];
44    for (const [key, value] of this.attrs.options.entries()) {
45      if (this._selectedKeys.has(key)) {
46        values.push(value);
47      }
48    }
49    return values;
50  }
51
52  serialize() {
53    return Array.from(this._selectedKeys);
54  }
55
56  deserialize(state: unknown): void {
57    if (Array.isArray(state) && state.every((x) => typeof x === 'string')) {
58      this._selectedKeys.clear();
59      for (const key of state) {
60        this.attrs.options.has(key) && this._selectedKeys.add(key);
61      }
62    }
63  }
64
65  render() {
66    return [
67      this.attrs.title && m('header', this.attrs.title),
68      m(MultiSelect, {
69        fixedSize: true,
70        options: Array.from(this.attrs.options.keys()).map((key) => ({
71          id: key,
72          name: key,
73          checked: this._selectedKeys.has(key),
74        })),
75        onChange: (diffs: MultiSelectDiff[]) => {
76          for (const diff of diffs) {
77            this.setEnabled(diff.id, diff.checked);
78          }
79          this.attrs.onChange?.(Array.from(this._selectedKeys.values()));
80        },
81      }),
82    ];
83  }
84}
85