Skip to content

Commit

Permalink
fix(resizer): regression introduced by #462 for the grid resize in SF
Browse files Browse the repository at this point in the history
- the previous PR #462 which added a delay in the grid resize actually introduced a regression in Salesforce, the hack which looks for a resize every few ms wasn't registered at all anymore because of the new delay. So let's put back the way it was before and and also add a 2nd one with the delay required by Angular-Slickgrid
  • Loading branch information
ghiscoding committed Sep 8, 2021
1 parent 2c34d12 commit f34d8b9
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -581,8 +581,9 @@ describe('Resizer Service', () => {
setTimeout(() => {
expect(divContainer.outerHTML).toBeTruthy();
expect(resizeSpy).toHaveBeenCalled();
expect(resizeSpy).toHaveBeenNthCalledWith(2);
expect(resizeSpy).toHaveBeenNthCalledWith(2, 10, undefined);
expect(resizeSpy).toHaveBeenNthCalledWith(3);
expect(resizeSpy).toHaveBeenNthCalledWith(4);
done();
}, 25);
});
Expand Down Expand Up @@ -663,8 +664,9 @@ describe('Resizer Service', () => {
setTimeout(() => {
expect(divContainer.outerHTML).toBeTruthy();
expect(resizeSpy).toHaveBeenCalled();
expect(resizeSpy).toHaveBeenNthCalledWith(2);
expect(resizeSpy).toHaveBeenNthCalledWith(2, 10, undefined);
expect(resizeSpy).toHaveBeenNthCalledWith(3);
expect(resizeSpy).toHaveBeenNthCalledWith(4);
done();
service.requestStopOfAutoFixResizeGrid();
}, 20);
Expand Down
38 changes: 24 additions & 14 deletions packages/common/src/services/resizer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export class ResizerService {
get gridUid(): string {
return this._grid?.getUID() ?? '';
}
get gridUidSelector(): string {
return this.gridUid ? `.${this.gridUid}` : '';
}

get intervalRetryDelay(): number {
return this._intervalRetryDelay;
Expand All @@ -85,7 +88,7 @@ export class ResizerService {
clearInterval(this._intervalId);
}

$(window).off(`resize.grid.${this.gridUid}`);
$(window).off(`resize.grid${this.gridUidSelector}`);
}

init(grid: SlickGrid, gridParentContainerElm: HTMLElement) {
Expand Down Expand Up @@ -148,14 +151,16 @@ 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));

// -- do a 2nd resize with a slight delay (in ms) so that we resize after the grid render is done
this.resizeGrid(10, newSizes);

// -- 2nd bind a trigger on the Window DOM element, so that it happens also when resizing after first load
// -- bind auto-resize to Window object only if it exist
$(window).on(`resize.grid.${this.gridUid}`, this.handleResizeGrid.bind(this, newSizes));
$(window).on(`resize.grid${this.gridUidSelector}`, this.handleResizeGrid.bind(this, newSizes));
}

handleResizeGrid(newSizes?: GridSize) {
Expand Down Expand Up @@ -316,7 +321,7 @@ export class ResizerService {
// also call the grid auto-size columns so that it takes available space when going bigger
if (this.gridOptions?.enableAutoSizeColumns && this._grid.autosizeColumns) {
// make sure that the grid still exist (by looking if the Grid UID is found in the DOM tree) to avoid SlickGrid error "missing stylesheet"
if (this.gridUid && $(`.${this.gridUid}`).length > 0) {
if (this.gridUid && $(`${this.gridUidSelector}`).length > 0) {
this._grid.autosizeColumns();
}
} else if (this.gridOptions.enableAutoResizeColumnsByCellContent && (!this._lastDimensions?.width || newWidth !== this._lastDimensions?.width)) {
Expand Down Expand Up @@ -570,6 +575,14 @@ export class ResizerService {
return Math.ceil(adjustedWidth);
}

/**
* Just check if the grid is still shown in the DOM
* @returns is grid shown
*/
protected checkIsGridShown(): boolean {
return !!(document.querySelector<HTMLDivElement>(`${this.gridUidSelector}`)?.offsetParent ?? false);
}

/**
* Patch for SalesForce, some issues arise when having a grid inside a Tab and user clicks in a different Tab without waiting for the grid to be rendered
* in ideal world, we would simply call a resize when user comes back to the Tab with the grid (tab focused) but this is an extra step and we might not always have this event available.
Expand All @@ -587,8 +600,8 @@ export class ResizerService {
const autoFixResizeTimeout = this.gridOptions?.autoFixResizeTimeout ?? (5 * 60 * 60); // interval is 200ms, so 4x is 1sec, so (4 * 60 * 60 = 60min)
const autoFixResizeRequiredGoodCount = this.gridOptions?.autoFixResizeRequiredGoodCount ?? 5;

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

Expand Down Expand Up @@ -631,25 +644,22 @@ export class ResizerService {
}

// visible grid (shown to the user and not hidden in another Tab will have an offsetParent defined)
let isGridVisible = !!(document.querySelector<HTMLDivElement>(`.${this.gridUid}`)?.offsetParent ?? false);

if (isGridVisible && (isResizeRequired || containerElmOffset?.left === 0 || containerElmOffset?.top === 0)) {
if (this.checkIsGridShown() && (isResizeRequired || containerElmOffset?.left === 0 || containerElmOffset?.top === 0)) {
await this.resizeGrid();

// make sure the grid is still visible after doing the resize
isGridVisible = !!(document.querySelector<HTMLDivElement>(`.${this.gridUid}`)?.offsetParent ?? false);
if (isGridVisible) {
if (this.checkIsGridShown()) {
isResizeRequired = false;
}
}

// make sure the grid is still visible after optionally doing a resize
// if it visible then we can consider it a good resize (it might not be visible if user quickly switch to another Tab)
if (isGridVisible) {
if (this.checkIsGridShown()) {
resizeGoodCount++;
}

if (isGridVisible && !isResizeRequired && (resizeGoodCount >= autoFixResizeRequiredGoodCount || intervalExecutionCounter++ >= autoFixResizeTimeout)) {
if (this.checkIsGridShown() && !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.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { GridOption, EventNamingStyle } from '@slickgrid-universal/common';
export const SalesforceGlobalGridOptions = {
autoEdit: true, // true single click (false for double-click)
autoCommitEdit: true,
autoFixResizeTimeout: 5 * 60 * 60, // interval is 200ms, so 4x is 1sec, so (5 * 60 * 60 = 60min)
autoFixResizeTimeout: 5 * 60 * 60, // interval is 200ms, so 5x is 1sec, so (5 * 60 * 60 = 60min)
autoFixResizeRequiredGoodCount: 5 * 60 * 60, // make it the same as the interval timeout, this is equivalent to say don't stop until the timeout is over
autoFixResizeWhenBrokenStyleDetected: true,
cellValueCouldBeUndefined: true,
Expand Down

0 comments on commit f34d8b9

Please sign in to comment.