From e10f7232a1738ad87a1f7bf1438ffa572edf0a53 Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Fri, 21 May 2021 18:06:04 -0400 Subject: [PATCH] fix(backend): able to preset filters on hidden columns & all queried - the backend services were using SlickGrid `getColumns` to get the column definitions but that returns only the visible columns, however we should be able to preset filters on hidden columns and also expect all columns to be queried (it's not because the column is hidden that we shouldn't be able to filter it and query it) --- .../angular-slickgrid-constructor.spec.ts | 2 +- .../components/angular-slickgrid.component.ts | 3 +- .../models/backendService.interface.ts | 3 +- .../__tests__/graphql.service.spec.ts | 71 +++++++++++++------ .../__tests__/grid-odata.service.spec.ts | 69 ++++++++++++------ .../services/graphql.service.ts | 13 ++-- .../services/grid-odata.service.ts | 9 +-- test/cypress/integration/example06.spec.js | 28 ++++---- 8 files changed, 127 insertions(+), 71 deletions(-) diff --git a/src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid-constructor.spec.ts b/src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid-constructor.spec.ts index 0f6bdfbcd..948eccc68 100644 --- a/src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid-constructor.spec.ts +++ b/src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid-constructor.spec.ts @@ -1151,7 +1151,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () = component.ngAfterViewInit(); expect(bindBackendSpy).toHaveBeenCalledWith(mockGrid); - expect(initSpy).toHaveBeenCalledWith(mockGraphqlOptions, mockPagination, mockGrid); + expect(initSpy).toHaveBeenCalledWith(mockGraphqlOptions, mockPagination, mockGrid, sharedService); }); it('should call bind backend sorting when "enableSorting" is set', () => { diff --git a/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts b/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts index 37a411e85..3726829fa 100644 --- a/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts +++ b/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts @@ -622,7 +622,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn const backendApi = gridOptions.backendServiceApi; if (backendApi && backendApi.service && backendApi.service.init) { - backendApi.service.init(backendApi.options, gridOptions.pagination, this.grid); + backendApi.service.init(backendApi.options, gridOptions.pagination, this.grid, this.sharedService); } } @@ -1081,6 +1081,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn // finally set the new presets columns (including checkbox selector if need be) this.grid.setColumns(gridColumns); + this.sharedService.visibleColumns = gridColumns; } } } diff --git a/src/app/modules/angular-slickgrid/models/backendService.interface.ts b/src/app/modules/angular-slickgrid/models/backendService.interface.ts index 8e4085ee6..16ae1e8a4 100644 --- a/src/app/modules/angular-slickgrid/models/backendService.interface.ts +++ b/src/app/modules/angular-slickgrid/models/backendService.interface.ts @@ -10,6 +10,7 @@ import { PaginationChangedArgs, SortChangedArgs, } from './../models/index'; +import { SharedService } from '../services'; export interface BackendService { /** Backend Service options */ @@ -25,7 +26,7 @@ export interface BackendService { clearSorters?: () => void; /** initialize the backend service with certain options */ - init?: (serviceOptions?: BackendServiceOption | any, pagination?: Pagination, grid?: any) => void; + init?: (serviceOptions?: BackendServiceOption | any, pagination?: Pagination, grid?: any, sharedService?: SharedService) => void; /** Get the dataset name */ getDatasetName?: () => string; diff --git a/src/app/modules/angular-slickgrid/services/__tests__/graphql.service.spec.ts b/src/app/modules/angular-slickgrid/services/__tests__/graphql.service.spec.ts index ac4b6ee38..b35ebbe6a 100644 --- a/src/app/modules/angular-slickgrid/services/__tests__/graphql.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/__tests__/graphql.service.spec.ts @@ -3,24 +3,25 @@ import { GraphqlService } from './../graphql.service'; import { Column, ColumnFilter, + ColumnFilters, ColumnSort, CurrentFilter, + CurrentSorter, + FieldType, FilterChangedArgs, GraphqlServiceApi, GraphqlServiceOption, GridOption, MultiColumnSort, - Pagination, - ColumnFilters, OperatorType, - FieldType, - CurrentSorter, + Pagination, } from '../../models'; +import { SharedService } from '../shared.service'; const DEFAULT_ITEMS_PER_PAGE = 25; const DEFAULT_PAGE_SIZE = 20; -function removeSpaces(textS) { +function removeSpaces(textS: string) { return `${textS}`.replace(/\s+/g, ''); } @@ -33,8 +34,8 @@ const gridOptionMock = { preProcess: jest.fn(), process: jest.fn(), postProcess: jest.fn(), - } as GraphqlServiceApi -} as GridOption; + } as unknown as GraphqlServiceApi +} as unknown as GridOption; const gridStub = { autosizeColumns: jest.fn(), @@ -53,9 +54,11 @@ describe('GraphqlService', () => { let service: GraphqlService; let paginationOptions: Pagination; let serviceOptions: GraphqlServiceOption; + let sharedService: SharedService; beforeEach(() => { mockColumns = [{ id: 'field1', field: 'field1', width: 100 }, { id: 'field2', field: 'field2', width: 100 }]; + sharedService = new SharedService(); service = new GraphqlService(); serviceOptions = { columnDefinitions: mockColumns, @@ -67,7 +70,7 @@ describe('GraphqlService', () => { pageSize: 10, totalItems: 100 }; - gridOptionMock.backendServiceApi.service = service; + gridOptionMock.backendServiceApi!.service = service; }); afterEach(() => { @@ -107,7 +110,7 @@ describe('GraphqlService', () => { }); it('should throw an error when no dataset is provided in the service options after service init', () => { - service.init({ datasetName: undefined }); + service.init({ datasetName: undefined as any }); expect(() => service.buildQuery()).toThrow('GraphQL Service requires the "datasetName" property to properly build the GraphQL query'); }); @@ -148,7 +151,7 @@ describe('GraphqlService', () => { it('should return a simple query with pagination set and nodes that includes at least "id" when the column definitions is an empty array', () => { const expectation = `query{ users(first:10, offset:0){ totalCount, nodes{ id }}}`; - const columns = []; + const columns: Column[] = []; service.init({ datasetName: 'users', columnDefinitions: columns }, paginationOptions, gridStub); const query = service.buildQuery(); @@ -188,7 +191,7 @@ describe('GraphqlService', () => { it('should return a simple query with pagination set and nodes that includes at least "id" when the column definitions is an empty array when using cursor', () => { const expectation = `query{users(first:20) { totalCount, nodes{id}, pageInfo{ hasNextPage,hasPreviousPage,endCursor,startCursor }, edges{ cursor }}}`; - const columns = []; + const columns: Column[] = []; service.init({ datasetName: 'users', columnDefinitions: columns, isWithCursor: true }, paginationOptions, gridStub); service.updatePagination(3, 20); @@ -442,7 +445,7 @@ describe('GraphqlService', () => { }); it('should return empty string when dataset name is undefined', () => { - service.init({ datasetName: undefined, columnDefinitions: [] }); + service.init({ datasetName: undefined as any, columnDefinitions: [] }); const output = service.getDatasetName(); expect(output).toBe(''); }); @@ -504,7 +507,7 @@ describe('GraphqlService', () => { } as FilterChangedArgs; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnFilterChanged(null, mockFilterChangedArgs); + const query = service.processOnFilterChanged(null as any, mockFilterChangedArgs); const currentFilters = service.getCurrentFilters(); expect(removeSpaces(query)).toBe(removeSpaces(expectation)); @@ -534,7 +537,7 @@ describe('GraphqlService', () => { } as FilterChangedArgs; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnFilterChanged(null, mockFilterChangedArgs); + const query = service.processOnFilterChanged(null as any, mockFilterChangedArgs); const currentFilters = service.getCurrentFilters(); expect(removeSpaces(query)).toBe(removeSpaces(expectation)); @@ -553,7 +556,7 @@ describe('GraphqlService', () => { const querySpy = jest.spyOn(service, 'buildQuery'); service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnPaginationChanged(null, { newPage: 3, pageSize: 20 }); + const query = service.processOnPaginationChanged(null as any, { newPage: 3, pageSize: 20 }); const currentPagination = service.getCurrentPagination(); expect(removeSpaces(query)).toBe(removeSpaces(expectation)); @@ -567,7 +570,7 @@ describe('GraphqlService', () => { service.init(serviceOptions, paginationOptions, gridStub); // @ts-ignore - const query = service.processOnPaginationChanged(null, { newPage: 3 }); + const query = service.processOnPaginationChanged(null as any, { newPage: 3 }); const currentPagination = service.getCurrentPagination(); expect(removeSpaces(query)).toBe(removeSpaces(expectation)); @@ -581,7 +584,7 @@ describe('GraphqlService', () => { service.init(serviceOptions, undefined, gridStub); // @ts-ignore - const query = service.processOnPaginationChanged(null, { newPage: 3 }); + const query = service.processOnPaginationChanged(null as any, { newPage: 3 }); const currentPagination = service.getCurrentPagination(); expect(removeSpaces(query)).toBe(removeSpaces(expectation)); @@ -598,7 +601,7 @@ describe('GraphqlService', () => { const mockSortChangedArgs = { columnId: 'gender', sortCol: mockColumn, sortAsc: false, multiColumnSort: false } as ColumnSort; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnSortChanged(null, mockSortChangedArgs); + const query = service.processOnSortChanged(null as any, mockSortChangedArgs); expect(removeSpaces(query)).toBe(removeSpaces(expectation)); expect(querySpy).toHaveBeenCalled(); @@ -616,7 +619,7 @@ describe('GraphqlService', () => { const mockSortChangedArgs = { sortCols: [mockColumnSort, mockColumnSortName], multiColumnSort: true, grid: gridStub } as MultiColumnSort; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnSortChanged(null, mockSortChangedArgs); + const query = service.processOnSortChanged(null as any, mockSortChangedArgs); expect(removeSpaces(query)).toBe(removeSpaces(expectation)); expect(querySpy).toHaveBeenCalled(); @@ -1050,7 +1053,7 @@ describe('GraphqlService', () => { const expectation = `query{users(first:10, offset:0, filterBy:[{field:gender, operator:EQ, value:""}]) { totalCount,nodes{ id,company,gender,name } }}`; const mockColumn = { id: 'gender', field: 'gender' } as Column; const mockColumnFilters = { - gender: { columnId: 'gender', columnDef: mockColumn, searchTerms: [undefined], operator: 'EQ', type: FieldType.string }, + gender: { columnId: 'gender', columnDef: mockColumn, searchTerms: [undefined as any], operator: 'EQ', type: FieldType.string }, } as ColumnFilters; service.init(serviceOptions, paginationOptions, gridStub); @@ -1121,6 +1124,8 @@ describe('GraphqlService', () => { }); describe('presets', () => { + let mockColumns: Column[] = []; + beforeEach(() => { serviceOptions.columnDefinitions = [{ id: 'company', field: 'company' }, { id: 'gender', field: 'gender' }, { id: 'duration', field: 'duration', type: FieldType.number }, { id: 'startDate', field: 'startDate' }]; }); @@ -1128,9 +1133,29 @@ describe('GraphqlService', () => { it('should return a query with search having a range of exclusive numbers when the search value contains 2 dots (..) to represent a range of numbers', () => { const expectation = `query{users(first:10, offset:0, filterBy:[{field:duration, operator:GE, value:"2"}, {field:duration, operator:LE, value:"33"}]) { totalCount,nodes{ id,company,gender,duration,startDate } }}`; - const presetFilters = [ - { columnId: 'duration', searchTerms: ['2..33'] }, - ] as CurrentFilter[]; + const presetFilters = [{ columnId: 'duration', searchTerms: ['2..33'] }] as CurrentFilter[]; + + service.init(serviceOptions, paginationOptions, gridStub); + service.updateFilters(presetFilters, true); + const query = service.buildQuery(); + const currentFilters = service.getCurrentFilters(); + + expect(removeSpaces(query)).toBe(removeSpaces(expectation)); + expect(currentFilters).toEqual(presetFilters); + }); + + it('should return a query with all columns and search even when having hidden columns (basically when it is not part of the `getColumns()` return) when all passed are passed with the shared service', () => { + const expectation = `query{users(first:10, offset:0, filterBy:[{field:duration, operator:GE, value:"2"}, {field:duration, operator:LE, value:"33"}]) { + totalCount,nodes{ id,company,gender,duration,startDate } }}`; + const presetFilters = [{ columnId: 'duration', searchTerms: ['2..33'] }] as CurrentFilter[]; + const mockColumnsCopy = [...mockColumns]; + + // remove "Gender" column from `getColumns` (to simulate hidden field) + mockColumnsCopy.splice(1, 1); + jest.spyOn(gridStub, 'getColumns').mockReturnValue(mockColumnsCopy); + + // but still pass all columns to the service init + jest.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValue(mockColumns); service.init(serviceOptions, paginationOptions, gridStub); service.updateFilters(presetFilters, true); diff --git a/src/app/modules/angular-slickgrid/services/__tests__/grid-odata.service.spec.ts b/src/app/modules/angular-slickgrid/services/__tests__/grid-odata.service.spec.ts index 737c26d5f..bf14b5e45 100644 --- a/src/app/modules/angular-slickgrid/services/__tests__/grid-odata.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/__tests__/grid-odata.service.spec.ts @@ -15,6 +15,7 @@ import { CurrentSorter, OdataOption, } from '../../models'; +import { SharedService } from '../shared.service'; const DEFAULT_ITEMS_PER_PAGE = 25; const DEFAULT_PAGE_SIZE = 20; @@ -28,7 +29,7 @@ const gridOptionMock = { process: jest.fn(), postProcess: jest.fn(), } -} as GridOption; +} as unknown as GridOption; const gridStub = { autosizeColumns: jest.fn(), @@ -47,9 +48,11 @@ describe('GridOdataService', () => { let service: GridOdataService; let paginationOptions: Pagination; let serviceOptions: OdataOption; + let sharedService: SharedService; beforeEach(() => { mockColumns = [{ id: 'field1', field: 'field1', width: 100 }, { id: 'field2', field: 'field2', width: 100 }]; + sharedService = new SharedService(); service = new GridOdataService(); serviceOptions = { columnDefinitions: mockColumns, @@ -64,7 +67,7 @@ describe('GridOdataService', () => { totalItems: 100 }; gridOptionMock.enablePagination = true; - gridOptionMock.backendServiceApi.service = service; + gridOptionMock.backendServiceApi!.service = service; }); afterEach(() => { @@ -119,7 +122,7 @@ describe('GridOdataService', () => { it('should return a simple query with pagination $top and $skip when using "updatePagination" method', () => { const expectation = `$top=20&$skip=40`; - const columns = []; + const columns: Column[] = []; service.init({ columnDefinitions: columns }, paginationOptions, gridStub); service.updatePagination(3, 20); @@ -191,7 +194,7 @@ describe('GridOdataService', () => { it('should not do anything when calling "updatePagination" method with "enablePagination" set to False', () => { const expectation = ''; - const columns = []; + const columns: Column[] = []; service.init({ columnDefinitions: columns }, paginationOptions, gridStub); service.updatePagination(3, 20); @@ -287,7 +290,7 @@ describe('GridOdataService', () => { } as FilterChangedArgs; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnFilterChanged(null, mockFilterChangedArgs); + const query = service.processOnFilterChanged(null as any, mockFilterChangedArgs); const currentFilters = service.getCurrentFilters(); expect(query).toBe(expectation); @@ -315,7 +318,7 @@ describe('GridOdataService', () => { } as FilterChangedArgs; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnFilterChanged(null, mockFilterChangedArgs); + const query = service.processOnFilterChanged(null as any, mockFilterChangedArgs); const currentFilters = service.getCurrentFilters(); expect(query).toBe(expectation); @@ -349,7 +352,7 @@ describe('GridOdataService', () => { } as FilterChangedArgs; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnFilterChanged(null, mockFilterChangedArgs); + const query = service.processOnFilterChanged(null as any, mockFilterChangedArgs); const currentFilters = service.getCurrentFilters(); expect(query).toBe(expectation); @@ -377,7 +380,7 @@ describe('GridOdataService', () => { } as FilterChangedArgs; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnFilterChanged(null, mockFilterChangedArgs); + const query = service.processOnFilterChanged(null as any, mockFilterChangedArgs); const currentFilters = service.getCurrentFilters(); expect(query).toBe(expectation); @@ -397,7 +400,7 @@ describe('GridOdataService', () => { const querySpy = jest.spyOn(service.odataService, 'buildQuery'); service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnPaginationChanged(null, { newPage: 3, pageSize: 20 }); + const query = service.processOnPaginationChanged(null as any, { newPage: 3, pageSize: 20 }); const currentPagination = service.getCurrentPagination(); expect(query).toBe(expectation); @@ -411,7 +414,7 @@ describe('GridOdataService', () => { service.init(serviceOptions, paginationOptions, gridStub); // @ts-ignore - const query = service.processOnPaginationChanged(null, { newPage: 3 }); + const query = service.processOnPaginationChanged(null as any, { newPage: 3 }); const currentPagination = service.getCurrentPagination(); expect(query).toBe(expectation); @@ -425,7 +428,7 @@ describe('GridOdataService', () => { service.init(serviceOptions, undefined, gridStub); // @ts-ignore - const query = service.processOnPaginationChanged(null, { newPage: 3 }); + const query = service.processOnPaginationChanged(null as any, { newPage: 3 }); const currentPagination = service.getCurrentPagination(); expect(query).toBe(expectation); @@ -439,7 +442,7 @@ describe('GridOdataService', () => { const querySpy = jest.spyOn(service.odataService, 'buildQuery'); service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnPaginationChanged(null, { newPage: 3, pageSize: 20 }); + const query = service.processOnPaginationChanged(null as any, { newPage: 3, pageSize: 20 }); const currentPagination = service.getCurrentPagination(); expect(query).toBe(expectation); @@ -456,7 +459,7 @@ describe('GridOdataService', () => { const mockSortChangedArgs = { columnId: 'gender', sortCol: mockColumn, sortAsc: false, multiColumnSort: false } as ColumnSort; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnSortChanged(null, mockSortChangedArgs); + const query = service.processOnSortChanged(null as any, mockSortChangedArgs); expect(query).toBe(expectation); expect(querySpy).toHaveBeenCalled(); @@ -472,7 +475,7 @@ describe('GridOdataService', () => { const mockSortChangedArgs = { sortCols: [mockColumnSort, mockColumnSortName], multiColumnSort: true, grid: gridStub } as MultiColumnSort; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnSortChanged(null, mockSortChangedArgs); + const query = service.processOnSortChanged(null as any, mockSortChangedArgs); expect(query).toBe(expectation); expect(querySpy).toHaveBeenCalled(); @@ -490,7 +493,7 @@ describe('GridOdataService', () => { const mockSortChangedArgs = { columnId: 'gender', sortCol: mockColumn, sortAsc: false, multiColumnSort: false } as ColumnSort; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnSortChanged(null, mockSortChangedArgs); + const query = service.processOnSortChanged(null as any, mockSortChangedArgs); expect(query).toBe(expectation); expect(querySpy).toHaveBeenCalled(); @@ -506,7 +509,7 @@ describe('GridOdataService', () => { const mockSortChangedArgs = { sortCols: [mockColumnSort, mockColumnSortName], multiColumnSort: true, grid: gridStub } as MultiColumnSort; service.init(serviceOptions, paginationOptions, gridStub); - const query = service.processOnSortChanged(null, mockSortChangedArgs); + const query = service.processOnSortChanged(null as any, mockSortChangedArgs); expect(query).toBe(expectation); expect(querySpy).toHaveBeenCalled(); @@ -826,7 +829,7 @@ describe('GridOdataService', () => { const expectation = `$top=10`; const mockColumn = { id: 'gender', field: 'gender' } as Column; const mockColumnFilters = { - gender: { columnId: 'gender', columnDef: mockColumn, searchTerms: [undefined], operator: 'EQ', type: FieldType.string }, + gender: { columnId: 'gender', columnDef: mockColumn, searchTerms: [undefined as any], operator: 'EQ', type: FieldType.string }, } as ColumnFilters; service.init(serviceOptions, paginationOptions, gridStub); @@ -1398,7 +1401,7 @@ describe('GridOdataService', () => { ] as CurrentSorter[]; service.init(serviceOptions, paginationOptions, gridStub); - service.updateSorters(null, mockCurrentSorter); + service.updateSorters(null as any, mockCurrentSorter); const query = service.buildQuery(); const currentSorters = service.getCurrentSorters(); @@ -1447,6 +1450,10 @@ describe('GridOdataService', () => { }); describe('presets', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + it('should return a query when using presets sorters array', () => { const expectation = `$top=10&$orderby=Company desc,FirstName asc`; const presets = [ @@ -1466,9 +1473,29 @@ describe('GridOdataService', () => { it('should return a query with a filter with range of numbers when the preset is a filter range with 2 dots (..) separator', () => { serviceOptions.columnDefinitions = [{ id: 'company', field: 'company' }, { id: 'gender', field: 'gender' }, { id: 'duration', field: 'duration', type: FieldType.number }]; const expectation = `$top=10&$filter=(Duration ge 4 and Duration le 88)`; - const presetFilters = [ - { columnId: 'duration', searchTerms: ['4..88'] }, - ] as CurrentFilter[]; + const presetFilters = [{ columnId: 'duration', searchTerms: ['4..88'] }] as CurrentFilter[]; + + service.init(serviceOptions, paginationOptions, gridStub); + service.updateFilters(presetFilters, true); + const query = service.buildQuery(); + const currentFilters = service.getCurrentFilters(); + + expect(query).toBe(expectation); + expect(currentFilters).toEqual(presetFilters); + }); + + it('should return a query with all columns and search even when having hidden columns (basically when it is not part of the `getColumns()` return) when all passed are passed with the shared service', () => { + serviceOptions.columnDefinitions = [{ id: 'company', field: 'company' }, { id: 'gender', field: 'gender' }, { id: 'duration', field: 'duration', type: FieldType.number }]; + const expectation = `$top=10&$filter=(Duration ge 4 and Duration le 88)`; + const presetFilters = [{ columnId: 'duration', searchTerms: ['4..88'] }] as CurrentFilter[]; + const mockColumnsCopy = [...serviceOptions.columnDefinitions]; + + // remove "Gender" column from `getColumns` (to simulate hidden field) + mockColumnsCopy.splice(1, 1); + jest.spyOn(gridStub, 'getColumns').mockReturnValue(mockColumnsCopy); + + // but still pass all columns to the service init + jest.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValue(mockColumns); service.init(serviceOptions, paginationOptions, gridStub); service.updateFilters(presetFilters, true); diff --git a/src/app/modules/angular-slickgrid/services/graphql.service.ts b/src/app/modules/angular-slickgrid/services/graphql.service.ts index 9d633d0aa..06e17ed1e 100644 --- a/src/app/modules/angular-slickgrid/services/graphql.service.ts +++ b/src/app/modules/angular-slickgrid/services/graphql.service.ts @@ -29,6 +29,7 @@ import { OperatorString } from './../models/index'; import QueryBuilder from './graphqlQueryBuilder'; +import { SharedService } from "./shared.service"; const DEFAULT_ITEMS_PER_PAGE = 25; const DEFAULT_PAGE_SIZE = 20; @@ -38,7 +39,7 @@ export class GraphqlService implements BackendService { private _currentFilters: ColumnFilters | CurrentFilter[] = []; private _currentPagination?: CurrentPagination; private _currentSorters: CurrentSorter[] = []; - private _columnDefinitions!: Column[]; + private _columnDefinitions?: Column[]; private _grid: any; private _datasetIdPropName = 'id'; options!: GraphqlServiceOption; @@ -59,14 +60,14 @@ export class GraphqlService implements BackendService { } /** Initialization of the service, which acts as a constructor */ - init(serviceOptions?: GraphqlServiceOption | undefined, pagination?: Pagination, grid?: any): void { + init(serviceOptions?: GraphqlServiceOption | undefined, pagination?: Pagination, grid?: any, sharedService?: SharedService): void { this._grid = grid; this.options = serviceOptions || { datasetName: '', columnDefinitions: [] }; this.pagination = pagination; this._datasetIdPropName = this._gridOptions.datasetIdPropertyName || 'id'; - if (grid && grid.getColumns) { - this._columnDefinitions = (serviceOptions && serviceOptions.columnDefinitions) || grid.getColumns(); + if (grid?.getColumns) { + this._columnDefinitions = sharedService?.allColumns ?? serviceOptions?.columnDefinitions ?? grid.getColumns(); } } @@ -81,7 +82,7 @@ export class GraphqlService implements BackendService { // get the column definitions and exclude some if they were tagged as excluded let columnDefinitions = this._columnDefinitions || this.options.columnDefinitions; - columnDefinitions = columnDefinitions.filter((column: Column) => !column.excludeFromQuery); + columnDefinitions = columnDefinitions?.filter((column: Column) => !column.excludeFromQuery); const queryQb = new QueryBuilder('query'); const datasetQb = new QueryBuilder(this.options.datasetName); @@ -520,7 +521,7 @@ export class GraphqlService implements BackendService { // display the correct sorting icons on the UI, for that it requires (columnId, sortAsc) properties const tmpSorterArray = currentSorters.map((sorter) => { - const columnDef = this._columnDefinitions.find((column: Column) => column.id === sorter.columnId); + const columnDef = this._columnDefinitions?.find((column: Column) => column.id === sorter.columnId); graphqlSorters.push({ field: columnDef ? ((columnDef.queryFieldSorter || columnDef.queryField || columnDef.field) + '') : (sorter.columnId + ''), diff --git a/src/app/modules/angular-slickgrid/services/grid-odata.service.ts b/src/app/modules/angular-slickgrid/services/grid-odata.service.ts index db4c3668c..dee9bbf92 100644 --- a/src/app/modules/angular-slickgrid/services/grid-odata.service.ts +++ b/src/app/modules/angular-slickgrid/services/grid-odata.service.ts @@ -25,6 +25,7 @@ import { SearchTerm } from './../models/index'; import { OdataQueryBuilderService } from './odataQueryBuilder.service'; +import { SharedService } from './shared.service'; const DEFAULT_ITEMS_PER_PAGE = 25; const DEFAULT_PAGE_SIZE = 20; @@ -64,7 +65,7 @@ export class GridOdataService implements BackendService { this._odataService = new OdataQueryBuilderService(); } - init(serviceOptions: Partial | undefined, pagination?: Pagination, grid?: any): void { + init(serviceOptions: Partial | undefined, pagination?: Pagination, grid?: any, sharedService?: SharedService): void { this._grid = grid; const mergedOptions = { ...this.defaultOptions, ...serviceOptions }; @@ -85,9 +86,9 @@ export class GridOdataService implements BackendService { this.options = this._odataService.options; this.pagination = pagination; - if (grid && grid.getColumns) { - this._columnDefinitions = serviceOptions && serviceOptions.columnDefinitions || grid.getColumns(); - this._columnDefinitions = this._columnDefinitions.filter((column: Column) => !column.excludeFromQuery); + if (grid?.getColumns) { + const tmpColumnDefinitions = sharedService?.allColumns ?? serviceOptions?.columnDefinitions ?? grid.getColumns(); + this._columnDefinitions = tmpColumnDefinitions.filter((column: Column) => !column.excludeFromQuery); } } diff --git a/test/cypress/integration/example06.spec.js b/test/cypress/integration/example06.spec.js index 0f627ab03..2c0ae2877 100644 --- a/test/cypress/integration/example06.spec.js +++ b/test/cypress/integration/example06.spec.js @@ -65,7 +65,7 @@ describe('Example 6 - GraphQL Grid', () => { {field:"gender",operator:EQ,value:"male"},{field:"name",operator:Contains,value:"JohnDoe"}, {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"} ],locale:"en",userId:123){ - totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -83,7 +83,7 @@ describe('Example 6 - GraphQL Grid', () => { filterBy:[ {field:"gender",operator:EQ,value:"male"},{field:"name",operator:Contains,value:"JohnDoe"}, {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"} - ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -101,7 +101,7 @@ describe('Example 6 - GraphQL Grid', () => { filterBy:[ {field:"gender",operator:EQ,value:"male"},{field:"name",operator:Contains,value:"JohnDoe"}, {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"} - ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -123,7 +123,7 @@ describe('Example 6 - GraphQL Grid', () => { {field:"company",operator:IN,value:"xyz"}, {field:"finish",operator:GE,value:"${presetLowestDay}"}, {field:"finish",operator:LE,value:"${presetHighestDay}"} - ],locale:"en",userId:123) { totalCount, nodes { id,name,gender,company,billing{address{zip,street}},finish } } }`)); + ],locale:"en",userId:123) { totalCount, nodes { id,name,gender,company,billing{address{street,zip}},finish } } }`)); }); }); @@ -142,7 +142,7 @@ describe('Example 6 - GraphQL Grid', () => { filterBy:[ {field:"gender",operator:EQ,value:"male"},{field:"name",operator:Contains,value:"JohnDoe"}, {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"} - ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -162,7 +162,7 @@ describe('Example 6 - GraphQL Grid', () => { filterBy:[ {field:"gender",operator:EQ,value:"male"},{field:"name",operator:Contains,value:"JohnDoe"}, {field:"company",operator:IN,value:"xyz"},{field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"} - ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -193,7 +193,7 @@ describe('Example 6 - GraphQL Grid', () => { filterBy:[ {field:"gender",operator:EQ,value:"male"},{field:"company",operator:IN,value:"xyz"}, {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"} - ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -223,7 +223,7 @@ describe('Example 6 - GraphQL Grid', () => { filterBy:[ {field:"gender",operator:EQ,value:"male"},{field:"company",operator:IN,value:"xyz"}, {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"} - ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + ],locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -252,7 +252,7 @@ describe('Example 6 - GraphQL Grid', () => { expect(text).to.eq(removeSpaces(`query{users(first:30,offset:0, orderBy:[{field:"name",direction:ASC},{field:"company",direction:DESC}], filterBy:[{field:"gender",operator:EQ,value:"male"},{field:"company",operator:IN,value:"xyz"}], - locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -265,7 +265,7 @@ describe('Example 6 - GraphQL Grid', () => { cy.get('[data-test=graphql-query-result]') .should(($span) => { const text = removeSpaces($span.text()); // remove all white spaces - expect(text).to.eq(removeSpaces(`query{users(first:30,offset:0,locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + expect(text).to.eq(removeSpaces(`query{users(first:30,offset:0,locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -287,7 +287,7 @@ describe('Example 6 - GraphQL Grid', () => { const text = removeSpaces($span.text()); // remove all white spaces expect(text).to.eq(removeSpaces(`query{users(first:30,offset:0, orderBy:[{field:"name",direction:ASC}], - locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + locale:"en",userId:123){totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -333,7 +333,7 @@ describe('Example 6 - GraphQL Grid', () => { filterBy:[{field:"gender",operator:EQ,value:"female"},{field:"name",operator:StartsWith,value:"Jane"}, {field:"company",operator:IN,value:"acme"},{field:"billing.address.zip",operator:GE,value:"11"}, {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}],locale:"en",userId:123) - {totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + {totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); @@ -370,7 +370,7 @@ describe('Example 6 - GraphQL Grid', () => { const text = removeSpaces($span.text()); // remove all white spaces expect(text).to.eq(removeSpaces(`query{users(first:30,offset:0, orderBy:[{field:"billing.address.zip",direction:DESC},{field:"company",direction:ASC}],locale:"en",userId:123){ - totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); }); }); @@ -612,7 +612,7 @@ describe('Example 6 - GraphQL Grid', () => { filterBy:[{field:"gender",operator:EQ,value:"female"},{field:"name",operator:StartsWith,value:"Jane"}, {field:"company",operator:IN,value:"acme"},{field:"billing.address.zip",operator:GE,value:"11"}, {field:"finish",operator:GE,value:"${presetLowestDay}"},{field:"finish",operator:LE,value:"${presetHighestDay}"}],locale:"fr",userId:123) - {totalCount,nodes{id,name,gender,company,billing{address{zip,street}},finish}}}`)); + {totalCount,nodes{id,name,gender,company,billing{address{street,zip}},finish}}}`)); }); });