diff --git a/packages/cli/templates/webcomponents/igc-ts/grid/default/files/src/app/__path__/__filePrefix__.test.ts b/packages/cli/templates/webcomponents/igc-ts/grid/default/files/src/app/__path__/__filePrefix__.test.ts index c04e0494b..f33429ae2 100644 --- a/packages/cli/templates/webcomponents/igc-ts/grid/default/files/src/app/__path__/__filePrefix__.test.ts +++ b/packages/cli/templates/webcomponents/igc-ts/grid/default/files/src/app/__path__/__filePrefix__.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import $(ClassName) from './$(path).js'; -describe('IgcDataGridComponent', () => { +describe('IgcGridComponent', () => { it(' is an instance of $(ClassName)', async () => { const element = document.createElement('app-$(path)'); expect(element).to.be.instanceOf($(ClassName)); diff --git a/packages/cli/templates/webcomponents/igc-ts/grid/default/files/src/app/__path__/__filePrefix__.ts b/packages/cli/templates/webcomponents/igc-ts/grid/default/files/src/app/__path__/__filePrefix__.ts index c871b2ffd..ef6e4c8c9 100644 --- a/packages/cli/templates/webcomponents/igc-ts/grid/default/files/src/app/__path__/__filePrefix__.ts +++ b/packages/cli/templates/webcomponents/igc-ts/grid/default/files/src/app/__path__/__filePrefix__.ts @@ -1,45 +1,13 @@ import { html, css, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; -import { - IgcDataGridModule, - IgcGridColumnOptionsModule, - IgcDataGridComponent, - IgcColumnGroupDescription, -} from 'igniteui-webcomponents-grids'; -import { ModuleManager } from 'igniteui-webcomponents-core'; +import { customElement, state } from 'lit/decorators.js'; +import { IgcGridComponent, IgcGroupingExpression, SortingDirection } from 'igniteui-webcomponents-grids'; -ModuleManager.register( - IgcDataGridModule, - IgcGridColumnOptionsModule, -); +import gridThemeLightMaterial from 'igniteui-webcomponents-grids/grids/themes/light/material.css?inline' + +IgcGridComponent.register(); @customElement('app-$(path)') export default class $(ClassName) extends LitElement { - data: any[] = [{ - Country: 'USA', - CountryFlag: 'https://static.infragistics.com/xplatform/images/flags/USA.png', - Margin: 3, - OrderDate: new Date(2021, 4, 3), - OrderItems: 7, - OrderValue: 500, - ProductID: 1001, - ProductName: 'Patriot Memory', - ProductPrice: 2000, - Status: 'Shipped', - }, - { - Country: 'Croatia', - CountryFlag: 'https://static.infragistics.com/xplatform/images/flags/Croatia.png', - Margin: 5, - OrderDate: new Date(2021, 1, 10), - OrderItems: 11, - OrderValue: 760, - ProductID: 1002, - ProductName: 'Asus GPU', - ProductPrice: 3000, - Status: 'Packing', - }]; - static styles = css` :host { height: 100%; @@ -47,37 +15,62 @@ export default class $(ClassName) extends LitElement { padding-right: 20px; width: calc(100% - 600px); } + igc-grid img { + object-fit: contain; + height: 100%; + width: 100%; + } `; + @state() + data: any[] = [{ + country: 'USA', + countryFlag: 'https://static.infragistics.com/xplatform/images/flags/USA.png', + margin: 0.03, + orderDate: new Date(2021, 4, 3), + orderItems: 7, + orderValue: 500, + productID: 1001, + productName: 'Patriot Memory', + productPrice: 2000, + status: 'Shipped', + }, + { + country: 'Croatia', + countryFlag: 'https://static.infragistics.com/xplatform/images/flags/Croatia.png', + margin: 0.05, + orderDate: new Date(2021, 1, 10), + orderItems: 11, + orderValue: 760, + productID: 1002, + productName: 'Asus GPU', + productPrice: 3000, + status: 'Packing', + }]; + + @state() + groupingExpressions: IgcGroupingExpression[] = [ + { fieldName: 'status', dir: SortingDirection.Desc }, + ]; + render() { return html` - ${gridThemeLightMaterial} + - - - - - - - - - + + + + + + + + + `; } - - firstUpdated() { - const grid = this.shadowRoot?.getElementById('grid') as IgcDataGridComponent; - grid.dataSource = this.data; - - const grouping = new IgcColumnGroupDescription(); - grouping.field = 'Status'; - grouping.displayName = 'Status'; - grid.groupDescriptions.add(grouping); - } } diff --git a/packages/cli/templates/webcomponents/igc-ts/grid/default/index.ts b/packages/cli/templates/webcomponents/igc-ts/grid/default/index.ts index 399cc8a97..ab26c60ef 100644 --- a/packages/cli/templates/webcomponents/igc-ts/grid/default/index.ts +++ b/packages/cli/templates/webcomponents/igc-ts/grid/default/index.ts @@ -10,12 +10,7 @@ class IgcGridTemplate extends IgniteUIForWebComponentsTemplate { this.projectType = "igc-ts"; this.name = "Grid"; this.description = "IgcGrid with local data"; - this.packages = [ - "igniteui-webcomponents-core@~6.0.0", - "igniteui-webcomponents-grids@~6.0.0", - "igniteui-webcomponents-inputs@~6.0.0", - "igniteui-webcomponents-layouts@~6.0.0" - ]; + this.packages = [ "igniteui-webcomponents-grids@~6.0.0" ]; } } module.exports = new IgcGridTemplate(); diff --git a/packages/cli/templates/webcomponents/igc-ts/grid/grid-editing/files/src/app/__path__/__filePrefix__.ts b/packages/cli/templates/webcomponents/igc-ts/grid/grid-editing/files/src/app/__path__/__filePrefix__.ts index 83ec64969..1ad71168d 100644 --- a/packages/cli/templates/webcomponents/igc-ts/grid/grid-editing/files/src/app/__path__/__filePrefix__.ts +++ b/packages/cli/templates/webcomponents/igc-ts/grid/grid-editing/files/src/app/__path__/__filePrefix__.ts @@ -1,216 +1,117 @@ import { css, html, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; +import { customElement, query, state } from 'lit/decorators.js'; +import { defineComponents, IgcButtonComponent, IgcCheckboxChangeEventArgs, IgcSwitchComponent } from 'igniteui-webcomponents'; import { - EditModeType, - GridActivationMode, - DataGridSelectionMode, - IgcDataGridComponent, - IgcDataGridModule, - IgcGridCellValueChangingEventArgs, - IgcGridColumnOptionsModule, - IgcTemplateCellUpdatingEventArgs, - IgcTemplateColumnComponent + IgcGridComponent } from 'igniteui-webcomponents-grids'; -import { ModuleManager } from 'igniteui-webcomponents-core'; import { DataGridSharedData } from './DataGridSharedData'; -ModuleManager.register( - IgcDataGridModule, - IgcGridColumnOptionsModule, -); +import gridThemeLightMaterial from 'igniteui-webcomponents-grids/grids/themes/light/material.css?inline'; + +defineComponents(IgcButtonComponent, IgcGridComponent, IgcSwitchComponent); @customElement('app-$(path)') export default class $(ClassName) extends LitElement { - data: any[] = DataGridSharedData.getEmployees(); - static styles = css` :host { height: 100%; margin: 0px; padding-right: 20px; width: calc(100% - 600px); - } - `; - - render() { - return html` -
-
- - - - Edit Mode: - - - Edit Mode: - -
- - - - - - - - - - - - -
- `; - } - - firstUpdated() { - const grid = this.shadowRoot?.getElementById('grid') as IgcDataGridComponent; - const commitButton = this.shadowRoot?.getElementById('commitClick') as HTMLButtonElement; - const undoButton = this.shadowRoot?.getElementById('undoClick') as HTMLButtonElement; - const redoButton = this.shadowRoot?.getElementById('redoClick') as HTMLButtonElement; - - const onCommitClick = () => { - grid.commitEdits(); - commitButton.disabled = true; - undoButton.disabled = !grid.canUndo; - }; - - const onUndoClick = () => { - grid.undo(); - undoButton.disabled = !grid.canUndo; - if (!grid.canUndo) { - commitButton.disabled = grid.canCommit; - } else { - commitButton.disabled = !grid.canCommit; - } - - redoButton.disabled = !grid.canRedo; - }; - - const onRedoClick = () => { - grid.redo(); - - if (grid.editMode === EditModeType.Cell || grid.editMode === EditModeType.None) { - commitButton.disabled = !grid.canCommit; - } - if (grid.editMode === EditModeType.CellBatch || grid.editMode === EditModeType.Row) { - redoButton.disabled = !grid.canRedo; - undoButton.disabled = !grid.canUndo; - if (!grid.canUndo) { - commitButton.disabled = grid.canCommit; - } else { - commitButton.disabled = !grid.canCommit; - } - } - }; - - if (commitButton !== null) { - commitButton.onclick = onCommitClick; + --ig-size: var(--ig-size-medium); } - if (undoButton !== null) { - undoButton.onclick = onUndoClick; + .actions { + display: flex; + gap: 8px; + padding: 8px; } - - if (redoButton !== null) { - redoButton.onclick = onRedoClick; + igc-grid img { + object-fit: contain; + height: 30px; } + `; - const onDeleteRowClick = (e: MouseEvent) => { - const button = e.srcElement as HTMLButtonElement; - const viewIndex = parseInt(button.id, 10); - const rowItem = grid.actualDataSource.getItemAtIndex(viewIndex); + @state() + data: any[] = DataGridSharedData.getEmployees(); - if (grid.editMode === EditModeType.CellBatch || grid.editMode === EditModeType.Row) { - grid.removeItem(rowItem); - commitButton.disabled = !grid.canCommit; - redoButton.disabled = !grid.canRedo; - undoButton.disabled = !grid.canUndo; - } else if (grid.editMode === EditModeType.Cell) { - // delete grid row immediately - grid.removeItem(rowItem); - } - }; + @query('igc-grid', true) + grid!: IgcGridComponent & { transactions: any }; - const onDeleteCellUpdating = (s: IgcTemplateColumnComponent, - e: IgcTemplateCellUpdatingEventArgs) => { - const content = e.content as HTMLDivElement; - if (content.childElementCount === 0) { - const button = document.createElement('button') as HTMLButtonElement; - button.innerText = 'Delete'; - button.onclick = onDeleteRowClick; - content.appendChild(button); - } + @state() + private batchEditingState = { + canUndo: false, + canRedo: false, + hasChanges: false, + }; - const button = content.children[0] as HTMLButtonElement; - button.disabled = e.cellInfo.isDeleted; - button.id = e.cellInfo.dataRow.toString(); - }; + @state() + private rowEditMode = false; - const editModeChanged = (event: any) => { - grid.cancelEdits(); - grid.editMode = event.target.value; - if (grid.editMode === EditModeType.None || grid.editMode === EditModeType.Cell) { - commitButton.disabled = true; - undoButton.disabled = !grid.canUndo; - redoButton.disabled = !grid.canRedo; - } - }; + @state() + private batchEditing = false; - const editModeClickActionChanged = (event: any) => { - grid.editModeClickAction = event.target.value; - }; + private undoClick = () => { + this.grid.endEdit(true); + this.grid.transactions.undo(); + } - const onCellValueChanging = (s: IgcDataGridComponent, e: IgcGridCellValueChangingEventArgs) => { - if (s.editMode === EditModeType.CellBatch || grid.editMode === EditModeType.Row) { - commitButton.disabled = !grid.canCommit; - undoButton.disabled = false; - } else if (grid.editMode === EditModeType.Cell || grid.editMode === EditModeType.None) { - commitButton.disabled = grid.canCommit; - } - if (e.newValue === '') { - commitButton.disabled = true; - s.setEditError(e.editID, 'Error, cell is empty'); - } - }; + private redoClick = () => { + this.grid.endEdit(true); + this.grid.transactions.redo(); + } - if (grid !== null) { - grid.dataSource = this.data; - grid.activationMode = GridActivationMode.Cell; - grid.selectionMode = DataGridSelectionMode.SingleCell; - grid.editMode = EditModeType.Cell; - grid.cellValueChanging = onCellValueChanging; - } + private commitClick = () => { + this.grid.endEdit(true); + this.grid.transactions.commit(this.grid.data); + } - const dropDown = this.shadowRoot?.getElementById('editModeDropBox'); - if (dropDown !== null) { - dropDown!.onchange = editModeChanged; + private async updateBatchEditing(active: boolean) { + this.batchEditing = active; + if (active) { + // await for batchEditing to apply so transactions are ready: + await this.updateComplete; + this.grid.transactions.onStateUpdate.subscribe(() => { + this.batchEditingState = { + canUndo: this.grid.transactions.canUndo, + canRedo: this.grid.transactions.canRedo, + hasChanges: this.grid.transactions.getAggregatedChanges(false).length > 0 + }; + }); } + } - const dropDown2 = this.shadowRoot?.getElementById('editModeClickActionDropBox'); - if (dropDown2 !== null) { - dropDown2!.onchange = editModeClickActionChanged; - } + render() { + return html` + +
+ ) => this.rowEditMode = e.detail.checked}> + Row Edit Mode + + ) => this.updateBatchEditing(e.detail.checked)}> + Batch Editing + + Commit + Undo + Redo +
- const deleteRowColumn = this.shadowRoot?.getElementById('deleteRowColumn') as IgcTemplateColumnComponent; - if (deleteRowColumn !== null) { - deleteRowColumn.cellUpdating = onDeleteCellUpdating; - } + + + + + + + + + + + + `; } } diff --git a/packages/cli/templates/webcomponents/igc-ts/grid/grid-editing/index.ts b/packages/cli/templates/webcomponents/igc-ts/grid/grid-editing/index.ts index f9356c296..78be35150 100644 --- a/packages/cli/templates/webcomponents/igc-ts/grid/grid-editing/index.ts +++ b/packages/cli/templates/webcomponents/igc-ts/grid/grid-editing/index.ts @@ -10,6 +10,7 @@ class IgcGridEditingTemplate extends IgniteUIForWebComponentsTemplate { this.projectType = "igc-ts"; this.name = "Grid Editing"; this.description = "IgcGrid with editing enabled"; + this.packages = [ "igniteui-webcomponents-grids@~6.0.0" ]; } } module.exports = new IgcGridEditingTemplate(); diff --git a/packages/cli/templates/webcomponents/igc-ts/grid/grid-summaries/files/src/app/__path__/__filePrefix__.ts b/packages/cli/templates/webcomponents/igc-ts/grid/grid-summaries/files/src/app/__path__/__filePrefix__.ts index 350c22ceb..697c13beb 100644 --- a/packages/cli/templates/webcomponents/igc-ts/grid/grid-summaries/files/src/app/__path__/__filePrefix__.ts +++ b/packages/cli/templates/webcomponents/igc-ts/grid/grid-summaries/files/src/app/__path__/__filePrefix__.ts @@ -1,33 +1,34 @@ import { css, html, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; -import 'igniteui-webcomponents-grids/grids/combined'; -import { IgcGridComponent } from 'igniteui-webcomponents-grids/grids'; +import { customElement, state } from 'lit/decorators.js'; import { - ComponentRenderer, - WebGridDescriptionModule, -} from 'igniteui-webcomponents-core'; + IgcGridComponent +} from 'igniteui-webcomponents-grids'; import { NwindData, } from './NwindData'; +IgcGridComponent.register(); + @customElement('app-$(path)') export default class $(ClassName) extends LitElement { - static styles = css` :host { height: 80%; margin: 0px; padding-right: 20px; width: calc(100% - 600px); - } + } `; + @state() + data = new NwindData(); + render() { return html` - +
- + @@ -39,19 +40,4 @@ export default class $(ClassName) extends LitElement {
`; } - - firstUpdated() { - const grid = this.shadowRoot?.getElementById('grid') as IgcGridComponent; - const nwindData = NwindData; - - grid.data = new nwindData(); - - const _componentRenderer = new ComponentRenderer(); - const renderer = (_componentRenderer: ComponentRenderer) => { - const context = _componentRenderer.context; - WebGridDescriptionModule.register(context); - return _componentRenderer; - } - renderer(_componentRenderer); - } } diff --git a/packages/cli/templates/webcomponents/igc-ts/grid/grid-summaries/index.ts b/packages/cli/templates/webcomponents/igc-ts/grid/grid-summaries/index.ts index 38f652027..26b4c2f51 100644 --- a/packages/cli/templates/webcomponents/igc-ts/grid/grid-summaries/index.ts +++ b/packages/cli/templates/webcomponents/igc-ts/grid/grid-summaries/index.ts @@ -10,6 +10,7 @@ class IgcGridSummariesTemplate extends IgniteUIForWebComponentsTemplate { this.projectType = "igc-ts"; this.name = "Grid Summaries"; this.description = "IgcGrid with column summaries"; + this.packages = [ "igniteui-webcomponents-grids@~6.0.0" ]; } } module.exports = new IgcGridSummariesTemplate(); diff --git a/spec/templates/angular-spec.ts b/spec/templates/angular-spec.ts index 26024308f..852b12e2c 100644 --- a/spec/templates/angular-spec.ts +++ b/spec/templates/angular-spec.ts @@ -1,8 +1,11 @@ -import { Framework, Util } from "@igniteui/cli-core"; +import { App, Framework, Util } from "@igniteui/cli-core"; const templatesLocation = "../../packages/cli/templates/angular"; describe("Angular templates", () => { + beforeAll(() => { + App.initialize(); + }); it("Templates should have IDs", async function() { const angularFramework = require(templatesLocation); @@ -27,7 +30,9 @@ describe("Angular templates", () => { // pass some __path__ so those won't match expect( (Util as any).validateTemplate(element["rootPath"] + "/files", target["rootPath"] + "/files", {path: "1"}, {}) - ).toBeTruthy(`Template ${element.id} can overwrite ${target.id}`); + ) + .withContext(`Template ${element.id} can overwrite ${target.id}`) + .toBeTruthy(); } } }); diff --git a/spec/templates/jquery-spec.ts b/spec/templates/jquery-spec.ts index 79d3c8b71..2d2cb3be2 100644 --- a/spec/templates/jquery-spec.ts +++ b/spec/templates/jquery-spec.ts @@ -1,14 +1,20 @@ +import { App } from "@igniteui/cli-core"; const templatesLocation = "../../packages/cli/templates/jquery"; describe("jQuery templates", () => { + beforeAll(() => { + App.initialize(); + }); it("Templates should have IDs", async function() { const jQueryFramework = require(templatesLocation); expect(jQueryFramework.projectLibraries[0]).toBeDefined(); for (const template of jQueryFramework.projectLibraries[0].templates) { - expect(template.id).toBeDefined("No ID: " + template.name); + expect(template.id) + .withContext("No ID: " + template.name) + .toBeDefined(); } }); diff --git a/spec/templates/react-spec.ts b/spec/templates/react-spec.ts index dbdbfeb97..f682d4092 100644 --- a/spec/templates/react-spec.ts +++ b/spec/templates/react-spec.ts @@ -1,7 +1,10 @@ -import { Framework, Util } from "@igniteui/cli-core"; +import { App, Framework, Util } from "@igniteui/cli-core"; const templatesLocation = "../../packages/cli/templates/react"; describe("React templates", () => { + beforeAll(() => { + App.initialize(); + }); it("Templates should have IDs", async function() { const reactFramework = require(templatesLocation); @@ -22,7 +25,9 @@ describe("React templates", () => { // pass some __path__ so those won't match expect( (Util as any).validateTemplate(element["rootPath"] + "/files", target["rootPath"] + "/files", {path: "1"}, {}) - ).toBeTruthy(`Template ${element.id} can overwrite ${target.id}`); + ) + .withContext(`Template ${element.id} can overwrite ${target.id}`) + .toBeTruthy(); } } }); diff --git a/spec/templates/webcomponents-spec.ts b/spec/templates/webcomponents-spec.ts new file mode 100644 index 000000000..60816bd0a --- /dev/null +++ b/spec/templates/webcomponents-spec.ts @@ -0,0 +1,38 @@ +import { App, Framework, Util } from "@igniteui/cli-core"; + +const templatesLocation = "../../packages/cli/templates/webcomponents"; +describe("Web Components templates", () => { + beforeAll(() => { + App.initialize(); + }); + + it("Templates should have IDs", async function() { + const wcFramework = require(templatesLocation); + expect(wcFramework.projectLibraries[0]).toBeDefined(); + + for (const template of wcFramework.projectLibraries[0].templates) { + expect(template.id) + .withContext("No ID: " + template.name + " type: " + template.projectType) + .toBeDefined(); + } + }); + + it("Igc Templates should have no internal collisions", async () => { + const wcFramework: Framework = require(templatesLocation); + const projLibrary = wcFramework.projectLibraries.find(x => x.projectType === "igc-ts"); + expect(projLibrary).toBeDefined(); + + for (let i = 0; i < projLibrary.templates.length; i++) { + const element = projLibrary.templates[i]; + for (let j = i + 1; j < projLibrary.templates.length; j++) { + const target = projLibrary.templates[j]; + // pass some __path__ so those won't match + expect( + (Util as any).validateTemplate(element["rootPath"] + "/files", target["rootPath"] + "/files", {path: "1"}, {}) + ) + .withContext(`Template ${element.id} can overwrite ${target.id}`) + .toBeTruthy(); + } + } + }); +});