Skip to content

Commit

Permalink
feat(footer): add custom footer to show metrics
Browse files Browse the repository at this point in the history
- this footer is typically only available when user is not using a Backend Service since they show the same kind of info
  • Loading branch information
ghiscoding-SE committed Jan 13, 2020
1 parent 6f375c9 commit 2054319
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 5 deletions.
4 changes: 3 additions & 1 deletion src/app/examples/grid-clientside.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ export class GridClientSideComponent implements OnInit {
{ columnId: 'duration', direction: 'DESC' },
{ columnId: 'complete', direction: 'ASC' }
],
}
},
showCustomFooter: true
};

// mock a dataset
Expand Down Expand Up @@ -272,6 +273,7 @@ export class GridClientSideComponent implements OnInit {
setTimeout(() => {
this.metrics = {
startTime: new Date(),
endTime: new Date(),
itemCount: args && args.current || 0,
totalItemCount: this.dataset.length || 0
};
Expand Down
11 changes: 11 additions & 0 deletions src/app/examples/grid-localization.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ export class GridLocalizationComponent implements OnInit {
enableFiltering: true,
enableTranslate: true,
i18n: this.translate,
customFooterOptions: {
leftFooterText: 'text shown on left container', // optionally display some text on left footer container
metricTexts: {
textItems: 'TEXT_ITEMS',
textOf: 'TEXT_OF',
// lastUpdatedText: 'Last Updated',
},
dateFormat: 'yyyy-MM-dd HH:mm aaaaa\'m\'',
hideTotalItemCount: false,
},
showCustomFooter: true,
excelExportOptions: {
// optionally pass a custom header to the Excel Sheet
// a lot of the info can be found on Web Archive of Excel-Builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { Column, CurrentFilter, CurrentSorter, GridOption, GridState, GridStateC
import { Filters } from '../../filters';
import { Editors } from '../../editors';
import * as utilities from '../../services/backend-utilities';
import { GraphqlPaginatedResult } from 'dist/public_api';


const mockExecuteBackendProcess = jest.fn();
Expand Down Expand Up @@ -593,7 +594,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
const spy = jest.spyOn(component, 'refreshGridData');

component.ngAfterViewInit();
component.gridOptions.backendServiceApi.internalPostProcess({ data: { users: { nodes: [{ firstName: 'John' }], pageInfo: { hasNextPage: false }, totalCount: 2 } } });
component.gridOptions.backendServiceApi.internalPostProcess({ data: { users: { nodes: [{ firstName: 'John' }], totalCount: 2 } } } as GraphqlPaginatedResult);

expect(spy).toHaveBeenCalled();
expect(component.gridOptions.backendServiceApi.internalPostProcess).toEqual(expect.any(Function));
Expand All @@ -617,7 +618,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
const spy = jest.spyOn(component, 'refreshGridData');

component.ngAfterViewInit();
component.gridOptions.backendServiceApi.internalPostProcess({ data: { notUsers: { nodes: [{ firstName: 'John' }], pageInfo: { hasNextPage: false }, totalCount: 2 } } });
component.gridOptions.backendServiceApi.internalPostProcess({ data: { notUsers: { nodes: [{ firstName: 'John' }], totalCount: 2 } } } as GraphqlPaginatedResult);

expect(spy).not.toHaveBeenCalled();
expect(component.dataset).toEqual([]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,24 @@
[dataView]="dataView" [grid]="grid" [options]="paginationOptions" [locales]="locales" [totalItems]="totalItems"
[backendServiceApi]="backendServiceApi">
</slick-pagination>

<div *ngIf="showCustomFooter && gridOptions" class="slick-custom-footer" style="width: 100%;">
<div class="left-footer col-xs-6">
{{gridOptions.customFooterOptions?.leftFooterText}}
</div>

<div class="right-footer metrics col-xs-6" *ngIf="metrics && !gridOptions.customFooterOptions?.hideMetrics">
<span *ngIf="!gridOptions.customFooterOptions?.hideLastUpdatedTimestamp">
<span>{{gridOptions.customFooterOptions?.metricTexts?.lastUpdatedText}}</span>
{{metrics.endTime | date: gridOptions.customFooterOptions?.dateFormat}}
<span>{{gridOptions.customFooterOptions?.metricSeparator}}</span>
</span>
{{metrics.itemCount}}
<span
*ngIf="!gridOptions.customFooterOptions?.hideTotalItemCount">{{gridOptions.customFooterOptions?.metricTexts?.textOf}}
{{metrics.totalItemCount}}
</span>
{{gridOptions.customFooterOptions?.metricTexts?.textItems}}
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ import {
GridStateChange,
GridStateType,
Locale,
Metrics,
Pagination,
SlickEventHandler,
} from './../models/index';
import { FilterFactory } from '../filters/filterFactory';
import { SlickgridConfig } from '../slickgrid-config';
import { isObservable, Observable, Subscription, Subject } from 'rxjs';
import { isObservable, Observable, Subscription } from 'rxjs';

// Services
import { AngularUtilService } from '../services/angularUtil.service';
Expand Down Expand Up @@ -125,7 +126,10 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
groupItemMetadataProvider: any;
backendServiceApi: BackendServiceApi;
locales: Locale;
metrics: Metrics;
metricsDateFormat = 'yyyy-MM-dd HH:mm aaaaa\'m\'';
paginationOptions: Pagination;
showCustomFooter = false;
showPagination = false;
totalItems = 0;
isGridInitialized = false;
Expand Down Expand Up @@ -394,6 +398,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
this.extensionService.translateContextMenu();
this.extensionService.translateGridMenu();
this.extensionService.translateHeaderMenu();
this.translateCustomFooterTexts();
}
})
);
Expand Down Expand Up @@ -472,7 +477,16 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
this.gridEventService.bindOnClick(grid, dataView);

if (dataView && grid) {
this._eventHandler.subscribe(dataView.onRowCountChanged, () => grid.invalidate());
this._eventHandler.subscribe(dataView.onRowCountChanged, (e: Event, args: any) => {
grid.invalidate();

this.metrics = {
startTime: new Date(),
endTime: new Date(),
itemCount: args && args.current || 0,
totalItemCount: this.dataset.length || 0
};
});

// without this, filtering data with local dataset will not always show correctly
// also don't use "invalidateRows" since it destroys the entire row and as bad user experience when updating a row
Expand Down Expand Up @@ -727,6 +741,9 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
/** @deprecated please use "extensionService" instead */
pluginService: this.extensionService,
});

// user could show a custom footer with the data metrics (dataset length and last updated timestamp)
this.showCustomFooterWithMetrics();
}

