Files
milestones/src/components/query/query.component.ts

212 lines
5.3 KiB
TypeScript

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<TreeNode>[] {
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<TreeNode>[] {
return [];
}
private getSorts(query: Query, headers: Header[]): Partial<TreeNode>[] {
const result: Partial<TreeNode>[] = [];
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;
};