This commit has a few notable changes: 1. A simple attempt at establishing a pattern for using SELECT statements. This will be useful in the future for joins/subquery support. 2. Expanded usage of searching to be able to pass instead of just a string, an object that lets a consumer choose which columns to search on. 3. Decouple our session recording filters from being loaded from the route model hook which is a departure from our convention. This has the benefit of actually letting the page first load and having the filters load async so the page doesn't wait for the filters to finish. This is also much faster to query for each individual filter option from SQLite rather than returning all data to filter in application code.
98 lines
2.4 KiB
JavaScript
98 lines
2.4 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import Component from '@glimmer/component';
|
|
import { action } from '@ember/object';
|
|
import { tracked } from '@glimmer/tracking';
|
|
import { debounce } from 'core/decorators/debounce';
|
|
|
|
export default class DropdownComponent extends Component {
|
|
// =attributes
|
|
|
|
@tracked selectedItems = [];
|
|
@tracked searchTerm;
|
|
|
|
/**
|
|
* Takes itemOptions and filters them by searchTerm if there is one
|
|
* and limits the number of items displayed in the dropdown to 500.
|
|
* @returns {[object]}
|
|
*/
|
|
get itemOptions() {
|
|
let items = this.args.itemOptions;
|
|
|
|
if (this.searchTerm && !this.args.updateSearchTerm) {
|
|
const searchTerm = this.searchTerm.toLowerCase();
|
|
items = this.args.itemOptions.filter((item) => {
|
|
const isNameMatch = item.name?.toLowerCase().includes(searchTerm);
|
|
const isIdMatch = item.id.includes(this.searchTerm);
|
|
return isNameMatch || isIdMatch;
|
|
});
|
|
}
|
|
return items.slice(0, 250);
|
|
}
|
|
|
|
// =methods
|
|
|
|
/**
|
|
* Sets searchTerm to be used for filtering itemOptions
|
|
* @param {object} event
|
|
*/
|
|
@action
|
|
@debounce(250)
|
|
async filterItems(event) {
|
|
const { value } = event.target;
|
|
|
|
if (this.args.updateSearchTerm) {
|
|
this.args.updateSearchTerm(value);
|
|
} else {
|
|
this.searchTerm = value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles checkbox event changes for selectedItems
|
|
* @param {object} event
|
|
*/
|
|
@action
|
|
selectItem(event) {
|
|
const { checked, value } = event.target;
|
|
if (checked) {
|
|
this.selectedItems = [...this.selectedItems, value];
|
|
} else {
|
|
this.selectedItems = this.selectedItems.filter((item) => item !== value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pass selectedItems to applyFilter callback and call onClose
|
|
* @param {function} close
|
|
*/
|
|
@action
|
|
applyFilter(onClose) {
|
|
this.args.applyFilter(this.selectedItems);
|
|
onClose();
|
|
}
|
|
|
|
/**
|
|
* Sets selectedItems to checkedItems when the user opens
|
|
* the dropdown and potentially has made changes
|
|
* outside of the scope of dropdown
|
|
*/
|
|
@action
|
|
open() {
|
|
this.selectedItems = [...this.args.checkedItems];
|
|
}
|
|
|
|
/**
|
|
* Custom close method for dropdown that resets selectedItems
|
|
* to checkedItems when the user closes the dropdown
|
|
*/
|
|
@action
|
|
close() {
|
|
this.selectedItems = [...this.args.checkedItems];
|
|
this.searchTerm = '';
|
|
}
|
|
}
|