Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editors): add way to change or disable Composite Editor form input #139

Merged
merged 25 commits into from
Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cb10984
feat(editors): add way to change or disable Composite Editor form input
Oct 7, 2020
0078ad4
core: update few npm packages
ghiscoding Oct 8, 2020
0a1ec0c
tests: add Cypress E2E tests
ghiscoding Oct 9, 2020
22ddc46
tests: refactor input name to fix flacky test
ghiscoding Oct 9, 2020
d9eb511
tests: fix failing Cypress test
ghiscoding Oct 9, 2020
6074e97
tests: fix Cypress flaky test
ghiscoding Oct 9, 2020
c67e015
fix(core): hide Grid Menu Filter/Sort cmd when disabling functionality
Oct 13, 2020
10f94cb
Merge branch 'feat/composite-editor-change-form-value' of https://git…
Oct 13, 2020
ab13589
refactor(tests): fix failing Cypress test
Oct 13, 2020
3a8ed3e
refactor(tests): fix failing Cypress test
Oct 13, 2020
5008b4d
refactor(tests): fix failing Cypress test
Oct 13, 2020
6457fd2
tests: try fixing Cypress flaky test
Oct 13, 2020
2c5dabc
tests: try fixing Cypress flaky test
Oct 13, 2020
d7d0c93
tests: try fixing Cypress flaky test
Oct 13, 2020
b03b2b3
tests: try fixing Cypress flaky test
Oct 13, 2020
fa4eb31
tests: try fixing Cypress flaky test
Oct 13, 2020
24e9618
tests: try fixing Cypress flaky test
Oct 13, 2020
06f3d6c
tests: add Cypress Dashboard projectId
Oct 13, 2020
305298d
tests: add Cypress recording
Oct 13, 2020
81d99e2
tests: try fixing Cypress flaky test
Oct 13, 2020
6b254ba
tests: disable Cypress flaky tests on CircleCI
ghiscoding Oct 13, 2020
be469d2
Merge branch 'feat/composite-editor-change-form-value' of https://git…
ghiscoding Oct 13, 2020
d4b19d3
tests: try fixing Cypress flaky test
ghiscoding Oct 14, 2020
7777be8
tests: try fixing Cypress flaky test
ghiscoding Oct 14, 2020
d9ca660
tests: try fixing Cypress flaky test
ghiscoding Oct 14, 2020
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
6 changes: 3 additions & 3 deletions examples/webpack-demo-vanilla-bundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
"moment-mini": "^2.24.0"
},
"devDependencies": {
"@types/jquery": "^3.5.1",
"@types/jquery": "^3.5.2",
"@types/moment": "^2.13.0",
"@types/node": "^14.11.2",
"@types/node": "^14.11.5",
"@types/webpack": "^4.41.22",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.2.0",
Expand All @@ -45,7 +45,7 @@
"html-loader": "^1.3.1",
"html-webpack-plugin": "^4.5.0",
"json-loader": "^0.5.7",
"mini-css-extract-plugin": "^0.11.3",
"mini-css-extract-plugin": "^0.12.0",
"node-sass": "4.14.1",
"sass-loader": "^10.0.2",
"style-loader": "^1.3.0",
Expand Down
44 changes: 35 additions & 9 deletions examples/webpack-demo-vanilla-bundle/src/examples/example12.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function checkItemIsEditable(dataContext, columnDef, grid) {
// case 'duration':
// case 'title':
// case 'product':
// case 'countryOfOrigin':
// case 'origin':
// isEditable = dataContext.percentComplete < 50;
// break;
}
Expand Down Expand Up @@ -105,6 +105,7 @@ export class Example12 {
this.gridContainerElm.addEventListener('onclick', this.handleOnCellClicked.bind(this));
this.gridContainerElm.addEventListener('ongridstatechanged', this.handleOnSelectedRowsChanged.bind(this));
this.gridContainerElm.addEventListener('ondblclick', () => this.openCompositeModal('edit', 50));
this.gridContainerElm.addEventListener('oncompositeeditorchange', this.handleOnCompositeEditorChange.bind(this));
}

dispose() {
Expand Down Expand Up @@ -141,12 +142,24 @@ export class Example12 {
id: 'percentComplete', name: '% Complete', field: 'percentComplete', type: FieldType.number,
sortable: true, filterable: true, columnGroup: 'Analysis',
filter: { model: Filters.compoundSlider, operator: '>=' },
editor: { model: Editors.slider, massUpdate: true, minValue: 0, maxValue: 100, },
// formatter: Formatters.collectionEditor,
editor: {
model: Editors.slider,
// model: Editors.singleSelect,
// enableRenderHtml: true,
// collection: Array.from(Array(101).keys()).map(k => ({ value: k, label: k, symbol: ' <i class="mdi mdi-check-circle color-primary"></i>' })),
// customStructure: {
// value: 'value',
// label: 'label',
// labelSuffix: 'symbol'
// },
massUpdate: true, minValue: 0, maxValue: 100,
},
},
{
id: 'start', name: 'Start', field: 'start', sortable: true,
formatter: Formatters.dateIso, columnGroup: 'Period',
type: FieldType.dateIso, outputType: FieldType.dateIso,
formatter: Formatters.dateUs, columnGroup: 'Period',
type: FieldType.dateIso, outputType: FieldType.dateUs,
filterable: true, filter: { model: Filters.compoundDate },
editor: { model: Editors.date, massUpdate: true, params: { hideClearButton: false } },
},
Expand All @@ -165,8 +178,8 @@ export class Example12 {
},
{
id: 'finish', name: 'Finish', field: 'finish', sortable: true,
formatter: Formatters.dateIso, columnGroup: 'Period',
type: FieldType.dateIso, outputType: FieldType.dateIso,
formatter: Formatters.dateUs, columnGroup: 'Period',
type: FieldType.dateIso, outputType: FieldType.dateUs,
filterable: true, filter: { model: Filters.compoundDate },
editor: {
model: Editors.date,
Expand Down Expand Up @@ -221,7 +234,7 @@ export class Example12 {
}
},
{
id: 'countryOfOrigin', name: 'Country of Origin', field: 'countryOfOrigin',
id: 'origin', name: 'Country of Origin', field: 'origin',
formatter: Formatters.complexObject, columnGroup: 'Item',
exportWithFormatter: true,
dataKey: 'code',
Expand All @@ -248,7 +261,7 @@ export class Example12 {
filter: {
model: Filters.inputText,
type: 'string',
queryField: 'countryOfOrigin.name',
queryField: 'origin.name',
}
},
{
Expand Down Expand Up @@ -392,7 +405,7 @@ export class Example12 {
cost: (i % 33 === 0) ? null : Math.round(Math.random() * 10000) / 100,
completed: (i % 3 === 0 && (randomFinish > new Date() && i > 3)),
product: { id: this.mockProducts()[randomItemId]?.id, itemName: this.mockProducts()[randomItemId]?.itemName, },
countryOfOrigin: (i % 2) ? { code: 'CA', name: 'Canada' } : { code: 'US', name: 'United States' },
origin: (i % 2) ? { code: 'CA', name: 'Canada' } : { code: 'US', name: 'United States' },
};

if (!(i % 8)) {
Expand Down Expand Up @@ -464,6 +477,19 @@ export class Example12 {
// }
}

handleOnCompositeEditorChange(event) {
const args = event && event.detail && event.detail.args;
const columnDef = args?.column;
const formValues = args?.formValues;

// you can change any other form input values when certain conditions are met
if (columnDef.id === 'percentComplete' && formValues.percentComplete === 100) {
this.sgb.slickCompositeEditor.changeFormInputValue('completed', true);
this.sgb.slickCompositeEditor.changeFormInputValue('finish', new Date());
// this.sgb.slickCompositeEditor.changeFormInputValue('product', { id: 0, itemName: 'Sleek Metal Computer' });
}
}

handleOnSelectedRowsChanged(event) {
const gridState = event && event.detail && event.detail.gridState;
if (Array.isArray(gridState?.rowSelection.dataContextIds)) {
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"rebuild": "run-s clean build",
"clean": "rimraf --maxBusyTries=10 packages/*/dist dist",
"cypress": "cypress open --config-file test/cypress.json",
"cypress:ci": "cypress run --config-file test/cypress.json --reporter mochawesome",
"cypress:ci": "cypress run --config-file test/cypress.json --reporter mochawesome --record",
"dev:watch": "lerna run dev:watch --parallel",
"diff": "lerna diff",
"updated": "lerna updated",
Expand Down Expand Up @@ -43,17 +43,17 @@
},
"devDependencies": {
"@types/jest": "^26.0.14",
"@types/node": "^14.11.2",
"@typescript-eslint/eslint-plugin": "^4.3.0",
"@typescript-eslint/parser": "^4.3.0",
"@types/node": "^14.11.5",
"@typescript-eslint/eslint-plugin": "^4.4.0",
"@typescript-eslint/parser": "^4.4.0",
"cypress": "^5.3.0",
"eslint": "^7.10.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prefer-arrow": "^1.2.2",
"http-server": "^0.12.3",
"jest": "^26.5.0",
"jest-cli": "^26.5.0",
"jest-environment-jsdom": "^26.5.0",
"jest": "^26.5.2",
"jest-cli": "^26.5.2",
"jest-environment-jsdom": "^26.5.2",
"jest-extended": "^0.11.5",
"jest-junit": "^12.0.0",
"jsdom": "^16.4.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,16 @@
"lodash.isequal": "^4.5.0",
"moment-mini": "^2.24.0",
"multiple-select-modified": "^1.3.4",
"slickgrid": "^2.4.29"
"slickgrid": "github:6pac/SlickGrid"
},
"devDependencies": {
"@types/dompurify": "^2.0.4",
"@types/jquery": "^3.5.1",
"@types/jquery": "^3.5.2",
"@types/moment": "^2.13.0",
"autoprefixer": "^10.0.1",
"copyfiles": "^2.4.0",
"cross-env": "^7.0.2",
"mini-css-extract-plugin": "^0.11.3",
"mini-css-extract-plugin": "^0.12.0",
"node-sass": "4.14.1",
"nodemon": "^2.0.4",
"npm-run-all": "^4.1.5",
Expand Down
35 changes: 29 additions & 6 deletions packages/common/src/editors/__tests__/autoCompleteEditor.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Editors } from '../index';
import { AutoCompleteEditor } from '../autoCompleteEditor';
import { KeyCode, FieldType } from '../../enums/index';
import { AutocompleteOption, Column, EditorArgs, EditorArguments, GridOption, SlickDataView, SlickGrid, SlickNamespace } from '../../interfaces/index';
import { AutocompleteOption, Column, EditorArguments, GridOption, SlickDataView, SlickGrid, SlickNamespace } from '../../interfaces/index';

declare const Slick: SlickNamespace;
const KEY_CHAR_A = 97;
Expand Down Expand Up @@ -164,6 +164,15 @@ describe('AutoCompleteEditor', () => {
expect(editor.getValue()).toBe('male');
});

it('should call "setValue" with value & apply value flag and expect the DOM element to have same value and also expect the value to be applied to the item object', () => {
mockColumn.type = FieldType.object;
editor = new AutoCompleteEditor(editorArguments);
editor.setValue({ value: 'male', label: 'male' }, true);

expect(editor.getValue()).toBe('male');
expect(editorArguments.item.gender).toEqual({ value: 'male', label: 'male' });
});

it('should define an item datacontext containing a string as cell value and expect this value to be loaded in the editor when calling "loadValue"', () => {
editor = new AutoCompleteEditor(editorArguments);
editor.loadValue(mockItemData);
Expand Down Expand Up @@ -302,7 +311,7 @@ describe('AutoCompleteEditor', () => {
});

it('should return item data with an empty string in its value when calling "applyValue" which fails the custom validation', () => {
mockColumn.internalColumnEditor.validator = (value: any, args: EditorArgs) => {
mockColumn.internalColumnEditor.validator = (value: any) => {
if (value.label.length < 10) {
return { valid: false, msg: 'Must be at least 10 chars long.' };
}
Expand Down Expand Up @@ -714,7 +723,7 @@ describe('AutoCompleteEditor', () => {

it('should provide "renderItem" in the "filterOptions" and expect the jQueryUI "_renderItem" to be overriden', () => {
const mockTemplateString = `<div>Hello World</div>`;
const mockTemplateCallback = (item) => mockTemplateString;
const mockTemplateCallback = () => mockTemplateString;
mockColumn.internalColumnEditor = {
editorOptions: {
source: [],
Expand Down Expand Up @@ -750,14 +759,28 @@ describe('AutoCompleteEditor', () => {
beforeEach(() => {
editorArguments = {
...editorArguments,
compositeEditorOptions: { headerTitle: 'Test', formValues: {}, modalType: 'edit' }
compositeEditorOptions: { headerTitle: 'Test', modalType: 'edit', formValues: {}, editors: {} },
} as EditorArguments;
});

afterEach(() => {
jest.clearAllMocks();
});

it('should call "setValue" with value & apply value flag and expect the DOM element to have same value and also expect the value to be applied to the item object', () => {
const activeCellMock = { row: 0, cell: 0 };
jest.spyOn(gridStub, 'getActiveCell').mockReturnValue(activeCellMock);
const onBeforeCompositeSpy = jest.spyOn(gridStub.onCompositeEditorChange, 'notify').mockReturnValue(false);
editor = new AutoCompleteEditor(editorArguments);
editor.setValue({ value: 'male', label: 'Male' }, true);

expect(editor.getValue()).toBe('Male');
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: { gender: 'male' }, editors: {},
}, expect.anything());
});

it('should call "show" and expect the DOM element to not be disabled when "onBeforeEditCell" is NOT returning false', () => {
const activeCellMock = { row: 0, cell: 0 };
const getCellSpy = jest.spyOn(gridStub, 'getActiveCell').mockReturnValue(activeCellMock);
Expand Down Expand Up @@ -787,7 +810,7 @@ describe('AutoCompleteEditor', () => {
expect(onBeforeEditSpy).toHaveBeenCalledWith({ ...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub });
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: {},
formValues: {}, editors: {},
}, expect.anything());
expect(disableSpy).toHaveBeenCalledWith(true);
expect(editor.editorDomElement.attr('disabled')).toEqual('disabled');
Expand All @@ -813,7 +836,7 @@ describe('AutoCompleteEditor', () => {
expect(onBeforeEditSpy).toHaveBeenCalledWith({ ...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub });
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: { gender: 'female' },
formValues: { gender: 'female' }, editors: {},
}, expect.anything());
});
});
Expand Down
28 changes: 25 additions & 3 deletions packages/common/src/editors/__tests__/checkboxEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ describe('CheckboxEditor', () => {
expect(editor.getValue()).toBe(true);
});

it('should call "setValue" with value & apply value flag and expect the DOM element to have same value and also expect the value to be applied to the item object', () => {
editor = new CheckboxEditor(editorArguments);
editor.setValue(true, true);

expect(editor.getValue()).toBe(true);
expect(editorArguments.item.isActive).toBe(true);
});

it('should call "setValue" with false and expect the DOM element value to return false (representing unchecked)', () => {
editor = new CheckboxEditor(editorArguments);
editor.setValue(false);
Expand Down Expand Up @@ -379,14 +387,28 @@ describe('CheckboxEditor', () => {
beforeEach(() => {
editorArguments = {
...editorArguments,
compositeEditorOptions: { headerTitle: 'Test', formValues: {}, modalType: 'edit' }
compositeEditorOptions: { headerTitle: 'Test', modalType: 'edit', formValues: {}, editors: {} },
} as EditorArguments;
});

afterEach(() => {
jest.clearAllMocks();
});

it('should call "setValue" with value & apply value flag and expect the DOM element to have same value and also expect the value to be applied to the item object', () => {
const activeCellMock = { row: 0, cell: 0 };
jest.spyOn(gridStub, 'getActiveCell').mockReturnValue(activeCellMock);
const onBeforeCompositeSpy = jest.spyOn(gridStub.onCompositeEditorChange, 'notify').mockReturnValue(false);
editor = new CheckboxEditor(editorArguments);
editor.setValue(true, true);

expect(editor.getValue()).toBe(true);
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: { isActive: true }, editors: {},
}, expect.anything());
});

it('should call "show" and expect the DOM element to not be disabled when "onBeforeEditCell" is NOT returning false', () => {
const activeCellMock = { row: 0, cell: 0 };
const getCellSpy = jest.spyOn(gridStub, 'getActiveCell').mockReturnValue(activeCellMock);
Expand Down Expand Up @@ -416,7 +438,7 @@ describe('CheckboxEditor', () => {
expect(onBeforeEditSpy).toHaveBeenCalledWith({ ...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub });
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: {},
formValues: {}, editors: {},
}, expect.anything());
expect(disableSpy).toHaveBeenCalledWith(true);
expect(editor.editorDomElement.disabled).toEqual(true);
Expand All @@ -440,7 +462,7 @@ describe('CheckboxEditor', () => {
expect(onBeforeEditSpy).toHaveBeenCalledWith({ ...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub });
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: { isActive: true },
formValues: { isActive: true }, editors: {},
}, expect.anything());
});
});
Expand Down
30 changes: 27 additions & 3 deletions packages/common/src/editors/__tests__/dateEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ describe('DateEditor', () => {
expect(editor.getValue()).toBe('2001-01-02T11:02:02.000Z');
});

it('should call "setValue" with value & apply value flag and expect the DOM element to have same value and also expect the value to be applied to the item object', () => {
mockColumn.type = FieldType.dateIso;
editor = new DateEditor(editorArguments);
editor.setValue('2001-01-02', true);

expect(editor.getValue()).toBe('2001-01-02');
expect(editorArguments.item.startDate).toBe('2001-01-02');
});

it('should define an item datacontext containing a string as cell value and expect this value to be loaded in the editor when calling "loadValue"', () => {
mockItemData = { id: 1, startDate: '2001-01-02T11:02:02.000Z', isActive: true };
editor = new DateEditor(editorArguments);
Expand Down Expand Up @@ -437,14 +446,29 @@ describe('DateEditor', () => {
beforeEach(() => {
editorArguments = {
...editorArguments,
compositeEditorOptions: { headerTitle: 'Test', formValues: {}, modalType: 'edit' }
compositeEditorOptions: { headerTitle: 'Test', modalType: 'edit', formValues: {}, editors: {} },
} as EditorArguments;
});

afterEach(() => {
jest.clearAllMocks();
});

it('should call "setValue" with value & apply value flag and expect the DOM element to have same value and also expect the value to be applied to the item object', () => {
const activeCellMock = { row: 0, cell: 0 };
jest.spyOn(gridStub, 'getActiveCell').mockReturnValue(activeCellMock);
const onBeforeCompositeSpy = jest.spyOn(gridStub.onCompositeEditorChange, 'notify').mockReturnValue(false);
mockColumn.type = FieldType.dateIso;
editor = new DateEditor(editorArguments);
editor.setValue('2001-01-02', true);

expect(editor.getValue()).toContain('2001-01-02');
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: { startDate: '2001-01-02' }, editors: {},
}, expect.anything());
});

it('should call "show" and expect the DOM element to not be disabled when "onBeforeEditCell" is NOT returning false', () => {
const activeCellMock = { row: 0, cell: 0 };
const getCellSpy = jest.spyOn(gridStub, 'getActiveCell').mockReturnValue(activeCellMock);
Expand Down Expand Up @@ -474,7 +498,7 @@ describe('DateEditor', () => {
expect(onBeforeEditSpy).toHaveBeenCalledWith({ ...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub });
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: {},
formValues: {}, editors: {},
}, expect.anything());
expect(disableSpy).toHaveBeenCalledWith(true);
expect(editor.flatInstance._input.disabled).toEqual(true);
Expand Down Expand Up @@ -502,7 +526,7 @@ describe('DateEditor', () => {
expect(onBeforeEditSpy).toHaveBeenCalledWith({ ...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub });
expect(onBeforeCompositeSpy).toHaveBeenCalledWith({
...activeCellMock, column: mockColumn, item: mockItemData, grid: gridStub,
formValues: { startDate: '2001-01-02' },
formValues: { startDate: '2001-01-02' }, editors: {},
}, expect.anything());
});
});
Expand Down
Loading