/** Load the Editor Collection asynchronously and replace the "collection" property when Observable resolves */
Expand Down Expand Up @@ -763,6 +780,21 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
return options;
}

private showCustomFooterWithMetrics() {
setTimeout(() => {
if (this.gridOptions && !(this.gridOptions.backendServiceApi || this.gridOptions.enablePagination)) {
this.showCustomFooter = this.gridOptions.hasOwnProperty('showCustomFooter') ? this.gridOptions.showCustomFooter : true;
}
});

if (this.gridOptions.enableTranslate || this.gridOptions.i18n) {
this.translateCustomFooterTexts();
} else {
this.gridOptions.customFooterOptions.metricTexts.textItems = this.locales && this.locales.TEXT_ITEMS || 'TEXT_ITEMS';
this.gridOptions.customFooterOptions.metricTexts.textOf = this.locales && this.locales.TEXT_OF || 'TEXT_OF';
}
}

/**
* For convenience to the user, we provide the property "editor" as an Angular-Slickgrid editor complex object
* however "editor" is used internally by SlickGrid for it's own Editor Factory
Expand All @@ -779,6 +811,14 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
});
}

/** Translate all Custom Footer Texts (footer with metrics) */
private translateCustomFooterTexts() {
if (this.gridOptions && this.gridOptions.customFooterOptions && this.gridOptions.customFooterOptions.metricTexts) {
this.gridOptions.customFooterOptions.metricTexts.textItems = this.translate.instant('ITEMS');
this.gridOptions.customFooterOptions.metricTexts.textOf = this.translate.instant('OF');
}
}

/**
* Update the Editor "collection" property from an async call resolved
* Since this is called after the async call resolves, the pointer will not be the same as the "column" argument passed.
Expand Down
9 changes: 9 additions & 0 deletions src/app/modules/angular-slickgrid/global-grid-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ export const GlobalGridOptions: GridOption = {
iconExportTextDelimitedCommand: 'fa fa-download',
width: 200,
},
customFooterOptions: {
dateFormat: 'yyyy-MM-dd HH:mm aaaaa\'m\'',
hideTotalItemCount: false,
metricSeparator: '|',
metricTexts: {
textItems: 'TEXT_ITEMS',
textOf: 'OF',
}
},
datasetIdPropertyName: 'id',
defaultFilter: Filters.input,
enableFilterTrimWhiteSpace: false, // do we want to trim white spaces on all Filters?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export interface CustomFooterOption {
/** Optionally pass some text to be displayed on the left side (in the "left-footer" css class) */
leftFooterText?: string;

/** Date format used when showing the startTime/endTime metrics on screen */
dateFormat?: string;

/** Defaults to false, do we want to hide the last updated timestamp (endTime)? */
hideLastUpdatedTimestamp?: boolean;

/** Defaults to false, do we want to hide the metrics when the footer is displayed? */
hideMetrics?: boolean;

/** Defaults to false, do we want to hide the total item count of the entire dataset (the count exclude any filtered data) */
hideTotalItemCount?: boolean;

