Skip to content

Commit

Permalink
fix(resizer): few fixes & adjustments after trying in SF
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed Jul 5, 2021
1 parent d127ac7 commit 32e80ec
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 41 deletions.
3 changes: 2 additions & 1 deletion packages/common/src/global-grid-options.ts
Expand Up @@ -8,7 +8,8 @@ export const GlobalGridOptions: GridOption = {
autoEdit: false,
asyncEditorLoading: false,
autoFitColumnsOnFirstLoad: true,
autoFixResizeCountBeforeQuitting: 10,
autoFixResizeTimeout: 4 * 60 * 5, // interval is 250ms, so 4x is 1sec, so (4 * 60 * 60 = 5min)
autoFixResizeRequiredGoodCount: 5,
autoFixResizeWhenBrokenStyleDetected: false,
autoResize: {
applyResizeToContainer: true,
Expand Down
10 changes: 8 additions & 2 deletions packages/common/src/interfaces/gridOption.interface.ts
Expand Up @@ -83,8 +83,14 @@ export interface GridOption {
/** Defaults to false, which leads to automatically adjust the size (height) of the grid to display the entire content without any scrolling in the grid. */
autoHeight?: boolean;

/** Defaults to 10, when "autoFixResizeWhenBrokenStyleDetected" is enabled then how many time do we want to retry before quitting? */
autoFixResizeCountBeforeQuitting?: number;
/**
* Defaults to 60, when "autoFixResizeWhenBrokenStyleDetected" is enabled then what will be the delay timeout before quitting?
* Note that that the resize gets called every 250ms
*/
autoFixResizeTimeout?: number;

/** Defaults to 10, how many good resize count do we require before we assume that it's all good and we can stop calling a resize of the grid? (only works when `autoFixResizeWhenBrokenStyleDetected` is enabled) */
autoFixResizeRequiredGoodCount?: number;

/** Defaults to false, this is a patch for Salesforce since we don't always have access to tab change events. */
autoFixResizeWhenBrokenStyleDetected?: boolean;
Expand Down
26 changes: 4 additions & 22 deletions packages/common/src/services/__tests__/resizer.service.spec.ts
Expand Up @@ -60,31 +60,12 @@ describe('Resizer Service', () => {
let eventPubSubService: EventPubSubService;
let service: ResizerService;
let divContainer: HTMLDivElement;
let divPane: HTMLDivElement;
let divHeaderElm: HTMLDivElement;
let divViewportElm: HTMLDivElement;
let mockGridOptions: GridOption;

beforeEach(() => {
divContainer = document.createElement('div');
divContainer.innerHTML = template;
document.body.appendChild(divContainer);
// divContainer = document.createElement('div');
// divContainer.id = CONTAINER_ID;
// divContainer.style.height = '800px';
// divContainer.style.width = '600px';
// divContainer.className = GRID_UID;
// divPane = document.createElement('div');
// divPane.className = 'gridPane';
// divPane.style.width = '100%';
// divViewportElm = document.createElement('div');
// divViewportElm.className = `slick-viewport`;
// divHeaderElm = document.createElement('div');
// divHeaderElm.className = `slick-header`;
// divPane.appendChild(divViewportElm);
// divViewportElm.appendChild(divHeaderElm);
// divContainer.appendChild(divPane);
// document.body.appendChild(divContainer);

eventPubSubService = new EventPubSubService();
service = new ResizerService(eventPubSubService);
Expand Down Expand Up @@ -579,7 +560,10 @@ describe('Resizer Service', () => {

it('should try to resize grid when its UI is deemed broken and expect "resizeGridWhenStylingIsBrokenUntilCorrected" to be called on interval', (done) => {
const resizeSpy = jest.spyOn(service, 'resizeGrid').mockReturnValue(Promise.resolve({ height: 150, width: 350 }));
Object.defineProperty(document.querySelector(`.${GRID_UID}`), 'offsetParent', { writable: true, configurable: true, value: 55 });

mockGridOptions.autoFixResizeTimeout = 10;
mockGridOptions.autoFixResizeRequiredGoodCount = 5;
mockGridOptions.autoFixResizeWhenBrokenStyleDetected = true;
service.intervalRetryDelay = 1;
service.init(gridStub, divContainer);
Expand All @@ -597,10 +581,8 @@ describe('Resizer Service', () => {
expect(resizeSpy).toHaveBeenCalled();
expect(resizeSpy).toHaveBeenNthCalledWith(2);
expect(resizeSpy).toHaveBeenNthCalledWith(3);
expect(resizeSpy).toHaveBeenNthCalledWith(4);
// expect(resizeSpy).toHaveBeenCalledTimes(6);
done();
}, 50);
}, 20);
});

it('should try to resize grid when its UI is deemed broken and expect "resizeGridWhenStylingIsBrokenUntilCorrected" but it should stop whenever we force it', (done) => {
Expand Down
31 changes: 17 additions & 14 deletions packages/common/src/services/resizer.service.ts
Expand Up @@ -22,7 +22,6 @@ const DATAGRID_FOOTER_HEIGHT = 25;
const DATAGRID_PAGINATION_HEIGHT = 35;
const DATAGRID_MIN_HEIGHT = 180;
const DATAGRID_MIN_WIDTH = 300;
const DEFAULT_INTERVAL_MAX_RETRIES = 70;
const DEFAULT_INTERVAL_RETRY_DELAY = 250;

export class ResizerService {
Expand All @@ -36,7 +35,6 @@ export class ResizerService {
private _pageContainerElm!: any;
private _gridParentContainerElm!: HTMLElement;
private _intervalId!: NodeJS.Timeout;
private _intervalExecutionCounter = 0;
private _intervalRetryDelay = DEFAULT_INTERVAL_RETRY_DELAY;
private _isStopResizeIntervalRequested = false;
private _hasResizedByContentAtLeastOnce = false;
Expand Down Expand Up @@ -150,8 +148,7 @@ export class ResizerService {
}

// -- 1st resize the datagrid size at first load (we need this because the .on event is not triggered on first load)
// -- also we add a slight delay (in ms) so that we resize after the grid render is done
this.resizeGrid(10, newSizes)
this.resizeGrid()
.then(() => this.resizeGridWhenStylingIsBrokenUntilCorrected())
.catch((rejection: any) => console.log('Error:', rejection));

Expand Down Expand Up @@ -261,7 +258,7 @@ export class ResizerService {
* @param {object} event that triggered the resize, defaults to null
* @return If the browser supports it, we can return a Promise that would resolve with the new dimensions
*/
resizeGrid(delay?: number, newSizes?: GridSize): Promise<GridSize> {
resizeGrid(delay?: number, newSizes?: GridSize): Promise<GridSize | undefined> {
return new Promise(resolve => {
// because of the javascript async nature, we might want to delay the resize a little bit
delay = delay || 0;
Expand All @@ -275,7 +272,7 @@ export class ResizerService {
});
}

resizeGridCallback(newSizes?: GridSize): GridSize {
resizeGridCallback(newSizes?: GridSize): GridSize | undefined {
const dimensions = this.resizeGridWithDimensions(newSizes);
this.pubSubService.publish('onGridAfterResize', dimensions);

Expand All @@ -286,7 +283,7 @@ export class ResizerService {
}
this._lastDimensions = dimensions;

return dimensions ?? { height: 0, width: 0 };
return dimensions;
}

resizeGridWithDimensions(newSizes?: GridSize): GridSize | undefined {
Expand Down Expand Up @@ -586,11 +583,14 @@ export class ResizerService {
private resizeGridWhenStylingIsBrokenUntilCorrected() {
// how many time we want to check before really stopping the resize check?
// We do this because user might be switching to another tab too quickly for the resize be really finished, so better recheck few times to make sure
const resizeCountBeforeQuitting = this.gridOptions?.autoFixResizeCountBeforeQuitting ?? 10;
const autoFixResizeTimeout = this.gridOptions?.autoFixResizeTimeout ?? (4 * 60 * 60); // interval is 250ms, so 4x is 1sec, so (4 * 60 * 60 = 60min)
const autoFixResizeRequiredGoodCount = this.gridOptions?.autoFixResizeRequiredGoodCount ?? 10;

const headerElm = document.querySelector<HTMLDivElement>(`.${this.gridUid} .slick-header`);
const viewportElm = document.querySelector<HTMLDivElement>(`.${this.gridUid} .slick-viewport`);
let resizeRequireCheckCount = 0;
let intervalExecutionCounter = 0;
let resizeGoodCount = 0;

if (headerElm && viewportElm && this.gridOptions.autoFixResizeWhenBrokenStyleDetected) {
this._intervalId = setInterval(async () => {
const headerTitleRowHeight = 44; // this one is set by SASS/CSS so let's hard code it
Expand All @@ -611,21 +611,24 @@ export class ResizerService {
// another resize condition could be that if the grid location is at coordinate x/y 0/0, we assume that it's in a hidden tab and we'll need to resize whenever that tab becomes active
// for these cases we'll resize until it's no longer true or until we reach a max time limit (70min)
const containerElmOffset = getHtmlElementOffset(this._gridParentContainerElm);
let isResizeRequired = (headerPos?.top === 0 || ((headerOffsetTop - viewportOffsetTop) > 2) || (containerElmOffset?.left > 0 && containerElmOffset?.top > 0)) ? true : false;
let isResizeRequired = (headerPos?.top === 0 || ((headerOffsetTop - viewportOffsetTop) > 2) || (containerElmOffset?.left === 0 && containerElmOffset?.top === 0)) ? true : false;

// user could choose to manually stop the looped of auto resize fix
if (this._isStopResizeIntervalRequested) {
isResizeRequired = false;
resizeRequireCheckCount = resizeCountBeforeQuitting;
intervalExecutionCounter = autoFixResizeTimeout;
}

if (isResizeRequired && (containerElmOffset?.left > 0 || containerElmOffset?.top > 0)) {
const gridElm = document.querySelector<HTMLDivElement>(`.${this.gridUid}`);
const isGridVisible = gridElm?.offsetParent ?? false;

if (isGridVisible && (isResizeRequired || resizeGoodCount < autoFixResizeRequiredGoodCount) && (containerElmOffset?.left > 0 || containerElmOffset?.top > 0)) {
await this.resizeGrid();
isResizeRequired = false;
resizeRequireCheckCount++;
resizeGoodCount++;
}

if (!this.gridOptions.autoFixResizeWhenBrokenStyleDetected || resizeRequireCheckCount >= resizeCountBeforeQuitting && !isResizeRequired || (this._intervalExecutionCounter++ > (4 * 60 * DEFAULT_INTERVAL_MAX_RETRIES))) { // interval is 250ms, so 4x is 1sec, so (4 * 60 * intervalMaxTimeInMin) shoud be 70min
if (isGridVisible && !isResizeRequired && (resizeGoodCount >= autoFixResizeRequiredGoodCount || intervalExecutionCounter++ >= autoFixResizeTimeout)) {
clearInterval(this._intervalId); // stop the interval if we don't need resize or if we passed let say 70min
}
}, this.intervalRetryDelay);
Expand Down
Binary file not shown.
Expand Up @@ -28,6 +28,7 @@ import {
OnSetItemsCalledEventArgs,
Pagination,
PaginationService,
ResizerService,
ServicePagination,
SharedService,
SlickDataView,
Expand All @@ -51,7 +52,6 @@ import { TextExportService } from '../../services/textExport.service';
import { TranslateServiceStub } from '../../../../../test/translateServiceStub';
import { HttpStub } from '../../../../../test/httpClientStub';
import { MockSlickEvent, MockSlickEventHandler } from '../../../../../test/mockSlickEvent';
import { ResizerService } from '../../../../common/src/services/resizer.service';
import { UniversalContainerService } from '../../services/universalContainer.service';
import { RxJsResourceStub } from '../../../../../test/rxjsResourceStub';
jest.mock('../../services/textExport.service');
Expand Down
Expand Up @@ -4,7 +4,8 @@ import { GridOption, EventNamingStyle } from '@slickgrid-universal/common';
export const SalesforceGlobalGridOptions = {
autoEdit: true, // true single click (false for double-click)
autoCommitEdit: true,
autoFixResizeCountBeforeQuitting: 10,
autoFixResizeTimeout: 4 * 60 * 60, // interval is 250ms, so 4x is 1sec, so (4 * 60 * 60 = 60min)
autoFixResizeRequiredGoodCount: 10,
autoFixResizeWhenBrokenStyleDetected: true,
cellValueCouldBeUndefined: true,
eventNamingStyle: EventNamingStyle.lowerCaseWithoutOnPrefix,
Expand Down

0 comments on commit 32e80ec

Please sign in to comment.