Skip to content

Commit

Permalink
feat(plugins): sync column definitions to user after plugin adds column
Browse files Browse the repository at this point in the history
- for some extensions/plugins, that is RowDetail, RowMove, RowSelections, are adding extra columns dynamically when the grid is created and are not synced to the user, this PR will help with that but has to be implement differently in each lib wrappers (Angular, Aurelia, ...)
- closes issue #1018
  • Loading branch information
ghiscoding committed Oct 25, 2022
1 parent c448482 commit 2359171
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 5 deletions.
6 changes: 5 additions & 1 deletion src/app/examples/grid-rowmove.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ <h2>
<i class="fa fa-random"></i>
Toggle Sorting
</button>
<button class="btn btn-outline-secondary btn-sm" data-test="add-crud-columns-btn" (click)="addEditDeleteColumns()">
<i class="fa fa-add"></i>
Add Edit/Delete Columns
</button>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<angular-slickgrid gridId="grid17"
[columnDefinitions]="columnDefinitions"
[(columnDefinitions)]="columnDefinitions"
[gridOptions]="gridOptions"
[dataset]="dataset"
(onAngularGridCreated)="angularGridReady($event.detail)">
Expand Down
39 changes: 38 additions & 1 deletion src/app/examples/grid-rowmove.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core';

import { AngularGridInstance, Column, ExtensionName, Filters, Formatters, GridOption, SlickRowMoveManager } from './../modules/angular-slickgrid';
import { AngularGridInstance, Column, ExtensionName, Filters, Formatters, GridOption, OnEventArgs, SlickRowMoveManager } from './../modules/angular-slickgrid';

@Component({
templateUrl: './grid-rowmove.component.html'
Expand Down Expand Up @@ -221,6 +221,43 @@ export class GridRowMoveComponent implements OnInit {
this.angularGrid.sortService.disableSortFunctionality(true);
}

addEditDeleteColumns() {
if (this.columnDefinitions[0].id !== 'change-symbol') {
const newCols = [
{
id: 'change-symbol',
field: 'id',
excludeFromColumnPicker: true,
excludeFromGridMenu: true,
excludeFromHeaderMenu: true,
formatter: Formatters.editIcon,
minWidth: 30,
maxWidth: 30,
onCellClick: (clickEvent: Event, args: OnEventArgs) => {
alert(`Technically we should Edit "Task ${args.dataContext.id}"`);
}
}, {
id: 'delete-symbol',
field: 'id',
excludeFromColumnPicker: true,
excludeFromGridMenu: true,
excludeFromHeaderMenu: true,
formatter: Formatters.deleteIcon,
minWidth: 30,
maxWidth: 30,
onCellClick: (e: Event, args: OnEventArgs) => {
if (confirm('Are you sure?')) {
this.angularGrid.gridService.deleteItemById(args.dataContext.id);
}
}
}
];

this.columnDefinitions.splice(0, 0, newCols[0], newCols[1]);
this.columnDefinitions = this.columnDefinitions.slice(); // or use spread operator [...cols] to trigger change
}
}

// or Toggle Filtering/Sorting functionalities
// ---------------------------------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,24 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
expect(pubSubSpy).toHaveBeenNthCalledWith(6, 'onAfterGridDestroyed', true);
});

it('should update column definitions when onPluginColumnsChanged event is triggered with updated columns', () => {
const colsChangeSpy = jest.spyOn(component.columnDefinitionsChange, 'emit');
const columnsMock = [
{ id: 'firstName', field: 'firstName', editor: undefined, internalColumnEditor: {} },
{ id: 'lastName', field: 'lastName', editor: undefined, internalColumnEditor: {} }
];

component.ngAfterViewInit();
component.initialization(slickEventHandler);
eventPubSubService.publish('onPluginColumnsChanged', {
columns: columnsMock,
pluginName: 'RowMoveManager'
});

expect(component.columnDefinitions).toEqual(columnsMock);
expect(colsChangeSpy).toHaveBeenCalledWith(columnsMock);
});