/** Defaults to "|", separator between the timestamp and the total count */
metricSeparator?: string;

metricTexts?: {
/** Optionally pass a text to display before the metrics endTime timestamp shown in the footer */
lastUpdatedText?: string;

textItems: string;
textLastUpdated?: string;
textOf: string;
}
}
13 changes: 13 additions & 0 deletions src/app/modules/angular-slickgrid/models/gridOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
RowDetailView,
RowMoveManager
} from './index';
import { CustomFooterOption } from './customFooterOption.interface';

export interface GridOption {
/** CSS class name used on newly added row */
Expand Down Expand Up @@ -101,6 +102,9 @@ export interface GridOption {
/** Default to false, which leads to create an extra pre-header panel (on top of column header) for column grouping purposes */
createPreHeaderPanel?: boolean;

/** Custom Footer Options */
customFooterOptions?: CustomFooterOption;

/** Data item column value extractor (getter) that can be used by the Excel like copy buffer plugin */
dataItemColumnValueExtractor?: (item: any, columnDef: Column) => any;

Expand Down Expand Up @@ -368,12 +372,21 @@ export interface GridOption {
/** Do we want to show cell selection? */
showCellSelection?: boolean;

/**
* Do we want to show a custom footer with some metrics?
* By default it will show how many items are in the dataset and when was last update done (timestamp)
* */
showCustomFooter?: boolean;

/** Do we want to show the footer row? */
showFooterRow?: boolean;

/** Do we want to show header row? */
showHeaderRow?: boolean;

/** Do we want to show metrics in custom footer? (dataset length, data filtered, last update timestamp) */
showFooterMetrics?: boolean;

/** Do we want to show the extra pre-header panel (on top of column header) for column grouping purposes */
showPreHeaderPanel?: boolean;

Expand Down
1 change: 1 addition & 0 deletions src/app/modules/angular-slickgrid/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export * from './currentColumn.interface';
export * from './currentFilter.interface';
export * from './currentPagination.interface';
export * from './currentSorter.interface';
export * from './customFooterOption.interface';
export * from './delimiterType.enum';
export * from './draggableGrouping.interface';
export * from './editCommand.interface';
Expand Down
6 changes: 6 additions & 0 deletions src/app/modules/angular-slickgrid/services/resizer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ declare var $: any;
const DATAGRID_MIN_HEIGHT = 180;
const DATAGRID_MIN_WIDTH = 300;
const DATAGRID_BOTTOM_PADDING = 20;
const DATAGRID_FOOTER_HEIGHT = 20;
const DATAGRID_PAGINATION_HEIGHT = 35;

export interface GridDimension {
Expand Down Expand Up @@ -87,6 +88,11 @@ export class ResizerService {
bottomPadding += DATAGRID_PAGINATION_HEIGHT;
}

// optionally show a custom footer with the data metrics (dataset length and last updated timestamp)
if (bottomPadding && gridOptions.showCustomFooter) {
bottomPadding += DATAGRID_FOOTER_HEIGHT;
}

let gridHeight = 0;
let gridOffsetTop = 0;

Expand Down
14 changes: 14 additions & 0 deletions src/app/modules/angular-slickgrid/styles/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,17 @@ $viewport-border-top: 0 none !default;
$viewport-border-right: 0 none !default;
$viewport-border-bottom: 0 none !default;
$viewport-border-left: 0 none !default;

/* Custom Footer */
$footer-bg-color: transparent !default;
$footer-font-style: italic !default;
$footer-font-weight: normal !default;
$footer-left-font-style: italic !default;
$footer-left-font-weight: normal !default;
$footer-left-text-align: left !default;
$footer-metrics-text-align: right !default;
$footer-metrics-font-style: italic !default;
$footer-metrics-font-weight: normal !default;
$footer-metrics-text-align: right !default;
$footer-text-color: #6e6e6e !default;
$footer-padding: 5px !default;
20 changes: 20 additions & 0 deletions src/app/modules/angular-slickgrid/styles/slick-footer.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.slick-custom-footer {
color: $footer-text-color;
padding: $footer-padding;
background-color: $footer-bg-color;
font-style: $footer-font-style;
font-weight: $footer-font-weight;

.left-footer {
font-style: $footer-left-font-style;
font-weight: $footer-left-font-weight;
text-align: $footer-left-text-align;
}

.metrics {
text-align: $footer-metrics-text-align;
font-style: $footer-metrics-font-style;
font-weight: $footer-metrics-font-weight;
text-align: $footer-metrics-text-align;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@import './slick-plugins';
@import './slick-default-theme';
@import './slick-pagination';
@import './slick-footer';
@import './slickgrid-examples';
@import './slick-bootstrap';
@import './bootstrap-jquery-ui-autocomplete';

0 comments on commit 2054319

Please sign in to comment.