@fleetbase/ember-ui
Version:
Fleetbase UI provides all the interface components, helpers, services and utilities for building a Fleetbase extension into the Console.
184 lines (149 loc) • 6 kB
JavaScript
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class QueryBuilderSortByComponent extends Component {
selectedSortBy = null;
selectedSortDirection = null;
sortByItems = [];
constructor() {
super(...arguments);
this.sortByItems = this.args.sortBy || [];
// Set default direction
this.selectedSortDirection = this.directions[0];
}
get directions() {
return [
{ value: 'asc', label: 'Ascending', icon: 'arrow-up' },
{ value: 'desc', label: 'Descending', icon: 'arrow-down' },
];
}
/**
* Only allow sorting by columns that are selected in the query
* This ensures valid SQL generation
*/
get availableSortColumns() {
// Use allSelectedColumns from parent if available, otherwise fall back to selectedColumns
const columnsToUse = this.args.allSelectedColumns || this.args.selectedColumns || [];
if (!columnsToUse.length) {
return [];
}
// Return all selected columns - both regular and aggregated columns can be sorted
return columnsToUse.map((column) => ({
...column,
// Add helpful label for aggregated columns
sortLabel: column.aggregate && column.aggregate !== 'none' ? `${column.aggregate.toUpperCase()}(${column.label})` : column.label,
}));
}
/**
* Check if sorting is possible with current column selection
*/
get canSort() {
return this.availableSortColumns.length > 0;
}
/**
* Get helpful message when sorting is not available
*/
get sortingMessage() {
const columnsToUse = this.args.allSelectedColumns || this.args.selectedColumns || [];
if (!columnsToUse.length) {
return 'Select columns first to enable sorting';
}
return null;
}
selectSortColumn(column) {
this.selectedSortBy = column;
}
selectSortDirection(direction) {
this.selectedSortDirection = direction;
}
addSortBy() {
if (this.selectedSortBy && this.selectedSortDirection) {
// Validate that the sort column is actually selected
const isSortColumnSelected = this.args.selectedColumns?.some((col) => col.full === this.selectedSortBy.full);
if (!isSortColumnSelected) {
console.warn('Cannot sort by column that is not selected:', this.selectedSortBy);
return;
}
// Check if this column is already in the sort list
const existingIndex = this.sortByItems.findIndex((item) => item.column.full === this.selectedSortBy.full);
if (existingIndex >= 0) {
// Update existing sort direction
const updatedItems = [...this.sortByItems];
updatedItems[existingIndex] = {
...updatedItems[existingIndex],
direction: this.selectedSortDirection,
};
this.sortByItems = updatedItems;
} else {
// Add new sort
const newSort = {
id: Date.now() + Math.random(),
column: this.selectedSortBy,
direction: this.selectedSortDirection,
};
this.sortByItems = [...this.sortByItems, newSort];
}
// Reset selections
this.selectedSortBy = null;
this.selectedSortDirection = this.directions[0];
this.notifyChange();
}
}
removeSortBy(index) {
this.sortByItems = this.sortByItems.filter((_, i) => i !== index);
this.notifyChange();
}
// @action reorderSortBy(newOrder) {
// this.sortByItems = newOrder;
// this.notifyChange();
// }
reorderGroupBy({ sourceList, sourceIndex, targetList, targetIndex }) {
// no change? bail
if (sourceList === targetList && sourceIndex === targetIndex) return;
// mutate the EmberArray in-place (per README)
const item = sourceList.objectAt(sourceIndex);
sourceList.removeAt(sourceIndex);
targetList.insertAt(targetIndex, item);
// ensure Glimmer sees a change even if it misses EmberArray observers
this.sortByItems = [...this.sortByItems];
this.notifyChange();
}
toggleSortDirection(index) {
const updatedItems = [...this.sortByItems];
const currentDirection = updatedItems[index].direction.value;
const newDirection = currentDirection === 'asc' ? this.directions[1] : this.directions[0];
updatedItems[index] = {
...updatedItems[index],
direction: newDirection,
};
this.sortByItems = updatedItems;
this.notifyChange();
}
/**
* Validate existing sort items when selected columns change
*/
validateSortItems() {
const columnsToUse = this.args.allSelectedColumns || this.args.selectedColumns || [];
if (!columnsToUse.length) {
// Clear all sorting if no columns selected
if (this.sortByItems.length > 0) {
this.sortByItems = [];
this.notifyChange();
}
return;
}
// Remove sort items for columns that are no longer selected
const validSortItems = this.sortByItems.filter((item) => {
return columnsToUse.some((col) => col.full === item.column.full);
});
if (validSortItems.length !== this.sortByItems.length) {
this.sortByItems = validSortItems;
this.notifyChange();
}
}
notifyChange() {
if (this.args.onChange) {
this.args.onChange(this.sortByItems);
}
}
}