@@ -2,25 +2,22 @@ import { getRow } from "../Api/Gridviews/GetRow";
22import { getRows } from "../Api/Gridviews/GetRows" ;
33import DomChangeListener from "../Dom/Change/Listener" ;
44import DomUtil from "../Dom/Util" ;
5- import { promiseMutex } from "../Helper/PromiseMutex" ;
65import { wheneverFirstSeen } from "../Helper/Selector" ;
76import UiDropdownSimple from "../Ui/Dropdown/Simple" ;
8- import { dialogFactory } from "./Dialog " ;
7+ import Filter from "./GridView/Filter " ;
98
109export class GridView {
10+ readonly #filter: Filter ;
1111 readonly #gridClassName: string ;
1212 readonly #table: HTMLTableElement ;
1313 readonly #pagination: WoltlabCorePaginationElement ;
1414 readonly #baseUrl: string ;
15- readonly #filterButton: HTMLButtonElement ;
16- readonly #filterPills: HTMLElement ;
1715 readonly #noItemsNotice: HTMLElement ;
1816 #pageNo: number ;
1917 #sortField: string ;
2018 #sortOrder: string ;
2119 #defaultSortField: string ;
2220 #defaultSortOrder: string ;
23- #filters: Map < string , string > ;
2421 #gridViewParameters?: Map < string , string > ;
2522
2623 constructor (
@@ -35,8 +32,6 @@ export class GridView {
3532 this . #gridClassName = gridClassName ;
3633 this . #table = document . getElementById ( `${ gridId } _table` ) as HTMLTableElement ;
3734 this . #pagination = document . getElementById ( `${ gridId } _pagination` ) as WoltlabCorePaginationElement ;
38- this . #filterButton = document . getElementById ( `${ gridId } _filterButton` ) as HTMLButtonElement ;
39- this . #filterPills = document . getElementById ( `${ gridId } _filters` ) as HTMLElement ;
4035 this . #noItemsNotice = document . getElementById ( `${ gridId } _noItemsNotice` ) as HTMLElement ;
4136 this . #pageNo = pageNo ;
4237 this . #baseUrl = baseUrl ;
@@ -49,9 +44,8 @@ export class GridView {
4944 this . #initPagination( ) ;
5045 this . #initSorting( ) ;
5146 this . #initInteractions( ) ;
52- this . #initFilters ( ) ;
47+ this . #filter = this . #setupFilter ( gridId ) ;
5348 this . #initEventListeners( ) ;
54- this . #initSelectCheckboxes( ) ;
5549
5650 window . addEventListener ( "popstate" , ( ) => {
5751 this . #handlePopState( ) ;
@@ -113,7 +107,7 @@ export class GridView {
113107 this . #pageNo,
114108 this . #sortField,
115109 this . #sortOrder,
116- this . #filters ,
110+ this . #filter . getActiveFilters ( ) ,
117111 this . #gridViewParameters,
118112 )
119113 ) . unwrap ( ) ;
@@ -129,7 +123,7 @@ export class GridView {
129123
130124 DomChangeListener . trigger ( ) ;
131125
132- this . #renderFilters ( response . filterLabels ) ;
126+ this . #filter . setFilterLabels ( response . filterLabels ) ;
133127 }
134128
135129 async #refreshRow( row : HTMLElement ) : Promise < void > {
@@ -153,11 +147,10 @@ export class GridView {
153147 parameters . push ( [ "sortField" , this . #sortField] ) ;
154148 parameters . push ( [ "sortOrder" , this . #sortOrder] ) ;
155149 }
156- if ( this . #filters) {
157- this . #filters. forEach ( ( value , key ) => {
158- parameters . push ( [ `filters[${ key } ]` , value ] ) ;
159- } ) ;
160- }
150+
151+ this . #filter. getActiveFilters ( ) . forEach ( ( value , key ) => {
152+ parameters . push ( [ `filters[${ key } ]` , value ] ) ;
153+ } ) ;
161154
162155 if ( parameters . length > 0 ) {
163156 url . search += url . search !== "" ? "&" : "?" ;
@@ -189,84 +182,11 @@ export class GridView {
189182 } ) ;
190183 }
191184
192- #initFilters( ) : void {
193- if ( ! this . #filterButton) {
194- return ;
195- }
196-
197- this . #filterButton. addEventListener (
198- "click" ,
199- promiseMutex ( ( ) => this . #showFilterDialog( ) ) ,
200- ) ;
201-
202- if ( ! this . #filterPills) {
203- return ;
204- }
205-
206- const filterButtons = this . #filterPills. querySelectorAll < HTMLButtonElement > ( "[data-filter]" ) ;
207- if ( ! filterButtons . length ) {
208- return ;
209- }
210-
211- this . #filters = new Map < string , string > ( ) ;
212- filterButtons . forEach ( ( button ) => {
213- this . #filters. set ( button . dataset . filter ! , button . dataset . filterValue ! ) ;
214- button . addEventListener ( "click" , ( ) => {
215- this . #removeFilter( button . dataset . filter ! ) ;
216- } ) ;
217- } ) ;
218- }
219-
220- async #showFilterDialog( ) : Promise < void > {
221- const url = new URL ( this . #filterButton. dataset . endpoint ! ) ;
222- if ( this . #filters) {
223- this . #filters. forEach ( ( value , key ) => {
224- url . searchParams . set ( `filters[${ key } ]` , value ) ;
225- } ) ;
226- }
227-
228- const { ok, result } = await dialogFactory ( ) . usingFormBuilder ( ) . fromEndpoint ( url . toString ( ) ) ;
229-
230- if ( ok ) {
231- this . #filters = new Map ( Object . entries ( result as ArrayLike < string > ) ) ;
232- this . #switchPage( 1 ) ;
233- }
234- }
235-
236- #renderFilters( labels : ArrayLike < string > ) : void {
237- if ( ! this . #filterPills) {
238- return ;
239- }
240- this . #filterPills. innerHTML = "" ;
241- if ( ! this . #filters) {
242- return ;
243- }
244-
245- this . #filters. forEach ( ( value , key ) => {
246- const button = document . createElement ( "button" ) ;
247- button . type = "button" ;
248- button . classList . add ( "button" , "small" ) ;
249- const icon = document . createElement ( "fa-icon" ) ;
250- icon . setIcon ( "circle-xmark" ) ;
251- button . append ( icon , labels [ key ] ) ;
252- button . addEventListener ( "click" , ( ) => {
253- this . #removeFilter( key ) ;
254- } ) ;
255-
256- this . #filterPills. append ( button ) ;
257- } ) ;
258- }
259-
260- #removeFilter( filter : string ) : void {
261- this . #filters. delete ( filter ) ;
262- this . #switchPage( 1 ) ;
263- }
264-
265185 #handlePopState( ) : void {
266186 let pageNo = 1 ;
267187 this . #sortField = this . #defaultSortField;
268188 this . #sortOrder = this . #defaultSortOrder;
269- this . #filters = new Map < string , string > ( ) ;
189+ this . #filter . resetFilters ( ) ;
270190
271191 const url = new URL ( window . location . href ) ;
272192 url . searchParams . forEach ( ( value , key ) => {
@@ -285,7 +205,7 @@ export class GridView {
285205
286206 const matches = key . match ( / ^ f i l t e r s \[ ( [ a - z 0 - 9 _ ] + ) \] $ / i) ;
287207 if ( matches ) {
288- this . #filters . set ( matches [ 1 ] , value ) ;
208+ this . #filter . setFilter ( matches [ 1 ] , value ) ;
289209 }
290210 } ) ;
291211
@@ -301,4 +221,13 @@ export class GridView {
301221 ( event . target as HTMLElement ) . remove ( ) ;
302222 } ) ;
303223 }
224+
225+ #setupFilter( gridId : string ) : Filter {
226+ const filter = new Filter ( gridId ) ;
227+ filter . addEventListener ( "switchPage" , ( event ) => {
228+ this . #switchPage( event . detail . pageNo ) ;
229+ } ) ;
230+
231+ return filter ;
232+ }
304233}
0 commit comments