mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-14 12:08:36 -05:00
handling array as a table data and headerFilter.plugin (#12926)
This commit is contained in:
7
src/sql/azdata.proposed.d.ts
vendored
7
src/sql/azdata.proposed.d.ts
vendored
@@ -756,4 +756,11 @@ declare module 'azdata' {
|
||||
*/
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface TableComponentProperties {
|
||||
/**
|
||||
* Specifies whether to use headerFilter plugin
|
||||
*/
|
||||
headerFilter?: boolean,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,9 @@ export function slickGridDataItemColumnValueWithNoData(value: any, columnDef: an
|
||||
if (typeof displayValue === 'number') {
|
||||
displayValue = displayValue.toString();
|
||||
}
|
||||
if (displayValue instanceof Array) {
|
||||
displayValue = displayValue.toString();
|
||||
}
|
||||
return {
|
||||
text: displayValue,
|
||||
ariaLabel: displayValue ? escape(displayValue) : ((displayValue !== undefined) ? localize("tableCell.NoDataAvailable", "no data available") : displayValue)
|
||||
|
||||
@@ -15,9 +15,9 @@ export interface IExtendedColumn<T> extends Slick.Column<T> {
|
||||
}
|
||||
|
||||
export interface CommandEventArgs<T extends Slick.SlickData> {
|
||||
grid: Slick.Grid<T>,
|
||||
column: Slick.Column<T>,
|
||||
command: string
|
||||
grid: Slick.Grid<T>,
|
||||
column: Slick.Column<T>,
|
||||
command: string
|
||||
}
|
||||
|
||||
export class HeaderFilter<T extends Slick.SlickData> {
|
||||
@@ -337,55 +337,50 @@ export class HeaderFilter<T extends Slick.SlickData> {
|
||||
}
|
||||
|
||||
private getFilterValues(dataView: Slick.DataProvider<T>, column: Slick.Column<T>): Array<any> {
|
||||
const seen: Array<string> = [];
|
||||
for (let i = 0; i < dataView.getLength(); i++) {
|
||||
const value = dataView.getItem(i)[column.field!];
|
||||
const seen: Set<string> = new Set();
|
||||
dataView.getItems().forEach(items => {
|
||||
const value = items[column.field!];
|
||||
const valueArr = value instanceof Array ? value : [value];
|
||||
valueArr.forEach(v => seen.add(v));
|
||||
});
|
||||
|
||||
if (!seen.some(x => x === value)) {
|
||||
seen.push(value);
|
||||
}
|
||||
}
|
||||
return seen;
|
||||
return Array.from(seen);
|
||||
}
|
||||
|
||||
private getFilterValuesByInput($input: JQuery<HTMLElement>): Array<string> {
|
||||
const column = $input.data('column'),
|
||||
filter = $input.val() as string,
|
||||
dataView = this.grid.getData() as Slick.DataProvider<T>,
|
||||
seen: Array<any> = [];
|
||||
|
||||
for (let i = 0; i < dataView.getLength(); i++) {
|
||||
const value = dataView.getItem(i)[column.field];
|
||||
seen: Set<any> = new Set();
|
||||
|
||||
dataView.getItems().forEach(item => {
|
||||
const value = item[column.field];
|
||||
const valueArr = value instanceof Array ? value : [(!value ? '' : value)];
|
||||
if (filter.length > 0) {
|
||||
const itemValue = !value ? '' : value;
|
||||
const lowercaseFilter = filter.toString().toLowerCase();
|
||||
const lowercaseVal = itemValue.toString().toLowerCase();
|
||||
if (!seen.some(x => x === value) && lowercaseVal.indexOf(lowercaseFilter) > -1) {
|
||||
seen.push(value);
|
||||
}
|
||||
valueArr.map(v => v.toLowerCase()).forEach((lowerVal, index) => {
|
||||
if (lowerVal.indexOf(lowercaseFilter) > -1) {
|
||||
seen.add(valueArr[index]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
valueArr.forEach(v => seen.add(v));
|
||||
}
|
||||
else {
|
||||
if (!seen.some(x => x === value)) {
|
||||
seen.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return seen.sort((v) => { return v; });
|
||||
return Array.from(seen).sort((v) => { return v; });
|
||||
}
|
||||
|
||||
private getAllFilterValues(data: Array<Slick.SlickData>, column: Slick.Column<T>) {
|
||||
const seen: Array<any> = [];
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const value = data[i][column.field!];
|
||||
const seen: Set<any> = new Set();
|
||||
|
||||
if (!seen.some(x => x === value)) {
|
||||
seen.push(value);
|
||||
}
|
||||
}
|
||||
data.forEach(items => {
|
||||
const value = items[column.field!];
|
||||
const valueArr = value instanceof Array ? value : [value];
|
||||
valueArr.forEach(v => seen.add(v));
|
||||
});
|
||||
|
||||
return seen.sort((v) => { return v; });
|
||||
return Array.from(seen).sort((v) => { return v; });
|
||||
}
|
||||
|
||||
private handleMenuItemClick(e: JQuery.Event<HTMLElement, null>, command: string, columnDef: Slick.Column<T>) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { ComponentBase } from 'sql/workbench/browser/modelComponents/componentBa
|
||||
|
||||
import { Table } from 'sql/base/browser/ui/table/table';
|
||||
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
|
||||
import { attachTableStyler } from 'sql/platform/theme/common/styler';
|
||||
import { attachTableStyler, attachButtonStyler } from 'sql/platform/theme/common/styler';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { getContentHeight, getContentWidth, Dimension } from 'vs/base/browser/dom';
|
||||
import { RowSelectionModel } from 'sql/base/browser/ui/table/plugins/rowSelectionModel.plugin';
|
||||
@@ -29,6 +29,7 @@ import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } fro
|
||||
import { convertSizeToNumber } from 'sql/base/browser/dom';
|
||||
import { ButtonColumn, ButtonClickEventArgs } from 'sql/base/browser/ui/table/plugins/buttonColumn.plugin';
|
||||
import { createIconCssClass } from 'sql/workbench/browser/modelComponents/iconUtils';
|
||||
import { HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
|
||||
|
||||
export enum ColumnSizingMode {
|
||||
ForceFit = 0, // all columns will be sized to fit in viewable space, no horiz scroll bar
|
||||
@@ -51,6 +52,7 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
|
||||
private _checkboxColumns: CheckboxSelectColumn<{}>[] = [];
|
||||
private _buttonsColumns: ButtonColumn<{}>[] = [];
|
||||
private _pluginsRegisterStatus: boolean[] = [];
|
||||
private _filterPlugin: HeaderFilter<Slick.SlickData>;
|
||||
private _onCheckBoxChanged = new Emitter<ICheckboxCellActionEventArgs>();
|
||||
private _onButtonClicked = new Emitter<ButtonClickEventArgs<{}>>();
|
||||
public readonly onCheckBoxChanged: vsEvent<ICheckboxCellActionEventArgs> = this._onCheckBoxChanged.event;
|
||||
@@ -133,7 +135,30 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
if (this._inputContainer) {
|
||||
this._tableData = new TableDataView<Slick.SlickData>();
|
||||
this._tableData = new TableDataView<Slick.SlickData>(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
(data: Slick.SlickData[]) => {
|
||||
let columns = this._table.grid.getColumns();
|
||||
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
let col: any = columns[i];
|
||||
let filterValues: Array<any> = col.filterValues;
|
||||
if (filterValues && filterValues.length > 0) {
|
||||
return data.filter(item => {
|
||||
let colValue = item[col.field];
|
||||
if (colValue instanceof Array) {
|
||||
return filterValues.find(x => colValue.indexOf(x) >= 0);
|
||||
}
|
||||
return filterValues.find(x => x === colValue);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
);
|
||||
|
||||
let options = <Slick.GridOptions<any>>{
|
||||
syncColumnCellResize: true,
|
||||
@@ -249,7 +274,9 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
|
||||
|
||||
Object.keys(this._checkboxColumns).forEach(col => this.registerPlugins(col, this._checkboxColumns[col]));
|
||||
Object.keys(this._buttonsColumns).forEach(col => this.registerPlugins(col, this._buttonsColumns[col]));
|
||||
|
||||
if (this.headerFilter === true) {
|
||||
this.registerFilterPlugin();
|
||||
}
|
||||
if (this.ariaRowCount === -1) {
|
||||
this._table.removeAriaRowCount();
|
||||
}
|
||||
@@ -356,6 +383,35 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
|
||||
|
||||
}
|
||||
|
||||
|
||||
private registerFilterPlugin() {
|
||||
const filterPlugin = new HeaderFilter<Slick.SlickData>();
|
||||
this._register(attachButtonStyler(filterPlugin, this.themeService));
|
||||
this._filterPlugin = filterPlugin;
|
||||
this._filterPlugin.onFilterApplied.subscribe((e, args) => {
|
||||
let filterValues = (<any>args).column.filterValues;
|
||||
if (filterValues) {
|
||||
this._tableData.filter();
|
||||
this._table.grid.resetActiveCell();
|
||||
this.layoutTable();
|
||||
} else {
|
||||
this._tableData.clearFilter();
|
||||
}
|
||||
});
|
||||
|
||||
this._filterPlugin.onCommand.subscribe((e, args: any) => {
|
||||
this._tableData.sort({
|
||||
sortAsc: args.command === 'sort-asc',
|
||||
sortCol: args.column,
|
||||
multiColumnSort: false,
|
||||
grid: this._table.grid
|
||||
});
|
||||
this.layoutTable();
|
||||
});
|
||||
|
||||
this._table.registerPlugin(filterPlugin);
|
||||
}
|
||||
|
||||
public focus(): void {
|
||||
if (this._table.grid.getDataLength() > 0) {
|
||||
if (!this._table.grid.getActiveCell()) {
|
||||
@@ -426,4 +482,8 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
|
||||
public set updateCells(newValue: azdata.TableCell[]) {
|
||||
this.setPropertyFromUI<azdata.TableCell[]>((properties, value) => { properties.updateCells = value; }, newValue);
|
||||
}
|
||||
|
||||
public get headerFilter(): boolean {
|
||||
return this.getPropertyOrDefault<boolean>((props) => props.headerFilter, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user