describe('initialization method', () => {
const customEditableInputFormatter: Formatter = (_row, _cell, value, columnDef) => {
const isEditableLine = !!columnDef.editor;
Expand Down Expand Up @@ -1108,7 +1126,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
});

it('should invoke "updateFilters" method with filters returned from "getColumnFilters" of the Filter Service when there is no Presets defined', () => {
const mockColumnFilter = { name: { columnId: 'name', columnDef: { id: 'name', field: 'name', filter: { model: Filters.autoComplete } }, operator: 'EQ', searchTerms: ['john'] } };
const mockColumnFilter = { name: { columnId: 'name', columnDef: { id: 'name', field: 'name', filter: { model: Filters.autocompleter } }, operator: 'EQ', searchTerms: ['john'] } };
jest.spyOn(filterServiceStub, 'getColumnFilters').mockReturnValue(mockColumnFilter as unknown as ColumnFilters);
const backendSpy = jest.spyOn(mockGraphqlService, 'updateFilters');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'slickgrid/dist/slick.grid.min';
import 'slickgrid/dist/slick.dataview.min';

// ...then everything else...
import { AfterViewInit, ApplicationRef, ChangeDetectorRef, Component, ElementRef, Inject, Input, OnDestroy, Optional, } from '@angular/core';
import { AfterViewInit, ApplicationRef, ChangeDetectorRef, Component, ElementRef, EventEmitter, Inject, Input, OnDestroy, Optional, Output, } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';

Expand Down Expand Up @@ -174,6 +174,10 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy {
return this._columnDefinitions;
}

// make the columnDefinitions a 2-way binding so that plugin adding cols
// are synched on user's side as well (RowMove, RowDetail, RowSelections)
@Output() columnDefinitionsChange = new EventEmitter(true);

@Input()
get dataset(): any[] {
return (this.customDataView ? this.slickGrid?.getData?.() : this.dataView?.getItems?.()) || [];
Expand Down Expand Up @@ -504,6 +508,18 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy {
// save reference for all columns before they optionally become hidden/visible
this.sharedService.allColumns = this._columnDefinitions;
this.sharedService.visibleColumns = this._columnDefinitions;

// before certain extentions/plugins potentially adds extra columns not created by the user itself (RowMove, RowDetail, RowSelections)
// we'll subscribe to the event and push back the change to the user so they always use full column defs array including extra cols
this.subscriptions.push(
this._eventPubSubService.subscribe<{ columns: Column[]; grid: SlickGrid }>('onPluginColumnsChanged', data => {
this._columnDefinitions = data.columns;
this.columnDefinitionsChange.emit(this._columnDefinitions);
})
);

// after subscribing to potential columns changed, we are ready to create these optional extensions
// when we did find some to create (RowMove, RowDetail, RowSelections), it will automatically modify column definitions (by previous subscribe)
this.extensionService.createExtensionsBeforeGridCreation(this._columnDefinitions, this.gridOptions);

// if user entered some Pinning/Frozen "presets", we need to apply them in the grid options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class SlickRowDetailView extends UniversalSlickRowDetailView {
protected readonly gridContainerElement: HTMLDivElement,
protected rxjs?: RxJsFacade,
) {
super();
super(eventPubSubService);
}

get addonOptions() {
Expand Down
26 changes: 26 additions & 0 deletions test/cypress/e2e/example17.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,4 +404,30 @@ describe('Example 17 - Row Move & Checkbox Selector Selector Plugins', { retries
}
});
});

it('should add Edit/Delete columns and expect 2 new columns added at the beginning of the grid', () => {
const newExpectedColumns = ['', '', ...fullTitles];
cy.get('[data-test="add-crud-columns-btn"]').click();

cy.get('#grid17')
.find('.slick-header-columns')
.children()
.each(($child, index) => {
if (index <= 5) {
expect($child.text()).to.eq(newExpectedColumns[index]);
}
});

cy.get('.slick-row')
.first()
.children('.slick-cell')
.children('.edit-icon')
.should('have.length', 1);

cy.get('.slick-row')
.first()
.children('.slick-cell:nth(1)')
.children('.delete-icon')
.should('have.length', 1);
});
});

0 comments on commit 2359171

Please sign in to comment.