From 5dfb839175c5548ff00f76faa2050df08578a908 Mon Sep 17 00:00:00 2001 From: Christopher Suh Date: Thu, 16 Jan 2025 18:11:56 -0800 Subject: [PATCH 01/12] add new sort button --- src/reactviews/media/sort-asc.gif | Bin 830 -> 0 bytes src/reactviews/media/sort-asc.png | Bin 105 -> 0 bytes src/reactviews/media/sort-desc.gif | Bin 833 -> 0 bytes src/reactviews/media/sort-desc.png | Bin 107 -> 0 bytes src/reactviews/media/sort.svg | 3 + src/reactviews/media/sort_asc.svg | 9 +- src/reactviews/media/sort_asc_inverse.svg | 9 +- src/reactviews/media/sort_desc.svg | 9 +- src/reactviews/media/sort_desc_inverse.svg | 9 +- src/reactviews/media/sort_inverse.svg | 3 + src/reactviews/media/table.css | 42 +++++++ .../table/plugins/headerFilter.plugin.ts | 109 +++++++++++++++--- 12 files changed, 149 insertions(+), 44 deletions(-) delete mode 100644 src/reactviews/media/sort-asc.gif delete mode 100644 src/reactviews/media/sort-asc.png delete mode 100644 src/reactviews/media/sort-desc.gif delete mode 100644 src/reactviews/media/sort-desc.png create mode 100644 src/reactviews/media/sort.svg create mode 100644 src/reactviews/media/sort_inverse.svg diff --git a/src/reactviews/media/sort-asc.gif b/src/reactviews/media/sort-asc.gif deleted file mode 100644 index 67a2a4c669fc5821a07fc486228d626e16d6ad9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 830 zcmZ?wbhEHb + + diff --git a/src/reactviews/media/sort_asc.svg b/src/reactviews/media/sort_asc.svg index c9c1838171..94f9cd580f 100644 --- a/src/reactviews/media/sort_asc.svg +++ b/src/reactviews/media/sort_asc.svg @@ -1,8 +1,3 @@ - - - + + diff --git a/src/reactviews/media/sort_asc_inverse.svg b/src/reactviews/media/sort_asc_inverse.svg index 2d40e6ca52..95cd58a56c 100644 --- a/src/reactviews/media/sort_asc_inverse.svg +++ b/src/reactviews/media/sort_asc_inverse.svg @@ -1,8 +1,3 @@ - - - + + diff --git a/src/reactviews/media/sort_desc.svg b/src/reactviews/media/sort_desc.svg index d045a30b02..5045e00674 100644 --- a/src/reactviews/media/sort_desc.svg +++ b/src/reactviews/media/sort_desc.svg @@ -1,8 +1,3 @@ - - - + + diff --git a/src/reactviews/media/sort_desc_inverse.svg b/src/reactviews/media/sort_desc_inverse.svg index 9184cf7626..4d0fed8a8d 100644 --- a/src/reactviews/media/sort_desc_inverse.svg +++ b/src/reactviews/media/sort_desc_inverse.svg @@ -1,8 +1,3 @@ - - - + + diff --git a/src/reactviews/media/sort_inverse.svg b/src/reactviews/media/sort_inverse.svg new file mode 100644 index 0000000000..87cfe0eeda --- /dev/null +++ b/src/reactviews/media/sort_inverse.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/reactviews/media/table.css b/src/reactviews/media/table.css index 7a03f0eaae..f80a90263c 100644 --- a/src/reactviews/media/table.css +++ b/src/reactviews/media/table.css @@ -61,6 +61,48 @@ flex: 0 0 auto; } +.slick-header-sort-button { + background-position: center center; + background-repeat: no-repeat; + cursor: pointer; + display: inline-block; + width: 16px; + background-image: url("sort_inverse.svg"); + flex: 0 0 auto; + margin-right: 2px; + background-color: transparent; + border: 0px; + padding: 0px; +} + +.slick-header-sortdesc-button { + background-position: center center; + background-repeat: no-repeat; + cursor: pointer; + display: inline-block; + width: 16px; + background-image: url("sort_desc_inverse.svg"); + flex: 0 0 auto; + margin-right: 2px; + background-color: transparent; + border: 0px; + padding: 0px; +} + +.slick-header-sortasc-button { + background-position: center center; + background-repeat: no-repeat; + cursor: pointer; + display: inline-block; + width: 16px; + background-image: url("sort_asc_inverse.svg"); + flex: 0 0 auto; + margin-right: 2px; + background-color: transparent; + border: 0px; + padding: 0px; +} + .slick-header-menubutton { background-position: center center; background-repeat: no-repeat; diff --git a/src/reactviews/pages/QueryResult/table/plugins/headerFilter.plugin.ts b/src/reactviews/pages/QueryResult/table/plugins/headerFilter.plugin.ts index ce8f2eb583..743b0e0788 100644 --- a/src/reactviews/pages/QueryResult/table/plugins/headerFilter.plugin.ts +++ b/src/reactviews/pages/QueryResult/table/plugins/headerFilter.plugin.ts @@ -34,6 +34,7 @@ export interface CommandEventArgs { } const ShowFilterText = locConstants.queryResult.showFilter; +const SortAscendingText = locConstants.queryResult.sortAscending; export const FilterButtonWidth: number = 34; @@ -51,10 +52,14 @@ export class HeaderFilter { private grid!: Slick.Grid; private handler = new Slick.EventHandler(); private columnDef!: FilterableColumn; - private columnButtonMapping: Map = new Map< + private columnFilterButtonMapping: Map = new Map< string, HTMLElement >(); + private columnSortButtonMapping: Map = new Map< + string, + SortProperties + >(); private _listData: TableFilterListElement[] = []; private _list!: VirtualizedList; @@ -116,33 +121,105 @@ export class HeaderFilter { const theme: string = resolveVscodeThemeType(this.theme); args.node.classList.add("slick-header-with-filter"); args.node.classList.add(theme); - const $el = jQuery( + const $filterButton = jQuery( ``, ) .addClass("slick-header-menubutton") .data("column", column); + const $sortButton = jQuery( + ``, + ) + .addClass("slick-header-sort-button") + .data("column", column); if (column.filterValues?.length) { - this.setButtonImage($el, column.filterValues?.length > 0); + this.setButtonImage($filterButton, column.filterValues?.length > 0); + } + + const filterButton = $filterButton.get(0); + if (filterButton) { + this._eventManager.addEventListener( + filterButton, + "click", + async (e: Event) => { + e.stopPropagation(); + e.preventDefault(); + await this.showFilter(filterButton); + this.grid.onHeaderClick.notify(); + }, + ); } - const elDivElement = $el.get(0); - if (elDivElement) { + const sortButton = $sortButton.get(0); + if (sortButton) { this._eventManager.addEventListener( - elDivElement, + sortButton, "click", async (e: Event) => { e.stopPropagation(); e.preventDefault(); - await this.showFilter(elDivElement); + this.columnDef = jQuery(sortButton).data("column"); //TODO: fix, shouldn't assign in the event handler + let columnFilterState: ColumnFilterState = { + columnDef: this.columnDef.id!, + filterValues: this.columnDef.filterValues!, + sorted: this.columnDef.sorted ?? SortProperties.NONE, + }; + let sortState = this.columnSortButtonMapping.get( + column.id!, + ); + + switch (sortState) { + case SortProperties.NONE: + $sortButton.removeClass("slick-header-sort-button"); + $sortButton.addClass("slick-header-sortasc-button"); + await this.handleMenuItemClick("sort-asc", column); + this.grid.setSortColumn(column.id!, true); + this.columnSortButtonMapping.set( + column.id!, + SortProperties.ASC, + ); + columnFilterState.sorted = SortProperties.ASC; + break; + case SortProperties.ASC: + $sortButton.removeClass( + "slick-header-sortasc-button", + ); + $sortButton.addClass( + "slick-header-sortdesc-button", + ); + await this.handleMenuItemClick("sort-desc", column); + this.grid.setSortColumn(column.id!, false); + this.columnSortButtonMapping.set( + column.id!, + SortProperties.DESC, + ); + columnFilterState.sorted = SortProperties.DESC; + break; + case SortProperties.DESC: + $sortButton.removeClass( + "slick-header-sortdesc-button", + ); + $sortButton.addClass("slick-header-sort-button"); + this.columnSortButtonMapping.set( + column.id!, + SortProperties.NONE, + ); + await this.resetData(this.columnDef); + columnFilterState.sorted = SortProperties.NONE; + this.updateState(columnFilterState); + break; + } this.grid.onHeaderClick.notify(); + + this.updateState(columnFilterState); }, ); } - $el.appendTo(args.node); + $sortButton.appendTo(args.node); + $filterButton.appendTo(args.node); - //@ts-ignore - this.columnButtonMapping[column.id] = $el[0]; + this.columnFilterButtonMapping.set(column.id!, filterButton); + this.columnSortButtonMapping.set(column.id!, SortProperties.NONE); } private async showFilter(filterButton: HTMLElement) { @@ -169,8 +246,6 @@ export class HeaderFilter { const offset = jQuery(filterButton).offset(); const $popup = jQuery( '