Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions src/app/examples/grid-graphql-nopage.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ import { Observable } from 'rxjs';

const COUNTRIES_API = 'https://countries.trevorblades.com/';

export interface Country {
countryCode: string;
countryName: string;
countryNative: string;
countryPhone: number;
countryCurrency: string;
countryEmoji: string;
continentCode: string;
continentName: string;
languageCode: string;
languageName: string;
languageNative: string;
};

@Component({
templateUrl: './grid-graphql-nopage.component.html',
styleUrls: ['./grid-graphql-nopage.component.scss'],
Expand Down Expand Up @@ -155,7 +169,7 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
// you can define the onInit callback OR enable the "executeProcessCommandOnInit" flag in the service init
preProcess: () => !this.isDataLoaded ? this.displaySpinner(true) : '',
process: (query) => this.getCountries(query),
postProcess: (result: GraphqlResult) => {
postProcess: (result: GraphqlResult<Country>) => {
this.metrics = result.metrics;
this.displaySpinner(false);
this.isDataLoaded = true;
Expand All @@ -178,8 +192,8 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
// --

/** Calling the GraphQL backend API to get the Countries with the Query created by the "process" method of GraphqlService */
getCountries(query: string): Observable<GraphqlResult> {
return this.http.post<GraphqlResult>(COUNTRIES_API, { query });
getCountries(query: string): Observable<GraphqlResult<Country>> {
return this.http.post<GraphqlResult<Country>>(COUNTRIES_API, { query });
}

/**
Expand All @@ -189,7 +203,7 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
*/
getContinents() {
const continentQuery = `query { continents { code, name }}`;
return this.http.post<GraphqlResult>(COUNTRIES_API, { query: continentQuery });
return this.http.post<GraphqlResult<Country>>(COUNTRIES_API, { query: continentQuery });
}

/**
Expand All @@ -199,6 +213,6 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
*/
getLanguages() {
const languageQuery = `query { languages { code, name }}`;
return this.http.post<GraphqlResult>(COUNTRIES_API, { query: languageQuery });
return this.http.post<GraphqlResult<Country>>(COUNTRIES_API, { query: languageQuery });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
BackendServiceApi,
BackendServiceOption,
Column,
ColumnEditor,
CustomFooterOption,
ExtensionName,
GraphqlPaginatedResult,
Expand Down Expand Up @@ -914,7 +915,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn

/** Load the Editor Collection asynchronously and replace the "collection" property when Observable resolves */
private loadEditorCollectionAsync(column: Column) {
const collectionAsync = column && column.editor && column.editor.collectionAsync;
const collectionAsync = column && column.editor && (column.editor as ColumnEditor).collectionAsync;
if (collectionAsync instanceof Observable) {
this.subscriptions.push(
collectionAsync.subscribe((resolvedCollection) => this.updateEditorCollection(column, resolvedCollection))
Expand Down Expand Up @@ -1083,14 +1084,14 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
* Since this is called after the async call resolves, the pointer will not be the same as the "column" argument passed.
* Once we found the new pointer, we will reassign the "editor" and "collection" to the "internalColumnEditor" so it has newest collection
*/
private updateEditorCollection(column: Column, newCollection: any[]) {
column.editor.collection = newCollection;
private updateEditorCollection<T = any>(column: Column<T>, newCollection: T[]) {
(column.editor as ColumnEditor).collection = newCollection;

// find the new column reference pointer
const columns = this.grid.getColumns();
if (Array.isArray(columns)) {
const columnRef: Column = columns.find((col: Column) => col.id === column.id);
columnRef.internalColumnEditor = column.editor;
columnRef.internalColumnEditor = column.editor as ColumnEditor;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class DualInputEditor implements Editor {
const columnId = this.columnDef && this.columnDef.id;
const elements = document.querySelectorAll(`.dual-editor-text.editor-${columnId}`);
if (elements.length > 0) {
elements.forEach((elm) => elm.removeEventListener('focusout', () => { }));
elements.forEach((elm) => elm.removeEventListener('focusout', this.handleFocusOut.bind(this)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ export class ExtensionUtility {
* @params items array
* @param property name to sort with
*/
sortItems(items: any[], propertyName: string) {
sortItems<T = any>(items: T[], propertyName: string) {
// sort the custom items by their position in the list
if (Array.isArray(items)) {
items.sort((itemA: any, itemB: any) => {
items.sort((itemA: T, itemB: T) => {
if (itemA && itemB && itemA.hasOwnProperty(propertyName) && itemB.hasOwnProperty(propertyName)) {
return itemA[propertyName] - itemB[propertyName];
}
Expand All @@ -142,7 +142,7 @@ export class ExtensionUtility {
}

/** Translate the an array of items from an input key and assign to the output key */
translateItems(items: any[], inputKey: string, outputKey: string) {
translateItems<T = any>(items: T[], inputKey: string, outputKey: string) {
if (Array.isArray(items)) {
for (const item of items) {
if (item[inputKey]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export class RowDetailViewExtension implements Extension {
this.rowDetailViewOptions.onAsyncEndUpdate(e, args);
}
});
this._eventHandler.subscribe(this._addon.onAfterRowDetailToggle, (e: any, args: { grid: any; item: any; expandedRows: any[]; }) => {
this._eventHandler.subscribe(this._addon.onAfterRowDetailToggle, (e: any, args: { grid: any; item: any; expandedRows: number[]; }) => {
// display preload template & re-render all the other Detail Views after toggling
// the preload View will eventually go away once the data gets loaded after the "onAsyncEndUpdate" event
this.renderPreloadView();
Expand Down
11 changes: 6 additions & 5 deletions src/app/modules/angular-slickgrid/models/column.interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CellMenu } from './cellMenu.interface';
import { ColumnEditor } from './columnEditor.interface';
import { ColumnFilter } from './columnFilter.interface';
import { Editor } from './editor.interface';
import { EditorValidator } from './editorValidator.interface';
import { FieldType } from './fieldType.enum';
import { Formatter } from './formatter.interface';
Expand All @@ -11,9 +12,9 @@ import { MenuCommandItem } from './menuCommandItem.interface';
import { OnEventArgs } from './onEventArgs.interface';
import { Sorter } from './sorter.interface';

export interface Column {
export interface Column<T = any> {
/** async background post-rendering formatter */
asyncPostRender?: (domCellNode: any, row: number, dataContext: any, columnDef: Column) => void;
asyncPostRender?: (domCellNode: any, row: number, dataContext: T, columnDef: Column) => void;

/** Row Move Behavior, used by the Row Move Manager Plugin */
behavior?: string;
Expand All @@ -37,7 +38,7 @@ export interface Column {
colspan?: number | '*';

/** Data key, for example this could be used as a property key for complex object comparison (e.g. dataKey: 'id') */
dataKey?: any;
dataKey?: string;

/** Do we want default sort to be ascending? True by default */
defaultSortAsc?: boolean;
Expand Down Expand Up @@ -148,7 +149,7 @@ export interface Column {
internalColumnEditor?: ColumnEditor;

/** Label key, for example this could be used as a property key for complex object label display (e.g. dataKey: 'name') */
labelKey?: any;
labelKey?: string;

/** Maximum Width of the column in pixels (number only). */
maxWidth?: number;
Expand Down Expand Up @@ -190,7 +191,7 @@ export interface Column {
* @param {string} item data context
* @return {string} name of the Field that will end up being used to query
*/
queryFieldNameGetterFn?: (dataContext: any) => string;
queryFieldNameGetterFn?: (dataContext: T) => string;

/**
* Similar to "queryField" but only used when Filtering (please note that it has higher precendence over "queryField").
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export interface DataView {
getItemByIdx(idx: number): number;

/** Get row index in the dataset by its Id */
getIdxById(id: string | number): number;
getIdxById(id: string | number): number | undefined;

/** Get item metadata at specific index */
getItemMetadata(index: number): any;
Expand All @@ -96,7 +96,7 @@ export interface DataView {
getRowByItem(item: any): number;

/** Get row number of an item in the dataset by its Id */
getRowById(id: string | number): number;
getRowById(id: string | number): number | undefined;

/** Insert an item to the dataset before a specific index */
insertItem(insertBefore: number, item: any): void;
Expand Down Expand Up @@ -173,7 +173,7 @@ export interface DataView {
updateIdxById(startingIndex: number): void;

/** Update an item in the dataset by its Id */
updateItem(id: string | number, item: any): void;
updateItem<T = any>(id: string | number, item: T): void;

// ---------------------------
// Available DataView Events
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Metrics } from './metrics.interface';
import { Statistic } from './statistic.interface';

export interface GraphqlPaginatedResult {
export interface GraphqlPaginatedResult<T = any> {
data: {
[datasetName: string]: {
/** result set of data objects (array of data) */
nodes: any[];
nodes: T[];

/** Total count of items in the table (needed for the Pagination to work) */
totalCount: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Metrics } from './metrics.interface';
import { Statistic } from './statistic.interface';

export interface GraphqlResult {
export interface GraphqlResult<T = any> {
data: {
[datasetName: string]: any[];
[datasetName: string]: T[];
};

/** Some metrics of the last executed query (startTime, endTime, executionTime, itemCount, totalItemCount) */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { GroupingComparerItem } from './groupingComparerItem.interface';
import { GroupingFormatterItem } from './groupingFormatterItem.interface';
import { SortDirectionNumber } from './sortDirectionNumber.enum';

export type GroupingGetterFunction = (value: any) => string;
export type GroupingGetterFunction<T = any> = (value: T) => string;

export interface Grouping {
export interface Grouping<T = any> {
/** Grouping Aggregators array */
aggregators?: Aggregator[];

Expand All @@ -31,7 +31,7 @@ export interface Grouping {
formatter?: (g: GroupingFormatterItem) => string;

/** Getter of the Column to be Grouped */
getter?: string | GroupingGetterFunction;
getter?: string | GroupingGetterFunction<T>;

/** Defaults to false, lazy load the Group Totals Calculation */
lazyTotalsCalculation?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export interface SlickGrid {
* Returns the databinding item at a given position.
* @param index Item index.
*/
getDataItem(index: number): any;
getDataItem<T = any>(index: number): T;

/** Returns the size of the databinding source. */
getDataLength(): number;
Expand Down
18 changes: 9 additions & 9 deletions src/app/modules/angular-slickgrid/services/collection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ import { sortByFieldType } from '../sorters/sorterUtilities';
import { uniqueArray } from './utilities';

@Injectable()
export class CollectionService {
export class CollectionService<T = any> {
constructor(@Optional() private translate: TranslateService) { }

/**
* Filter 1 or more items from a collection
* @param collection
* @param filterByOptions
*/
filterCollection(collection: any[], filterByOptions: CollectionFilterBy | CollectionFilterBy[], filterResultBy: FilterMultiplePassType | FilterMultiplePassTypeString | null = FilterMultiplePassType.chain): any[] {
let filteredCollection: any[] = [];
filterCollection(collection: T[], filterByOptions: CollectionFilterBy | CollectionFilterBy[], filterResultBy: FilterMultiplePassType | FilterMultiplePassTypeString | null = FilterMultiplePassType.chain): T[] {
let filteredCollection: T[] = [];

// when it's array, we will use the new filtered collection after every pass
// basically if input collection has 10 items on 1st pass and 1 item is filtered out, then on 2nd pass the input collection will be 9 items
Expand All @@ -50,8 +50,8 @@ export class CollectionService {
* @param collection
* @param filterBy
*/
singleFilterCollection(collection: any[], filterBy: CollectionFilterBy): any[] {
let filteredCollection: any[] = [];
singleFilterCollection(collection: T[], filterBy: CollectionFilterBy): T[] {
let filteredCollection: T[] = [];

if (filterBy) {
const objectProperty = filterBy.property;
Expand All @@ -71,14 +71,14 @@ export class CollectionService {
if (objectProperty) {
filteredCollection = collection.filter((item) => item[objectProperty].toString().indexOf(value.toString()) !== -1);
} else {
filteredCollection = collection.filter((item) => (item !== null && item !== undefined) && item.toString().indexOf(value.toString()) !== -1);
filteredCollection = collection.filter((item: any) => (item !== null && item !== undefined) && item.toString().indexOf(value.toString()) !== -1);
}
break;
case OperatorType.notContains:
if (objectProperty) {
filteredCollection = collection.filter((item) => item[objectProperty].toString().indexOf(value.toString()) === -1);
} else {
filteredCollection = collection.filter((item) => (item !== null && item !== undefined) && item.toString().indexOf(value.toString()) === -1);
filteredCollection = collection.filter((item: any) => (item !== null && item !== undefined) && item.toString().indexOf(value.toString()) === -1);
}
break;
case OperatorType.notEqual:
Expand All @@ -101,12 +101,12 @@ export class CollectionService {
* @param sortByOptions
* @param enableTranslateLabel
*/
sortCollection(columnDef: Column, collection: any[], sortByOptions: CollectionSortBy | CollectionSortBy[], enableTranslateLabel?: boolean): any[] {
sortCollection(columnDef: Column, collection: T[], sortByOptions: CollectionSortBy | CollectionSortBy[], enableTranslateLabel?: boolean): T[] {
if (enableTranslateLabel && (!this.translate || !this.translate.instant)) {
throw new Error('[Angular-Slickgrid] requires "ngx-translate" to be installed and configured when the grid option "enableTranslate" is enabled.');
}

let sortedCollection: any[] = [];
let sortedCollection: T[] = [];

if (sortByOptions) {
if (Array.isArray(sortByOptions)) {
Expand Down
Loading