import { Component } from '@angular/core'; import { TreeComponent } from '../tree/tree.component'; import { TreeNode } from '../../models/tree-node'; import { QueryService } from '../../services/query.service'; import { Query } from '../../models/query'; import { Action } from '../../models/action'; import { faArrowDown, faArrowUp, faRemove, faSort, faSortAsc, faSortDesc, faSortDown, } from '@fortawesome/free-solid-svg-icons'; import { ExecuteService } from '../../services/execute.service'; import { Header } from '../../models/header'; import { SORT } from '../../enums/sort'; @Component({ selector: 'fbi-query', standalone: true, imports: [TreeComponent], templateUrl: './query.component.html', styleUrl: './query.component.scss', }) export class QueryComponent { node: TreeNode = new TreeNode({}); constructor( private queryService: QueryService, executeService: ExecuteService ) { queryService.Query$.subscribe((query: Query) => { const headers = executeService.headers(query); const fields = this.getFields(query, headers); const filters = this.getFilters(query, headers); const sort = this.getSorts(query, headers); this.node = new TreeNode({ hidden: true, expanded: true, children: [ { label: 'Fields', leaf: false, expanded: true, children: fields, }, { label: 'Filters', expanded: true, leaf: false, children: filters, }, { label: 'Sort', expanded: true, leaf: false, children: sort, }, ] as TreeNode[], }); }); } onActionClick(event: { action: Action; node: TreeNode }): void { const data = event.action.data as ActionData; switch (data.cmd) { case ACTIONS.REMOVE: this.queryService.remove(event.node.data); break; case ACTIONS.UP: case ACTIONS.DOWN: this.queryService.add(event.node.data, data.data); break; case ACTIONS.SORTASC: case ACTIONS.SORTDSC: case ACTIONS.SORTDEL: this.queryService.sort(data.data); break; } } private getFields(query: Query, headers: Header[]): Partial[] { return (query?.fields ?? []).map( (field: string, index: number, array: string[]) => { const sort = query?.sort?.field ?? ''; const sdir = query?.sort?.dir ?? SORT.NONE; const actions = []; // move if (index !== 0) { actions.push({ label: 'Move Up', icon: faArrowUp, data: { cmd: ACTIONS.UP, data: index - 1 }, }); } if (index !== array.length - 1) { actions.push({ label: 'Move Down', icon: faArrowDown, data: { cmd: ACTIONS.DOWN, data: index + 1 }, }); } // sort if (sort === field) { switch (sdir) { case SORT.ASC: actions.push({ label: 'Sort Dsc', icon: faSortDown, data: { cmd: ACTIONS.SORTDSC, data: field }, }); break; case SORT.DSC: actions.push({ label: 'Clear Sort', icon: faSort, data: { cmd: ACTIONS.SORTDEL, data: field }, }); break; default: actions.push({ label: 'Sort Asc', icon: faSortAsc, data: { cmd: ACTIONS.SORTASC, data: field }, }); break; } } else { actions.push({ label: 'Sort Asc', icon: faSortAsc, data: { cmd: ACTIONS.SORTASC, data: field }, }); } // remove actions.push({ label: 'Remove', icon: faRemove, data: { cmd: ACTIONS.REMOVE }, }); const label = headers.find((header: Header) => header.source === field)?.label ?? 'unknown'; return { label: label, data: field, actions: actions, }; } ); } private getFilters(query: Query, headers: Header[]): Partial[] { return []; } private getSorts(query: Query, headers: Header[]): Partial[] { const result: Partial[] = []; if (query?.sort?.isValid?.()) { const s = query.sort; const label = headers.find((header: Header) => header.source === s.field)?.label ?? 'unknown'; const actions = []; if (s.dir === SORT.ASC) { actions.push({ label: 'Sort Dsc', icon: faSortDesc, data: { cmd: ACTIONS.SORTDSC, data: s.field }, }); } else if (s.dir === SORT.DSC) { actions.push({ label: 'Clear Sort', icon: faSort, data: { cmd: ACTIONS.SORTDEL, data: s.field }, }); } result.push({ label: label, data: s.field, actions: actions, }); } return result; } } enum ACTIONS { REMOVE = 'del', UP = 'up', DOWN = 'down', SORTDSC = 'dsc', SORTASC = 'asc', SORTDEL = 'nne', } type ActionData = { cmd: ACTIONS; data: any; };