From 29dd46c959c32b0b387b8568e5cabbbad4021755 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Mon, 30 Oct 2023 17:40:26 +0200 Subject: [PATCH 01/25] fix(simple-combo): only select with enter when dropdown is open --- .../src/lib/simple-combo/simple-combo.component.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.ts b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.ts index 513684cea98..31a82fc89fe 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.ts +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.ts @@ -303,10 +303,12 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co if (filtered === null || filtered === undefined) { return; } - this.select(this.dropdown.focusedItem.itemID); - event.preventDefault(); - event.stopPropagation(); - this.close(); + if (!this.dropdown.collapsed) { + this.select(this.dropdown.focusedItem.itemID); + event.preventDefault(); + event.stopPropagation(); + this.close(); + } // manually trigger text selection as it will not be triggered during editing this.textSelection.trigger(); this.filterValue = this.getElementVal(filtered); From 54e69db2d2b2aed7806c571d261105f2d00c152a Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Tue, 31 Oct 2023 14:20:55 +0200 Subject: [PATCH 02/25] test(combo): making sure typing tests have their inputs focused --- .../src/lib/simple-combo/simple-combo.component.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts index 4e7a1f2ff11..20158c2c587 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts @@ -915,6 +915,7 @@ describe('IgxSimpleCombo', () => { }); it('should not clear selection on tab/blur after filtering and selecting a value', () => { + combo.focusSearchInput(); UIInteractions.simulateTyping('con', input); expect(combo.comboInput.value).toEqual('con'); fixture.detectChanges(); @@ -1032,6 +1033,7 @@ describe('IgxSimpleCombo', () => { })); it('should select the first filtered item with Enter', () => { + combo.focusSearchInput(); UIInteractions.simulateTyping('con', input); expect(combo.comboInput.value).toEqual('con'); fixture.detectChanges(); From e281186d6eef26dffd6818595b9cc5e62ac5f677 Mon Sep 17 00:00:00 2001 From: Damyan Petev Date: Mon, 13 Nov 2023 15:35:26 +0200 Subject: [PATCH 03/25] fix(dropdown,select): add igxFor DI alias for tree-shaking --- .../src/lib/combo/combo-dropdown.component.ts | 1 + .../lib/directives/for-of/for_of.directive.ts | 35 ++++++++++++++++--- .../src/lib/drop-down/drop-down.component.ts | 7 ++-- projects/igniteui-angular/src/public_api.ts | 4 ++- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo-dropdown.component.ts b/projects/igniteui-angular/src/lib/combo/combo-dropdown.component.ts index 5815b281779..aaa861b4064 100644 --- a/projects/igniteui-angular/src/lib/combo/combo-dropdown.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo-dropdown.component.ts @@ -36,6 +36,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I /** @hidden @internal */ public override get scrollContainer(): HTMLElement { + // TODO: Update, use public API if possible: return this.virtDir.dc.location.nativeElement; } diff --git a/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts b/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts index c0d409f0b4c..1106a9caaa3 100644 --- a/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts @@ -79,13 +79,36 @@ export class IgxForOfContext { } +/** @hidden @internal */ +export abstract class IgxForOfToken { + public abstract igxForOf: U & T[] | null; + public abstract state: IForOfState; + public abstract totalItemCount: number; + public abstract scrollPosition: number; + + public abstract chunkLoad: EventEmitter; + public abstract chunkPreload: EventEmitter; + + public abstract scrollTo(index: number): void; + public abstract getScrollForIndex(index: number, bottom?: boolean): number; + public abstract getScroll(): HTMLElement | undefined; + + // TODO: Re-evaluate use for this internally, better expose through separate API + public abstract igxForItemSize: any; + public abstract igxForContainerSize: any; + /** @hidden */ + public abstract dc: ComponentRef +} + @Directive({ selector: '[igxFor][igxForOf]', - providers: [IgxForOfScrollSyncService], + providers: [ + IgxForOfScrollSyncService, + { provide: IgxForOfToken, useExisting: IgxForOfDirective } + ], standalone: true }) -// eslint-disable @angular-eslint/no-conflicting-lifecycle -export class IgxForOfDirective implements OnInit, OnChanges, DoCheck, OnDestroy, AfterViewInit { +export class IgxForOfDirective extends IgxForOfToken implements OnInit, OnChanges, DoCheck, OnDestroy, AfterViewInit { /** * An @Input property that sets the data to be rendered. @@ -383,7 +406,9 @@ export class IgxForOfDirective implements OnInit, OnChan protected platformUtil: PlatformUtil, @Inject(DOCUMENT) protected document: any, - ) { } + ) { + super(); + } public verticalScrollHandler(event) { this.onScroll(event); @@ -604,7 +629,7 @@ export class IgxForOfDirective implements OnInit, OnChan * * @param index */ - public scrollTo(index) { + public scrollTo(index: number) { if (index < 0 || index > (this.isRemote ? this.totalItemCount : this.igxForOf.length) - 1) { return; } diff --git a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.ts b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.ts index e3a0aadf57e..dfc1d4a1e24 100644 --- a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.ts +++ b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.ts @@ -28,7 +28,7 @@ import { IBaseCancelableBrowserEventArgs, IBaseEventArgs } from '../core/utils'; import { IgxSelectionAPIService } from '../core/selection'; import { Subject } from 'rxjs'; import { IgxDropDownItemBaseDirective } from './drop-down-item.base'; -import { IgxForOfDirective } from '../directives/for-of/for_of.directive'; +import { IgxForOfToken } from '../directives/for-of/for_of.directive'; import { take } from 'rxjs/operators'; import { DisplayDensityToken, IDisplayDensityOptions } from '../core/density'; import { OverlaySettings } from '../services/overlay/utilities'; @@ -135,8 +135,8 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID @Input() public labelledBy: string; - @ContentChild(IgxForOfDirective, { read: IgxForOfDirective }) - protected virtDir: IgxForOfDirective; + @ContentChild(IgxForOfToken) + protected virtDir: IgxForOfToken; @ViewChild(IgxToggleDirective, { static: true }) protected toggleDirective: IgxToggleDirective; @@ -343,6 +343,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID return; } let targetScroll = this.virtDir.getScrollForIndex(this.selectedItem.index); + // TODO: This logic _cannot_ be right, those are optional user-provided inputs that can be strings with units, refactor: const itemsInView = this.virtDir.igxForContainerSize / this.virtDir.igxForItemSize; targetScroll -= (itemsInView / 2 - 1) * this.virtDir.igxForItemSize; this.virtDir.getScroll().scrollTop = targetScroll; diff --git a/projects/igniteui-angular/src/public_api.ts b/projects/igniteui-angular/src/public_api.ts index 8d806987eef..b02a124207e 100644 --- a/projects/igniteui-angular/src/public_api.ts +++ b/projects/igniteui-angular/src/public_api.ts @@ -19,7 +19,9 @@ export * from './lib/directives/drag-drop/public_api'; export * from './lib/directives/filter/filter.directive'; export * from './lib/directives/focus/focus.directive'; export * from './lib/directives/focus-trap/focus-trap.directive'; -export * from './lib/directives/for-of/for_of.directive'; +export { + IgxForOfContext, IgxForOfDirective, IForOfState, IgxGridForOfContext, IgxGridForOfDirective +} from './lib/directives/for-of/for_of.directive'; export * from './lib/directives/layout/layout.directive'; export * from './lib/directives/mask/mask.directive'; export * from './lib/directives/radio/public_api'; From fbf6735ebaa56829f66b754c69902948e1d3cd7d Mon Sep 17 00:00:00 2001 From: Konstantin Dinev Date: Tue, 14 Nov 2023 12:00:13 +0200 Subject: [PATCH 04/25] Update codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5b7646ec2de..ae3f507fd3f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,10 +13,10 @@ name: "CodeQL" on: push: - branches: [ master, 16.1.x, 15.1.x ] + branches: [ master, 17.0.x, 16.1.x, 15.1.x ] pull_request: # The branches below must be a subset of the branches above - branches: [ master, 16.1.x, 15.1.x ] + branches: [ master, 17.0.x, 16.1.x, 15.1.x ] schedule: - cron: '33 4 * * 4' From 7bfb7e79f49a58eae1771b312488ea8374369bf4 Mon Sep 17 00:00:00 2001 From: jackofdiamond5 Date: Tue, 14 Nov 2023 15:43:10 +0200 Subject: [PATCH 05/25] fix(simple-combo): do not filter on enter & closed; clean up --- .../simple-combo/simple-combo.component.html | 4 +-- .../simple-combo/simple-combo.component.ts | 31 +++++-------------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.html b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.html index d2f244d15b7..da62444007e 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.html +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.html @@ -17,7 +17,7 @@ [attr.aria-expanded]="!this.dropdown.collapsed" [attr.aria-controls]="this.dropdown.listId" [attr.aria-labelledby]="this.ariaLabelledBy || this.label?.id || this.placeholder" [attr.placeholder]="placeholder" [disabled]="disabled" [igxTextSelection]="!composing" - (focus)="onFocus()" (input)="handleInputChange($event)" (click)="handleInputClick()" + (input)="handleInputChange($event)" (click)="handleInputClick()" (keyup)="handleKeyUp($event)" (keydown)="handleKeyDown($event)" (blur)="onBlur()"/> @@ -62,7 +62,7 @@ [tabindex]="dropdown.collapsed ? -1 : 0" [attr.id]="dropdown.id" [attr.aria-activedescendant]="this.activeDescendant" (focus)="dropdown.onFocus()" (keydown)="handleItemKeyDown($event)"> - =14" } }, + "node_modules/@puppeteer/browsers": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.8.0.tgz", + "integrity": "sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==", + "dev": true, + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.3.1", + "tar-fs": "3.0.4", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=16.3.0" + } + }, "node_modules/@rollup/plugin-json": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.1.tgz", @@ -4119,6 +4141,12 @@ "node": ">=6" } }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -4479,6 +4507,16 @@ "@types/node": "*" } }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz", @@ -5453,6 +5491,18 @@ "node": ">=0.10.0" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -5592,6 +5642,12 @@ "dequal": "^2.0.3" } }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", + "dev": true + }, "node_modules/babel-loader": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", @@ -5774,6 +5830,15 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/basic-ftp": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", + "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -6335,6 +6400,15 @@ "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", "dev": true }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", @@ -6692,6 +6766,25 @@ "node": ">=6.0" } }, + "node_modules/chromium-bidi": { + "version": "0.4.33", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.33.tgz", + "integrity": "sha512-IxoFM5WGQOIAd95qrSXzJUv4eXIrh+RvU3rwwqIiwYuvfE7U/Llj4fejbsJnjJMUYCuGtVQsY2gv7oGl4aTNSQ==", + "dev": true, + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "9.0.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/chromium-bidi/node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -7579,6 +7672,15 @@ "node": ">=8" } }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -7744,6 +7846,15 @@ "node": ">=0.10.0" } }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", + "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -7974,6 +8085,51 @@ "node": ">=0.10.0" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/degenerator/node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/degenerator/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/del": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", @@ -8089,6 +8245,12 @@ "node": ">= 0.8.0" } }, + "node_modules/devtools-protocol": { + "version": "0.0.1203626", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1203626.tgz", + "integrity": "sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g==", + "dev": true + }, "node_modules/di": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", @@ -9761,6 +9923,41 @@ "node": ">=0.10.0" } }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fancy-log": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", @@ -9782,6 +9979,12 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -9840,6 +10043,15 @@ "node": ">=0.8.0" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/fflate": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", @@ -10496,6 +10708,53 @@ "node": ">=6" } }, + "node_modules/get-uri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", + "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", + "dev": true, + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.0", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/get-uri/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/get-uri/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -15510,6 +15769,12 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "node_modules/mrmime": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", @@ -15702,6 +15967,15 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -15859,6 +16133,26 @@ "dev": true, "optional": true }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -16927,6 +17221,45 @@ "node": ">=6" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dev": true, + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", + "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "dev": true, + "dependencies": { + "degenerator": "^5.0.0", + "ip": "^1.1.8", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver/node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "dev": true + }, "node_modules/package-json": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", @@ -17222,6 +17555,12 @@ "node": ">=8" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -17769,6 +18108,15 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -17810,6 +18158,34 @@ "node": ">= 0.10" } }, + "node_modules/proxy-agent": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", + "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -17875,6 +18251,59 @@ "node": ">=8" } }, + "node_modules/puppeteer": { + "version": "21.5.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.5.1.tgz", + "integrity": "sha512-NkI06BXckVZeZUkODK+BbgGelQSu7uYEp9PaJDozxpwNRFDYoVfHQvd2G4dERoLdP6+qx4EBPwEhk4dEkQc2Kg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "1.8.0", + "cosmiconfig": "8.3.6", + "puppeteer-core": "21.5.1" + }, + "engines": { + "node": ">=16.3.0" + } + }, + "node_modules/puppeteer-core": { + "version": "21.5.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.5.1.tgz", + "integrity": "sha512-u6c3SZKAOaOQogaTkQvllxT/o2PP16wkbrUWINtMhfvrB4ko+xwqC1pb+vyCPMmNUh3N/CX5YGqb3DWx2fUPSQ==", + "dev": true, + "dependencies": { + "@puppeteer/browsers": "1.8.0", + "chromium-bidi": "0.4.33", + "cross-fetch": "4.0.0", + "debug": "4.3.4", + "devtools-protocol": "0.0.1203626", + "ws": "8.14.2" + }, + "engines": { + "node": ">=16.3.0" + } + }, + "node_modules/puppeteer-core/node_modules/ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -17929,6 +18358,12 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "node_modules/quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -20869,6 +21304,16 @@ "node": ">= 4.0.0" } }, + "node_modules/streamx": { + "version": "2.15.5", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.5.tgz", + "integrity": "sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -21292,6 +21737,28 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dev": true, + "dependencies": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "node_modules/tar-fs/node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -21793,6 +22260,12 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -22094,6 +22567,16 @@ "node": ">=0.8.0" } }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -22519,6 +23002,12 @@ "node": ">=4" } }, + "node_modules/urlpattern-polyfill": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", + "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", + "dev": true + }, "node_modules/use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -23315,6 +23804,12 @@ "defaults": "^1.0.3" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, "node_modules/webpack": { "version": "5.89.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", @@ -23640,6 +24135,16 @@ "node": ">=0.8.0" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -23919,6 +24424,16 @@ "node": ">=12" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index b12ace865e8..c76533a172f 100644 --- a/package.json +++ b/package.json @@ -121,6 +121,7 @@ "ng-packagr": "^17.0.0", "postcss": "^8.4.31", "postcss-scss": "^4.0.6", + "puppeteer": "^21.5.1", "sass-embedded": "^1.69.1", "sass-true": "^6.0.1", "sassdoc": "^2.7.4", @@ -132,4 +133,4 @@ "typedoc-plugin-localization": "^3.0.3", "typescript": "5.2.2" } -} \ No newline at end of file +} diff --git a/projects/igniteui-angular/karma.azure.conf.js b/projects/igniteui-angular/karma.azure.conf.js index bf674b3c3c1..1354369e599 100644 --- a/projects/igniteui-angular/karma.azure.conf.js +++ b/projects/igniteui-angular/karma.azure.conf.js @@ -1,5 +1,6 @@ // Karma configuration file, see link for more information // https://karma-runner.github.io/1.0/config/configuration-file.html +process.env.CHROME_BIN = require('puppeteer').executablePath(); module.exports = function (config) { config.set({ diff --git a/projects/igniteui-angular/karma.conf.js b/projects/igniteui-angular/karma.conf.js index 7184c34ffba..8d7de0758e3 100644 --- a/projects/igniteui-angular/karma.conf.js +++ b/projects/igniteui-angular/karma.conf.js @@ -1,7 +1,7 @@ // Karma configuration file, see link for more information // https://karma-runner.github.io/1.0/config/configuration-file.html -// process.env.CHROME_BIN = require('puppeteer').executablePath(); +process.env.CHROME_BIN = require('puppeteer').executablePath(); module.exports = function (config) { config.set({ From e748177b98382fe4f964fd5496402ec27b1b2673 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 16 Nov 2023 13:20:18 +0200 Subject: [PATCH 08/25] fix(density): inject DOCUMENT token --- projects/igniteui-angular/src/lib/core/density.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/density.ts b/projects/igniteui-angular/src/lib/core/density.ts index 08adf227c49..61b9ed9fa80 100644 --- a/projects/igniteui-angular/src/lib/core/density.ts +++ b/projects/igniteui-angular/src/lib/core/density.ts @@ -9,8 +9,10 @@ import { Optional, Inject, ElementRef, + inject, } from '@angular/core'; import { IBaseEventArgs, mkenum } from './utils'; +import { DOCUMENT } from '@angular/common'; /** * Defines the possible values of the components' display density. @@ -64,6 +66,8 @@ export const DisplayDensityToken = new InjectionToken( }) // eslint-disable-next-line @angular-eslint/directive-class-suffix export class DisplayDensityBase implements DoCheck, OnInit { + private _document = inject(DOCUMENT); + @Output() public densityChanged = new EventEmitter(); @@ -118,7 +122,7 @@ export class DisplayDensityBase implements DoCheck, OnInit { } public get size() { - return document.defaultView + return this._document.defaultView .getComputedStyle(this._host.nativeElement) .getPropertyValue('--ig-size') .trim(); From ecb1783d2f0b4ce8c8f8cbc8c06f19da63be6b5d Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 16 Nov 2023 14:31:45 +0200 Subject: [PATCH 09/25] refactor(density): inject DOCUMENT in a custom Injector Context --- .../igniteui-angular/src/lib/core/density.ts | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/density.ts b/projects/igniteui-angular/src/lib/core/density.ts index 61b9ed9fa80..83acb436665 100644 --- a/projects/igniteui-angular/src/lib/core/density.ts +++ b/projects/igniteui-angular/src/lib/core/density.ts @@ -10,10 +10,30 @@ import { Inject, ElementRef, inject, + runInInjectionContext, + Injector, } from '@angular/core'; import { IBaseEventArgs, mkenum } from './utils'; import { DOCUMENT } from '@angular/common'; +/** Create a document factory **/ +function _document(): Document { + return document; +} + +/** + * Construct a provider object to be used when creating an Injector context + */ +const documentProviders = [ + { provide: DOCUMENT, useFactory: _document } +]; + +/** + * A custom Injector context used when injecting DOCUMENT using + * the `inject` function. + */ +const documentInjector = Injector.create({ providers: documentProviders }); + /** * Defines the possible values of the components' display density. */ @@ -66,7 +86,7 @@ export const DisplayDensityToken = new InjectionToken( }) // eslint-disable-next-line @angular-eslint/directive-class-suffix export class DisplayDensityBase implements DoCheck, OnInit { - private _document = inject(DOCUMENT); + private _document: Document; @Output() public densityChanged = new EventEmitter(); @@ -145,6 +165,10 @@ export class DisplayDensityBase implements DoCheck, OnInit { protected _host: ElementRef ) { Object.assign(this.oldDisplayDensityOptions, displayDensityOptions); + + runInInjectionContext(documentInjector, () => { + this._document = inject(DOCUMENT); + }); } /** From b28dc7e7eb593684c0880270e44e6647a669f95c Mon Sep 17 00:00:00 2001 From: Teodosia Hristodorova <52423497+teodosiah@users.noreply.github.com> Date: Thu, 16 Nov 2023 17:23:37 +0200 Subject: [PATCH 10/25] fix(grid): save disablePinning property of all grids (#13651) --- .../src/lib/grids/state.directive.spec.ts | 21 ++++++++++--------- .../src/lib/grids/state.directive.ts | 4 +++- .../lib/grids/state.hierarchicalgrid.spec.ts | 12 +++++------ .../src/lib/grids/state.pivotgrid.spec.ts | 10 ++++----- .../src/lib/grids/state.treegrid.spec.ts | 6 +++--- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/state.directive.spec.ts b/projects/igniteui-angular/src/lib/grids/state.directive.spec.ts index e41ddb9565c..5834d37cd71 100644 --- a/projects/igniteui-angular/src/lib/grids/state.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/state.directive.spec.ts @@ -82,7 +82,7 @@ describe('IgxGridState - input properties #grid', () => { }); it('getState should return correct JSON string', () => { - const initialGridState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"groupBy":{"expressions":[],"expansion":[],"defaultExpanded":true},"paging":{"index":0,"recordsPerPage":15,"metadata":{"countPages":1,"countRecords":10,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"moving":true}'; + const initialGridState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"groupBy":{"expressions":[],"expansion":[],"defaultExpanded":true},"paging":{"index":0,"recordsPerPage":15,"metadata":{"countPages":1,"countRecords":10,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"moving":true}'; const fix = TestBed.createComponent(IgxGridStateComponent); fix.detectChanges(); @@ -359,8 +359,8 @@ describe('IgxGridState - input properties #grid', () => { fix.detectChanges(); const state = fix.componentInstance.state; /* eslint-disable max-len */ - const columnsState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}]}'; - const initialState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false}]}'; + const columnsState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]}'; + const initialState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]}'; /* eslint-enable max-len */ const columns = JSON.parse(columnsState).columns; @@ -381,8 +381,8 @@ describe('IgxGridState - input properties #grid', () => { const grid = fix.componentInstance.grid; spyOn(grid.columnInit, 'emit').and.callThrough(); /* eslint-disable max-len */ - const columnsState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"200px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}]}'; - const initialState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false}]}'; + const columnsState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"200px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]}'; + const initialState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true,"selectable":false,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]}'; /* eslint-enable max-len */ const columnsStateObject = JSON.parse(columnsState); @@ -771,7 +771,8 @@ class HelperFunctions { [header]="c.header" [dataType]="c.dataType" [pinned]="c.pinned" - [hidden]="c.hidden"> + [hidden]="c.hidden" + [disablePinning]="c.disablePinning"> @@ -790,10 +791,10 @@ export class IgxGridStateComponent { public columns: any[] = [ /* eslint-disable max-len */ - { field: 'ProductID', header: 'Product ID', width: '150px', dataType: 'number', pinned: true, sortable: true, filterable: true, groupable: false, hasSummary: false, hidden: false, maxWidth: '300px', searchable: false, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: false, headerClasses: 'testCss', headerGroupClasses: '', resizable: true }, - { field: 'ProductName', header: 'Prodyct Name', width: '150px', dataType: 'string', pinned: false, selectable: false, sortable: true, filterable: true, groupable: true, hasSummary: false, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: false, headerClasses: '', headerGroupClasses: '', resizable: true }, - { field: 'InStock', header: 'In Stock', width: '140px', dataType: 'boolean', pinned: false, sortable: false, filterable: true, groupable: false, hasSummary: true, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: true, headerClasses: '', headerGroupClasses: '', resizable: true }, - { field: 'OrderDate', header: 'Date ordered', width: '110px', dataType: 'date', pinned: false, sortable: true, filterable: false, groupable: true, hasSummary: false, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: true, headerClasses: '', headerGroupClasses: '', resizable: false }, + { field: 'ProductID', header: 'Product ID', width: '150px', dataType: 'number', pinned: true, sortable: true, filterable: true, groupable: false, hasSummary: false, hidden: false, maxWidth: '300px', searchable: false, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: false, headerClasses: 'testCss', headerGroupClasses: '', resizable: true, disablePinning: false }, + { field: 'ProductName', header: 'Prodyct Name', width: '150px', dataType: 'string', pinned: false, selectable: false, sortable: true, filterable: true, groupable: true, hasSummary: false, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: false, headerClasses: '', headerGroupClasses: '', resizable: true, disablePinning: false }, + { field: 'InStock', header: 'In Stock', width: '140px', dataType: 'boolean', pinned: false, sortable: false, filterable: true, groupable: false, hasSummary: true, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: true, headerClasses: '', headerGroupClasses: '', resizable: true, disablePinning: true }, + { field: 'OrderDate', header: 'Date ordered', width: '110px', dataType: 'date', pinned: false, sortable: true, filterable: false, groupable: true, hasSummary: false, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: true, headerClasses: '', headerGroupClasses: '', resizable: false, disablePinning: false }, /* eslint-enable max-len */ ]; } diff --git a/projects/igniteui-angular/src/lib/grids/state.directive.ts b/projects/igniteui-angular/src/lib/grids/state.directive.ts index bfbad50741b..bdbb1e04b12 100644 --- a/projects/igniteui-angular/src/lib/grids/state.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/state.directive.ts @@ -89,6 +89,7 @@ export interface IColumnState { columnGroup: boolean; parent: any; disableHiding: boolean; + disablePinning: boolean; } export type GridFeatures = keyof IGridStateOptions; @@ -200,7 +201,8 @@ export class IgxGridStateDirective { selectable: c.selectable, parent: c.parent ? c.parent.header : null, columnGroup: c.columnGroup, - disableHiding: c.disableHiding + disableHiding: c.disableHiding, + disablePinning: c.disablePinning })); return { columns: gridColumns }; }, diff --git a/projects/igniteui-angular/src/lib/grids/state.hierarchicalgrid.spec.ts b/projects/igniteui-angular/src/lib/grids/state.hierarchicalgrid.spec.ts index 691f3a7dcb7..258f38f1abb 100644 --- a/projects/igniteui-angular/src/lib/grids/state.hierarchicalgrid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/state.hierarchicalgrid.spec.ts @@ -91,7 +91,7 @@ describe('IgxHierarchicalGridState - input properties #hGrid', () => { it('getState should return corect JSON string', () => { pending(); - const initialGridState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":true}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":4,"countRecords":20,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[{"id":"igx-row-island-childData","parentRowID":"0","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":2,"countRecords":7,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"1","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":3,"countRecords":14,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"2","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":2,"countRecords":7,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"3","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":3,"countRecords":14,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"4","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":2,"countRecords":7,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}}]}'; + const initialGridState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":true,"disablePinning":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":4,"countRecords":20,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[{"id":"igx-row-island-childData","parentRowID":"0","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":2,"countRecords":7,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"1","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":3,"countRecords":14,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"2","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":2,"countRecords":7,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"3","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":3,"countRecords":14,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"4","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"disableHiding":true,"disablePinning":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":2,"countRecords":7,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"rowIslands":[]}}]}'; fix.detectChanges(); const state = fix.componentInstance.state; @@ -467,11 +467,11 @@ describe('IgxHierarchicalGridState - input properties #hGrid', () => { fix.detectChanges(); const state = fix.componentInstance.state; - // const rootGridColumns = '[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}]'; - // const childGridColumns = '[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}]'; - const initialState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}],"rowIslands":[{"id":"igx-row-island-childData","parentRowID":"0","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"1","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"2","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"3","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"4","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}],"rowIslands":[]}}]}' - const newRootGridColumns = '[{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}]'; - const newChildGridColumns = '[{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":true,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":true,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":true,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":true,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}]'; + // const rootGridColumns = '[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false,"disablePinning":false}]'; + // const childGridColumns = '[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]'; + const initialState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}],"rowIslands":[{"id":"igx-row-island-childData","parentRowID":"0","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"1","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"2","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"3","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}],"rowIslands":[]}},{"id":"igx-row-island-childData","parentRowID":"4","state":{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}],"rowIslands":[]}}]}' + const newRootGridColumns = '[{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]'; + const newChildGridColumns = '[{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":true,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"Product ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":true,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Product Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":true,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"Col1","width":"140px","header":"Col 1","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":true,"dataType":"date","hasSummary":false,"field":"Col2","width":"110px","header":"Col 2","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"Col3","width":"110px","header":"Col 3","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]'; const newColumnsState = HelperFunctions.buildStateString(grid, 'columns', newRootGridColumns, newChildGridColumns); fix.detectChanges(); let gridState = state.getState(true, ['columns', 'rowIslands']); diff --git a/projects/igniteui-angular/src/lib/grids/state.pivotgrid.spec.ts b/projects/igniteui-angular/src/lib/grids/state.pivotgrid.spec.ts index 535f6b9aa73..ba54f4f110b 100644 --- a/projects/igniteui-angular/src/lib/grids/state.pivotgrid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/state.pivotgrid.spec.ts @@ -32,11 +32,11 @@ describe('IgxPivotGridState #pivotGrid :', () => { const jsonString = state.getState(true); const expectedObj = { "columns": [ - { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "Bulgaria", "width": "220px", "header": "Bulgaria", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false }, - { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "US", "width": "220px", "header": "US", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false }, - { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "Uruguay", "width": "220px", "header": "Uruguay", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false }, - { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "UK", "width": "220px", "header": "UK", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false }, - { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "Japan", "width": "220px", "header": "Japan", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false } + { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "Bulgaria", "width": "220px", "header": "Bulgaria", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false, "disablePinning": false }, + { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "US", "width": "220px", "header": "US", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false, "disablePinning": false }, + { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "Uruguay", "width": "220px", "header": "Uruguay", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false, "disablePinning": false }, + { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "UK", "width": "220px", "header": "UK", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false, "disablePinning": false }, + { "pinned": false, "sortable": true, "filterable": true, "sortingIgnoreCase": true, "filteringIgnoreCase": true, "headerClasses": "", "headerGroupClasses": "", "groupable": false, "movable": false, "hidden": false, "dataType": "number", "hasSummary": false, "field": "Japan", "width": "220px", "header": "Japan", "resizable": false, "searchable": true, "selectable": true, "parent": null, "columnGroup": false, "disableHiding": false, "disablePinning": false } ], "filtering": { "filteringOperands": [], "operator": 0, "type": 0 }, "advancedFiltering": {}, "sorting": [], "cellSelection": [], "rowSelection": [], "columnSelection": [], diff --git a/projects/igniteui-angular/src/lib/grids/state.treegrid.spec.ts b/projects/igniteui-angular/src/lib/grids/state.treegrid.spec.ts index dcbd64afce9..010b4b822dd 100644 --- a/projects/igniteui-angular/src/lib/grids/state.treegrid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/state.treegrid.spec.ts @@ -83,7 +83,7 @@ describe('IgxTreeGridState - input properties #tGrid', () => { it('getState should return corect JSON string', () => { // eslint-disable-next-line max-len - const initialGridState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"Name","width":"150px","header":"Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"date","hasSummary":true,"field":"Hire Date","width":"140px","header":"Hire Date","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"Age","width":"110px","header":"Age","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":4,"countRecords":18,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"moving":true,"rowIslands":[]}'; + const initialGridState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"Name","width":"150px","header":"Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"date","hasSummary":true,"field":"Hire Date","width":"140px","header":"Hire Date","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"Age","width":"110px","header":"Age","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{},"sorting":[],"paging":{"index":0,"recordsPerPage":5,"metadata":{"countPages":4,"countRecords":18,"error":0}},"cellSelection":[],"rowSelection":[],"columnSelection":[],"rowPinning":[],"expansion":[],"moving":true,"rowIslands":[]}'; fix.detectChanges(); const state = fix.componentInstance.state; @@ -198,8 +198,8 @@ describe('IgxTreeGridState - input properties #tGrid', () => { fix.detectChanges(); const state = fix.componentInstance.state; /* eslint-disable max-len */ - const initialColumnsState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"Name","width":"150px","header":"Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"date","hasSummary":true,"field":"Hire Date","width":"140px","header":"Hire Date","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":true,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"Age","width":"110px","header":"Age","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}]}'; - const newColumnsState = '{"columns":[{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"Name","width":"150px","header":"Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":true},{"pinned":false,"sortable":true,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"Age","width":"110px","header":"Age","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"date","hasSummary":true,"field":"Hire Date","width":"140px","header":"Hire Date","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false}]}'; + const initialColumnsState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"string","hasSummary":false,"field":"Name","width":"150px","header":"Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"date","hasSummary":true,"field":"Hire Date","width":"140px","header":"Hire Date","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"Age","width":"110px","header":"Age","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]}'; + const newColumnsState = '{"columns":[{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ID","width":"150px","header":"ID","resizable":true,"searchable":false,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"Name","width":"150px","header":"Name","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":true,"disablePinning":false},{"pinned":false,"sortable":true,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"number","hasSummary":false,"field":"Age","width":"110px","header":"Age","resizable":false,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"date","hasSummary":true,"field":"Hire Date","width":"140px","header":"Hire Date","resizable":true,"searchable":true,"selectable":true,"parent":null,"columnGroup":false,"disableHiding":false,"disablePinning":false}]}'; /* eslint-enable max-len */ const columns = JSON.parse(newColumnsState).columns; From 6824cb8169332ace0175d14f607df9b81cdae192 Mon Sep 17 00:00:00 2001 From: Konstantin Dinev Date: Mon, 20 Nov 2023 10:33:02 +0200 Subject: [PATCH 11/25] test(ssr): adding a test project --- angular.json | 104 ++ package-lock.json | 934 ++++++++++++------ package.json | 45 +- projects/ssr-test/server.ts | 56 ++ projects/ssr-test/src/app/app.component.html | 7 + projects/ssr-test/src/app/app.component.scss | 0 .../ssr-test/src/app/app.component.spec.ts | 29 + projects/ssr-test/src/app/app.component.ts | 14 + .../ssr-test/src/app/app.config.server.ts | 11 + projects/ssr-test/src/app/app.config.ts | 9 + projects/ssr-test/src/app/app.routes.ts | 3 + projects/ssr-test/src/assets/.gitkeep | 0 projects/ssr-test/src/favicon.ico | Bin 0 -> 15086 bytes projects/ssr-test/src/index.html | 13 + projects/ssr-test/src/main.server.ts | 7 + projects/ssr-test/src/main.ts | 6 + projects/ssr-test/src/styles.scss | 27 + projects/ssr-test/tsconfig.app.json | 30 + projects/ssr-test/tsconfig.spec.json | 14 + 19 files changed, 994 insertions(+), 315 deletions(-) create mode 100644 projects/ssr-test/server.ts create mode 100644 projects/ssr-test/src/app/app.component.html create mode 100644 projects/ssr-test/src/app/app.component.scss create mode 100644 projects/ssr-test/src/app/app.component.spec.ts create mode 100644 projects/ssr-test/src/app/app.component.ts create mode 100644 projects/ssr-test/src/app/app.config.server.ts create mode 100644 projects/ssr-test/src/app/app.config.ts create mode 100644 projects/ssr-test/src/app/app.routes.ts create mode 100644 projects/ssr-test/src/assets/.gitkeep create mode 100644 projects/ssr-test/src/favicon.ico create mode 100644 projects/ssr-test/src/index.html create mode 100644 projects/ssr-test/src/main.server.ts create mode 100644 projects/ssr-test/src/main.ts create mode 100644 projects/ssr-test/src/styles.scss create mode 100644 projects/ssr-test/tsconfig.app.json create mode 100644 projects/ssr-test/tsconfig.spec.json diff --git a/angular.json b/angular.json index f9c478afe8a..e10e6ffa784 100644 --- a/angular.json +++ b/angular.json @@ -335,6 +335,110 @@ } } } + }, + "ssr-test": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "projects/ssr-test", + "sourceRoot": "projects/ssr-test/src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/ssr-test", + "index": "projects/ssr-test/src/index.html", + "browser": "projects/ssr-test/src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "projects/ssr-test/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "projects/ssr-test/src/favicon.ico", + "projects/ssr-test/src/assets" + ], + "styles": [ + "projects/ssr-test/src/styles.scss" + ], + "scripts": [], + "server": "projects/ssr-test/src/main.server.ts", + "prerender": true, + "ssr": { + "entry": "projects/ssr-test/server.ts" + }, + "stylePreprocessorOptions": { + "includePaths": [ + "node_modules" + ] + } + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "ssr-test:build:production" + }, + "development": { + "buildTarget": "ssr-test:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "ssr-test:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "projects/ssr-test/tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": [ + "projects/ssr-test/src/favicon.ico", + "projects/ssr-test/src/assets" + ], + "styles": [ + "projects/ssr-test/src/styles.scss" + ], + "scripts": [] + } + } + } } }, "cli": { diff --git a/package-lock.json b/package-lock.json index d15152028cb..99f77c7ef60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,20 @@ "version": "0.0.0", "hasInstallScript": true, "dependencies": { - "@angular/animations": "^17.0.1", - "@angular/common": "^17.0.1", - "@angular/compiler": "^17.0.1", - "@angular/core": "^17.0.1", - "@angular/forms": "^17.0.1", - "@angular/platform-browser": "^17.0.1", - "@angular/platform-browser-dynamic": "^17.0.1", - "@angular/router": "^17.0.1", + "@angular/animations": "^17.0.3", + "@angular/common": "^17.0.3", + "@angular/compiler": "^17.0.3", + "@angular/core": "^17.0.3", + "@angular/forms": "^17.0.3", + "@angular/platform-browser": "^17.0.3", + "@angular/platform-browser-dynamic": "^17.0.3", + "@angular/platform-server": "^17.0.3", + "@angular/router": "^17.0.3", + "@angular/ssr": "^17.0.1", "@igniteui/material-icons-extended": "^3.0.0", "@types/hammerjs": "^2.0.40", "@types/source-map": "0.5.2", + "express": "^4.18.2", "fflate": "^0.7.3", "hammerjs": "^2.0.8", "igniteui-theming": "^3.3.0", @@ -31,18 +34,19 @@ "zone.js": "~0.14.2" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.0.0", - "@angular-devkit/schematics": "^17.0.0", - "@angular-eslint/builder": "^17.0.0", - "@angular-eslint/eslint-plugin": "^17.0.0", - "@angular-eslint/eslint-plugin-template": "^17.0.0", - "@angular-eslint/schematics": "^17.0.0", - "@angular-eslint/template-parser": "^17.0.0", - "@angular/cli": "^17.0.0", - "@angular/compiler-cli": "^17.0.1", - "@angular/language-service": "^17.0.1", + "@angular-devkit/build-angular": "^17.0.1", + "@angular-devkit/schematics": "^17.0.1", + "@angular-eslint/builder": "^17.1.0", + "@angular-eslint/eslint-plugin": "^17.1.0", + "@angular-eslint/eslint-plugin-template": "^17.1.0", + "@angular-eslint/schematics": "^17.1.0", + "@angular-eslint/template-parser": "^17.1.0", + "@angular/cli": "^17.0.1", + "@angular/compiler-cli": "^17.0.3", + "@angular/language-service": "^17.0.3", "@angularclass/hmr": "^3.0.0", "@types/estree": "^1.0.0", + "@types/express": "^4.17.17", "@types/jasmine": "^5.1.1", "@types/jasminewd2": "^2.0.10", "@types/node": "^20.8.9", @@ -113,12 +117,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1700.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1700.0.tgz", - "integrity": "sha512-whi7HvOjv1J3He9f+H8xNJWKyjAmWuWNl8gxNW6EZP/XLcrOu+/5QT4bPtXQBRIL/avZuc++5sNQS+kReaNCig==", + "version": "0.1700.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1700.1.tgz", + "integrity": "sha512-w84luzQNRjlt7XxX3+jyzcwBBv3gAjjvFWTjN1E5mlpDCUXgYmQ3CMowFHeu0U06HD5Sapap9p2l6GoajuZK5Q==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.0.0", + "@angular-devkit/core": "17.0.1", "rxjs": "7.8.1" }, "engines": { @@ -137,15 +141,15 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.0.0.tgz", - "integrity": "sha512-hkV8k4moAnUquac2Dz5XPd5izDDgEF82NeUkSwizcTaqlJqYOdmWASMsXyVBzdrTmDtFKQiphfA96i7eo5MlvA==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.0.1.tgz", + "integrity": "sha512-OomGAeBg/OOxzPpoU7EkdD3WwhKip+0Giy/cGtkalSgQ5vWTuZhf8UnxwTf7xEXW5LtvfoTtv7sKmb1dJT7FzA==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.1", - "@angular-devkit/architect": "0.1700.0", - "@angular-devkit/build-webpack": "0.1700.0", - "@angular-devkit/core": "17.0.0", + "@angular-devkit/architect": "0.1700.1", + "@angular-devkit/build-webpack": "0.1700.1", + "@angular-devkit/core": "17.0.1", "@babel/core": "7.23.2", "@babel/generator": "7.23.0", "@babel/helper-annotate-as-pure": "7.22.5", @@ -156,7 +160,7 @@ "@babel/preset-env": "7.23.2", "@babel/runtime": "7.23.2", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "17.0.0", + "@ngtools/webpack": "17.0.1", "@vitejs/plugin-basic-ssl": "1.0.1", "ansi-colors": "4.1.3", "autoprefixer": "10.4.16", @@ -269,12 +273,12 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1700.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1700.0.tgz", - "integrity": "sha512-Hx9JUb32gigsHlbBZJ5sw3q3H7qHeX8HTh4aIq4Glvb/5e+HgPlclVSIA5BY2ZYatHixU+CUAXRmcIKxViS02Q==", + "version": "0.1700.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1700.1.tgz", + "integrity": "sha512-u9LTcG9Kg2J6WkF1WSoBLdDabhbKxcuHY24SouAJTwg33j6YksglL7qnofOsNxny3Gdnze2BhCjQ1GS9Y8ovXw==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1700.0", + "@angular-devkit/architect": "0.1700.1", "rxjs": "7.8.1" }, "engines": { @@ -297,9 +301,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.0.tgz", - "integrity": "sha512-QUu3LnEi4A8t733v2+I0sLtyBJx3Q7zdTAhaauCbxbFhDid0cbYm8hYsyG/njor1irTPxSJbn6UoetVkwUQZxg==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.1.tgz", + "integrity": "sha512-UjNx9fZW0oU7UaeoB0HblYz/Nm8MWtinAe39XkY+zjECLWqKAcHPotfYjucXiky1UlBUOScIKbwjMDdEY8xkuw==", "dev": true, "dependencies": { "ajv": "8.12.0", @@ -333,12 +337,12 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.0.0.tgz", - "integrity": "sha512-LD7fjDORuBf139/oJ/gSwbIzQPfsm6Y67s1FD+XLi0QXaRt6dw4r7BMD08l1r//oPQofNgbEH4coGVO4NdCL/A==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.0.1.tgz", + "integrity": "sha512-bwgdGviRZC5X8Tl4QcjtIJAcC0p8yIhOyYVFrq4PWYvI+DfV9P6w3OFuoS6rwEoiIQR90+12iKBYMt1MfL/c0Q==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.0.0", + "@angular-devkit/core": "17.0.1", "jsonc-parser": "3.2.0", "magic-string": "0.30.5", "ora": "5.4.1", @@ -360,13 +364,13 @@ } }, "node_modules/@angular-eslint/builder": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-17.0.0.tgz", - "integrity": "sha512-cquqJH0R/IIh2PElcGXdo9FTcrkwO78H2MXk9ChGFBjQrYjihFLhFm12VuQsih7X6bJjA0cmr2PL1KbtgjMk1Q==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-17.1.0.tgz", + "integrity": "sha512-rLIInxx9q82DDrfcg5gzjNftxhkqdLILUgjlA9XtA9LayU3rz4CS81we+vAOAPbbnGxoMsEeBg5nVecbKN3dVQ==", "dev": true, "dependencies": { - "@nx/devkit": "17.0.3", - "nx": "17.0.3" + "@nx/devkit": "17.1.2", + "nx": "17.1.2" }, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", @@ -374,19 +378,19 @@ } }, "node_modules/@angular-eslint/bundled-angular-compiler": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.0.0.tgz", - "integrity": "sha512-nHLliW18XduO51+e/RST8O2YnhcQR3+NSSy8zlmYyjLeUi5NBpC/Hwp68KxPP2YcUYie1tWlaw48YJYo97qE6A==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.1.0.tgz", + "integrity": "sha512-Y+CN/8nQZaYjsb2b2sXbkQr0LrgBWhCzyLZ+rLfnLE60B9k4GeDt5b7z/OdSObi1xozXfqiaAZ1eXo0iQMN3JA==", "dev": true }, "node_modules/@angular-eslint/eslint-plugin": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-17.0.0.tgz", - "integrity": "sha512-I2gb7hDthNiWbeNXlINBYQIbwKkPPM8442EIPeWtwgOQ2qjMwTAz1l3FA46U7pwbaXsdlY0p9Kp4ABy9T0cknA==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-17.1.0.tgz", + "integrity": "sha512-pQac5h+XwsquDzaasK/xs9tjdQ/f9eLq8e5An9eXJGHWy4KcrMmQ1XrpaMMMg503LF3rRG/dHKBskGsYgSN9oQ==", "dev": true, "dependencies": { - "@angular-eslint/utils": "17.0.0", - "@typescript-eslint/utils": "6.10.0" + "@angular-eslint/utils": "17.1.0", + "@typescript-eslint/utils": "6.11.0" }, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", @@ -394,15 +398,15 @@ } }, "node_modules/@angular-eslint/eslint-plugin-template": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.0.0.tgz", - "integrity": "sha512-Yy9097HAkMEiYANGw2UZQuJSO0fXpBWUMOxwWUFDD5Am7eB51a+5BiOdBe8uy4lM5OnIfm+aIASwbmvPHwjjTA==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.1.0.tgz", + "integrity": "sha512-nL9VhChwFQLIRQM4xbTY8Vo095Q4/D77hPtqt3ShYIrORjYTwaWa8+neexToAqXVMapce7oFmFa/OqtxvEerLg==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.0.0", - "@angular-eslint/utils": "17.0.0", - "@typescript-eslint/type-utils": "6.10.0", - "@typescript-eslint/utils": "6.10.0", + "@angular-eslint/bundled-angular-compiler": "17.1.0", + "@angular-eslint/utils": "17.1.0", + "@typescript-eslint/type-utils": "6.11.0", + "@typescript-eslint/utils": "6.11.0", "aria-query": "5.3.0", "axobject-query": "4.0.0" }, @@ -411,17 +415,282 @@ "typescript": "*" } }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/@typescript-eslint/scope-manager": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz", + "integrity": "sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/@typescript-eslint/type-utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.11.0.tgz", + "integrity": "sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.11.0", + "@typescript-eslint/utils": "6.11.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/@typescript-eslint/types": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.11.0.tgz", + "integrity": "sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz", + "integrity": "sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/@typescript-eslint/utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.11.0.tgz", + "integrity": "sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.11.0", + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/typescript-estree": "6.11.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz", + "integrity": "sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz", + "integrity": "sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.11.0.tgz", + "integrity": "sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz", + "integrity": "sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.11.0.tgz", + "integrity": "sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.11.0", + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/typescript-estree": "6.11.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@angular-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz", + "integrity": "sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/eslint-plugin/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@angular-eslint/schematics": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-17.0.0.tgz", - "integrity": "sha512-lNeLPJoCjq67D0SHIehcseJqMe2rG485inH8ZmA1bIoRYAyQ3s/sLH2+Qbkh7aP3m+Jd3TVLArt3g1hbqFWRUA==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-17.1.0.tgz", + "integrity": "sha512-74gW1E5P4z3PvxNXOTXGaF6li/MLcSeJO8z7XtcP7wcXWu0fihOKlMJGgqB3rIcBa8lRcTDLekQERF+kRZ15aQ==", "dev": true, "dependencies": { - "@angular-eslint/eslint-plugin": "17.0.0", - "@angular-eslint/eslint-plugin-template": "17.0.0", - "@nx/devkit": "17.0.3", + "@angular-eslint/eslint-plugin": "17.1.0", + "@angular-eslint/eslint-plugin-template": "17.1.0", + "@nx/devkit": "17.1.2", "ignore": "5.2.4", - "nx": "17.0.3", + "nx": "17.1.2", "strip-json-comments": "3.1.1", "tmp": "0.2.1" }, @@ -430,12 +699,12 @@ } }, "node_modules/@angular-eslint/template-parser": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-17.0.0.tgz", - "integrity": "sha512-uYdANaTVEXxvsTYPQU0dh7dNK4b9Ez6y512DH9Hgnv1T6CSwBPjMk0/rQfefJevk+LxDjCBspnbXcgnY/yi88Q==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-17.1.0.tgz", + "integrity": "sha512-CTxzB3stjynngTabdO8xTkiPc6Jvo15C2fxb1pYIlDIH2LgPJJxxCHi+IAt9oJpJOPa8QjLVF9VAXE3fLKAcpg==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.0.0", + "@angular-eslint/bundled-angular-compiler": "17.1.0", "eslint-scope": "^7.0.0" }, "peerDependencies": { @@ -444,23 +713,142 @@ } }, "node_modules/@angular-eslint/utils": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-17.0.0.tgz", - "integrity": "sha512-kfKk4jqmvX/aFCHhl3BfAyvF+DRE/qPyGMBbFL/dm7mRTr4ZRsNX88KyzpWlA9tD355b+cFvM2jd9hqtPM8KIQ==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-17.1.0.tgz", + "integrity": "sha512-AmG0xpRtnBQwrbHObonSilmD3hiFEtZHwFY3LT28VWxznB6WIAHFE7SrKWrRsRsXlib8LaRo4uobR5+MO8aLpw==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.0.0", - "@typescript-eslint/utils": "6.10.0" + "@angular-eslint/bundled-angular-compiler": "17.1.0", + "@typescript-eslint/utils": "6.11.0" }, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", "typescript": "*" } }, + "node_modules/@angular-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz", + "integrity": "sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.11.0.tgz", + "integrity": "sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz", + "integrity": "sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/visitor-keys": "6.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular-eslint/utils/node_modules/@typescript-eslint/utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.11.0.tgz", + "integrity": "sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.11.0", + "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/typescript-estree": "6.11.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@angular-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz", + "integrity": "sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.11.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@angular-eslint/utils/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@angular/animations": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-17.0.1.tgz", - "integrity": "sha512-Uee6E8zyU6XjDfKFozybcf+JZy0nUFQ1bUEmRwFP5HvYJSSJ5YiUDokNiVxyn9znwZ7zKHlM6Bq9ZY9cCmeKKQ==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-17.0.3.tgz", + "integrity": "sha512-aBLVJ0HHYdIZCAXymQDP6UGuz/5oM/3uLCFVHx32vhibLByjw0jNCvy2lzmPLU5gUU6wEWX2b3ZtnzFqhmo4+A==", "dependencies": { "tslib": "^2.3.0" }, @@ -468,19 +856,19 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.0.1" + "@angular/core": "17.0.3" } }, "node_modules/@angular/cli": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.0.0.tgz", - "integrity": "sha512-VzKYmN+1wSE2wLBEFu/NHSrRQbeaKkEDO9aZxd7nAnxC5T1Zcva7dfqZIXMHXH2HESYAZCvOS8ikBE/7DCtWWw==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.0.1.tgz", + "integrity": "sha512-3iJWw+bpr/8y1ZY1m0wGfukffQVmD6DJUNubB297NCq1bJyUj+uwBuDnpIH+vidJvPBEEY+9XPJr0Jnd6+i7rg==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1700.0", - "@angular-devkit/core": "17.0.0", - "@angular-devkit/schematics": "17.0.0", - "@schematics/angular": "17.0.0", + "@angular-devkit/architect": "0.1700.1", + "@angular-devkit/core": "17.0.1", + "@angular-devkit/schematics": "17.0.1", + "@schematics/angular": "17.0.1", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "ini": "4.1.1", @@ -506,9 +894,9 @@ } }, "node_modules/@angular/common": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.0.1.tgz", - "integrity": "sha512-AvvhZc+PhX5lVEW/Vorxe3Zf1rIEJJvfduRuRv+nsjijo3ZGjdgYjTYEx4ighZgH60RLIAuwyBE24gPkT2Pm7g==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.0.3.tgz", + "integrity": "sha512-AD/d1n0hNisHDhIeBsW2ERZI9ChjiOuZ3IiGwcYKmlcOHTrZTJPAh/ZMgahv24rArlNVax7bT+Ik8+sJedGcEQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -516,14 +904,14 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.0.1", + "@angular/core": "17.0.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.0.1.tgz", - "integrity": "sha512-qlKqCvjoxPHJ1e8+UMaBl/n9zzrmGXI5eWMVhULSvQnQvPWkwNlUh5XFeoSFcTEQxORjaO2/08Z31DmTJAqlPA==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.0.3.tgz", + "integrity": "sha512-ryUcj8Vc+Q4jMrjrmsEIsGLXeWSmNE/KoTyURPCH+NWq9GBMbjv4oe0/oFSBMN2ZtRMVCvqv2Nq+Z2KRDRGB0A==", "dependencies": { "tslib": "^2.3.0" }, @@ -531,7 +919,7 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.0.1" + "@angular/core": "17.0.3" }, "peerDependenciesMeta": { "@angular/core": { @@ -540,9 +928,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.0.1.tgz", - "integrity": "sha512-Rnvh2V2CYhG7NR5VI4cESGKk9jyqLat0HoqXa06v3TtbjkiZyjjwh0SyZ8NYOBMkQeWiQTHGcgxGvjKD3L3qqA==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.0.3.tgz", + "integrity": "sha512-oj7KJBFgs6ulT1/A/xkkDHBOB0c7o9HV2Mn5pUosXBo2VgcGYeuJeXffC+mFr5FyiRO1sUanw4vSWnLzK1U0pQ==", "dev": true, "dependencies": { "@babel/core": "7.23.2", @@ -563,14 +951,14 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/compiler": "17.0.1", + "@angular/compiler": "17.0.3", "typescript": ">=5.2 <5.3" } }, "node_modules/@angular/core": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.0.1.tgz", - "integrity": "sha512-yVwU+oz0G8g6Q5ORyOCpgqMPdSiCdfW+uQhjI37WROnXHja3jY843AqrYTKE6mMx1r6q9h1wbDy+x2E61OWP7A==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.0.3.tgz", + "integrity": "sha512-zY4yhPiphuktrodaM+GiP8G07qnUlmwKElLjYazeIR8A+kF51RQRpSf/pWe5M0uJIn5Oja+RdO9kzhDI9QvOcA==", "dependencies": { "tslib": "^2.3.0" }, @@ -583,9 +971,9 @@ } }, "node_modules/@angular/forms": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.0.1.tgz", - "integrity": "sha512-FpmUf2kgzwZXVbFB4VrwbnrO0m88QLUBsDsbLfQVQQwb7KxwSaftUu/aIrjst1gFCdl9k0Vqtrq2gwLZKzdSGQ==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.0.3.tgz", + "integrity": "sha512-slCUGe5nVOrA0Su9pkmgPXBVzkgh4stvVFBb6ic9/+GlmtRi8h1v5jAFhR4B0R4iaaIoF+TTpRKhZShwtFSqSg==", "dependencies": { "tslib": "^2.3.0" }, @@ -593,25 +981,25 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.0.1", - "@angular/core": "17.0.1", - "@angular/platform-browser": "17.0.1", + "@angular/common": "17.0.3", + "@angular/core": "17.0.3", + "@angular/platform-browser": "17.0.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-17.0.1.tgz", - "integrity": "sha512-kDKmtMj410We8Rbph4e2xSuIs+MlzE7+QvIR07tofcoAR6Qpe2hr6WdsfExGBNIk5LNMYI3zdbEkAofG/JuRDA==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-17.0.3.tgz", + "integrity": "sha512-Fhvk8G0vJblzsIY8ZF8IVwLq8S4qGBx+cqY4p5dgqIAtV3vChHgrdbd4/BhTSpGiJ6sYteH9nt5vgqNYZlxLPQ==", "dev": true, "engines": { "node": "^18.13.0 || >=20.9.0" } }, "node_modules/@angular/platform-browser": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.0.1.tgz", - "integrity": "sha512-JpvU0YDEM5KYdHtxC0Kdzk/hdwvZPq5vju5lTmIjTVa2OOabApOrQ6cq1MpKlrvjv1rw8MClHIM0l5Y0g9KH5g==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.0.3.tgz", + "integrity": "sha512-4SoW0yeAxgfcLIekKsvZVg/WgI5aQZyz9HGOoyBcVQ8coYoZmM9bAYQi+9zvyweqoWc+jgw72X1E8wtmMXt7Aw==", "dependencies": { "tslib": "^2.3.0" }, @@ -619,9 +1007,9 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/animations": "17.0.1", - "@angular/common": "17.0.1", - "@angular/core": "17.0.1" + "@angular/animations": "17.0.3", + "@angular/common": "17.0.3", + "@angular/core": "17.0.3" }, "peerDependenciesMeta": { "@angular/animations": { @@ -630,9 +1018,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.0.1.tgz", - "integrity": "sha512-xEcbB/ukXc65LaX4JBQYEM7D5Z8LcUIZniSJFneY7deZt3wNiKgmPZrPoXUyDV26QULh7N0IADEzvbcMF60AFQ==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.0.3.tgz", + "integrity": "sha512-Ab6ZeGG63z9Ilv8r4lHcmSirVaw8quRrPjDbT8cgIteHbj0SbwgDzxX0ve+fjjubFUluNSNtc6OYglWMHJ/g7Q==", "dependencies": { "tslib": "^2.3.0" }, @@ -640,16 +1028,35 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.0.1", - "@angular/compiler": "17.0.1", - "@angular/core": "17.0.1", - "@angular/platform-browser": "17.0.1" + "@angular/common": "17.0.3", + "@angular/compiler": "17.0.3", + "@angular/core": "17.0.3", + "@angular/platform-browser": "17.0.3" + } + }, + "node_modules/@angular/platform-server": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-17.0.3.tgz", + "integrity": "sha512-/7Y91mCehVbxt52Kfm2PBbeMn1+S/2+MXwJjUXUHzKQPQx+bDH2eVzS2nIPnnToeD0Y8AOYOnafPUvNb7oSzgg==", + "dependencies": { + "tslib": "^2.3.0", + "xhr2": "^0.2.0" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0" + }, + "peerDependencies": { + "@angular/animations": "17.0.3", + "@angular/common": "17.0.3", + "@angular/compiler": "17.0.3", + "@angular/core": "17.0.3", + "@angular/platform-browser": "17.0.3" } }, "node_modules/@angular/router": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-17.0.1.tgz", - "integrity": "sha512-73PCDDsRAjemODMRndZhwEN6Tb9rVVbDfMWgLQ4HgfgKnjek8P9BoYf8rOf3qV5fXf3c1Sm9MmKtaPv+l5lU9Q==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-17.0.3.tgz", + "integrity": "sha512-zw31XXMqLJ1CcHxDtEl2/FTJXeRbbnLM8oHtCPzbbxTkhAlnXxSYxjds0+1IMmpzz/v9qGBhYvUt8ZfZhqDBHQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -657,12 +1064,25 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.0.1", - "@angular/core": "17.0.1", - "@angular/platform-browser": "17.0.1", + "@angular/common": "17.0.3", + "@angular/core": "17.0.3", + "@angular/platform-browser": "17.0.3", "rxjs": "^6.5.3 || ^7.4.0" } }, + "node_modules/@angular/ssr": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-17.0.1.tgz", + "integrity": "sha512-DlUudZCYhwfiuYwsIWTFxXgDS1DUyUFfv1bas2QTEFh6zo/V54+OOF7LPspezMQHulG/SkPGO1tJC1Z5FtwiMg==", + "dependencies": { + "critters": "0.0.20", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^17.0.0", + "@angular/core": "^17.0.0" + } + }, "node_modules/@angularclass/hmr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@angularclass/hmr/-/hmr-3.0.0.tgz", @@ -3305,9 +3725,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.0.0.tgz", - "integrity": "sha512-/Bb5MXlphNp3UDsQDa4EB4AwpF4D/plrCPd5YGfVvD43j5g5Rpen+cqz5jai1zfAkF1dPl2qq0nRp/jwmJO3uA==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.0.1.tgz", + "integrity": "sha512-IfiWIBY1GntfJFV/U1CSOHZ7zF5p0zFMFzux7/iGXUXit299LTdJ5mZTe9++lFcH6dPHgEPWlinuYAfzorY4ng==", "dev": true, "engines": { "node": "^18.13.0 || >=20.9.0", @@ -3546,21 +3966,21 @@ } }, "node_modules/@nrwl/devkit": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-17.0.3.tgz", - "integrity": "sha512-k1o0tvmGcg2/Kw2d56ULixqngCj5zTfp3mn6yS0ytIJrTQnJVkI8GcFCtpnqbzQjD8nKHhvTIcOMsj2BzLos9A==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-17.1.2.tgz", + "integrity": "sha512-INPZk4qts3xNJt8E9fttuVTufXdigPUOvUiAiPJmR2oUGDF8SeOlIYNForbz+XMRvxyIVtf45O32azUsgeZe3Q==", "dev": true, "dependencies": { - "@nx/devkit": "17.0.3" + "@nx/devkit": "17.1.2" } }, "node_modules/@nrwl/tao": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-17.0.3.tgz", - "integrity": "sha512-X6zcwf6c3z7TuztRJWM/OCfzm7+LI4Uw4coc9+PWr44ohHkgId2wEJTzXrDT3+lvv8DgwPpgWPwqntw+YcgRYg==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-17.1.2.tgz", + "integrity": "sha512-tL+dlygeor/kLG5fuK5qaiVFJ4hEtvJ/E+xY9epp20UKCNQSEkrSFiesiXtX6E/PPf4YbOQ4B4itWR2EYCm03Q==", "dev": true, "dependencies": { - "nx": "17.0.3", + "nx": "17.1.2", "tslib": "^2.3.0" }, "bin": { @@ -3568,12 +3988,12 @@ } }, "node_modules/@nx/devkit": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-17.0.3.tgz", - "integrity": "sha512-gW9aVc2BJBQ6PME07lsiaHg2Tjm9FN/qFjzxeSQYe2cR/s4hXqCBUfgKEqjgzMq+ykDR2Japkd8Vg8BN0uWnpA==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-17.1.2.tgz", + "integrity": "sha512-9Izd9jsa++AaZSSlhi0zkv58k4clzE0kICurx9DjfWN6zXnD08HqJoUYCVVaeYS/SrWlQUbMig8e49BO8ZV5mw==", "dev": true, "dependencies": { - "@nrwl/devkit": "17.0.3", + "@nrwl/devkit": "17.1.2", "ejs": "^3.1.7", "enquirer": "~2.3.6", "ignore": "^5.0.4", @@ -3619,9 +4039,9 @@ "dev": true }, "node_modules/@nx/nx-darwin-arm64": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-17.0.3.tgz", - "integrity": "sha512-KA75JC/hgkt9qwK4dnN1tlaTXWdYItkNMjji6YjkyAYabbLKQKVcQoPocYP/RB/Gng+vNslXwuug2atgxDf43g==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-17.1.2.tgz", + "integrity": "sha512-U8fwkuw0vmDfeRQX9LSMt1XiAXM57fxOiuHlrIBn8hUBvMAugAgSAYd7K9YQjrFf9UFUtQeSHDU9N/c/n63hdg==", "cpu": [ "arm64" ], @@ -3635,9 +4055,9 @@ } }, "node_modules/@nx/nx-darwin-x64": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-17.0.3.tgz", - "integrity": "sha512-YVWk9jNibD7fzn8oNBl/UNu8NEfcVwFo5wiNyfOql495yP0tyGdZNHD4i/7aS2Y654G1JYDRf7TutJ7wWFU8bg==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-17.1.2.tgz", + "integrity": "sha512-QR9Jrm32UK2nLdDRtjFabfCvF5SOQJ2IuYkw6Sxe16xGZU2DS9nQku0TQO3Uy2HV1xSR7vzj7ys5z4eI2k+/mA==", "cpu": [ "x64" ], @@ -3651,9 +4071,9 @@ } }, "node_modules/@nx/nx-freebsd-x64": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-17.0.3.tgz", - "integrity": "sha512-yiYkfY+3IrlBrlaXN6SO4Fnb0a+Ti+FPwAqRPpH6q3uTCh0NmNgE99ydtT31ZbgCF1ZwRK8NdCbuNO3w9uznwA==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-17.1.2.tgz", + "integrity": "sha512-6rDuFHJREVg5XpcM5RlE8pHP4bgcbns8sSemF/g75SV4iEkBqxRvSe88oBtF44b7IpX2zdONRDV4qQcRf3DxRg==", "cpu": [ "x64" ], @@ -3667,9 +4087,9 @@ } }, "node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-17.0.3.tgz", - "integrity": "sha512-x4h6QJlESJZ0bigUlxNEVyi7F/VWQQx+1IBptofXhK5eTOPjJ5qgINdM38AZg+kBJDz5XOVMDejg6RzHlhs0Tg==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-17.1.2.tgz", + "integrity": "sha512-4FwqUX7NxVfJ0v7frBKNbjENz6pvp3slDfoG2/WmnAj5a6TCu7magwlg1qLQaHYJ1m/i8u7RrG0Uz4SYHWzkVw==", "cpu": [ "arm" ], @@ -3683,9 +4103,9 @@ } }, "node_modules/@nx/nx-linux-arm64-gnu": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-17.0.3.tgz", - "integrity": "sha512-1lysnsZv9FS+9fciK0qh5PhsQ8U+vyFoR/jiJl+3vqYNUwEmNLD0VEAZzpZL2SJXQqD5E0bjuQpYxiD7YRXImQ==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-17.1.2.tgz", + "integrity": "sha512-r6UATY0dVdxwpVJPf/f/KfRkFpMP06wC6HcfNMGbTBTKiKtsdYF42bWoSkDgtgP2bOx9FDH+Hwu3U/Rtj44FIA==", "cpu": [ "arm64" ], @@ -3699,9 +4119,9 @@ } }, "node_modules/@nx/nx-linux-arm64-musl": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-17.0.3.tgz", - "integrity": "sha512-0/bvSpbc4vOy9E24fu0ajDGe3SO8lmLtlxjXwGRcnzlt/MWM8sazoO0lX163/X2wF6tuL6+HXHOr6AeqsdeRXQ==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-17.1.2.tgz", + "integrity": "sha512-MXGYY/KCzQhbj5UKwnRO2/GhByOkRlI+EeH1Mazam8wZ1BiBfcVWZoOUybIlxxes1o4cAnkZwB527tCmwrHvGw==", "cpu": [ "arm64" ], @@ -3715,9 +4135,9 @@ } }, "node_modules/@nx/nx-linux-x64-gnu": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-17.0.3.tgz", - "integrity": "sha512-tKO6MYUxpUsHMuZrYy8hG20RIOdBY3kyEK8wxH8JZZaXKeYUK+5vv5DavWpY5wuu2jffNIJNsbUzcrqOlcbDOg==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-17.1.2.tgz", + "integrity": "sha512-3cC131hJ3VhuxjzzBlwIdVp46onykOo78EmnURNdLxcWOpmcKgYXn7OnVwjrglYi+JL7D0vABGKKUpt1cs6/rA==", "cpu": [ "x64" ], @@ -3731,9 +4151,9 @@ } }, "node_modules/@nx/nx-linux-x64-musl": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-17.0.3.tgz", - "integrity": "sha512-H88yBLrI51m6NGoCkpBYhacRyTBfDuf7x00SnxSfD1yLlxCazPUG7CGkMedpzXo10YHxCFvg7B/Fa23DRRleUg==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-17.1.2.tgz", + "integrity": "sha512-1UrR87ByhE0zSXt0C+RNT5ZiAsctOSWZwPYQAGolz8K70BxomDeRVtIaRog5KK5SHlEd1ILvgsmrhovjLjrJNw==", "cpu": [ "x64" ], @@ -3747,9 +4167,9 @@ } }, "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-17.0.3.tgz", - "integrity": "sha512-bKzmzjvgLB4IzLWTySqXgBgXawfw0ZSjUkscFQ3ZHrK9loMba1Ue8Ugy2DktlkUrCyPmGSot+YZViTzWP75C3w==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-17.1.2.tgz", + "integrity": "sha512-2M7FfzfPGAN7tCUWZilPGNk/RbbGcA00MKOA4MDqMwJtLobW8KqfMedilRNTEuyNibejOHwvGzA9T/Ac/ahHgA==", "cpu": [ "arm64" ], @@ -3763,9 +4183,9 @@ } }, "node_modules/@nx/nx-win32-x64-msvc": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-17.0.3.tgz", - "integrity": "sha512-SJssAOyUM1IW9t84/Uzau9JHo14hnG5mxvcrborNGlLq+WnP0jzISVs7gvV2xWZ9j1JemxA5KLbkMuIkJyR6qQ==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-17.1.2.tgz", + "integrity": "sha512-oxKCKunuo4wRusMlNu7PlhBijhtNy7eBZPAWyqUsdfnb+CjY2QncjCguW3fnsG9gHQFCa+y0b1WkSkvJ5G1DiQ==", "cpu": [ "x64" ], @@ -4045,13 +4465,13 @@ ] }, "node_modules/@schematics/angular": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.0.0.tgz", - "integrity": "sha512-9jKU5x/WzaBsfSkUowK1X74FqtMXa6+A60XgW4ACO8i6fwKfPeS+tIrAieeYOX80/njBh7I5CvcpHmWA2SbcXQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.0.1.tgz", + "integrity": "sha512-BacI1fQsEXNYkfJzDJn3CsUSc9A4M7nhXtvt3XjceUhOqUp2AR4uIeUwDOrpLnkRwv5+rZLafUnRN3k01WUJOw==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.0.0", - "@angular-devkit/schematics": "17.0.0", + "@angular-devkit/core": "17.0.1", + "@angular-devkit/schematics": "17.0.1", "jsonc-parser": "3.2.0" }, "engines": { @@ -4961,7 +5381,6 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -5969,8 +6388,7 @@ "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/boxen": { "version": "4.2.0", @@ -6452,7 +6870,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -6570,7 +6987,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", @@ -7392,7 +7808,6 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, "dependencies": { "safe-buffer": "5.2.1" }, @@ -7404,7 +7819,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -7427,8 +7841,7 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/copy-anything": { "version": "2.0.6", @@ -7591,7 +8004,6 @@ "version": "0.0.20", "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz", "integrity": "sha512-CImNRorKOl5d8TWcnAz5n5izQ6HFsvz29k327/ELy6UFcmbiZNOsinaKvzv16WZR0P6etfSWYzE47C4/56B3Uw==", - "dev": true, "dependencies": { "chalk": "^4.1.0", "css-select": "^5.1.0", @@ -7606,7 +8018,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -7621,7 +8032,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7637,7 +8047,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -7648,14 +8057,12 @@ "node_modules/critters/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/critters/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -7664,7 +8071,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -7754,7 +8160,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -7783,7 +8188,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, "engines": { "node": ">= 6" }, @@ -8036,7 +8440,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", @@ -8185,7 +8588,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -8212,7 +8614,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -8342,7 +8743,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -8356,7 +8756,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, "funding": [ { "type": "github", @@ -8368,7 +8767,6 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -8383,7 +8781,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dev": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -8584,8 +8981,7 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { "version": "3.1.9", @@ -8627,7 +9023,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -8751,7 +9146,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "engines": { "node": ">=0.12" }, @@ -8933,8 +9327,7 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "1.0.5", @@ -9440,7 +9833,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -9608,7 +10000,6 @@ "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -9649,14 +10040,12 @@ "node_modules/express/node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/express/node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -9680,7 +10069,6 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -9689,7 +10077,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -9698,7 +10085,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -9716,7 +10102,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, "bin": { "mime": "cli.js" }, @@ -9727,14 +10112,12 @@ "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express/node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, "dependencies": { "ee-first": "1.1.1" }, @@ -9746,7 +10129,6 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -9761,7 +10143,6 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -9784,14 +10165,12 @@ "node_modules/express/node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/express/node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -9806,7 +10185,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -10527,7 +10905,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -10561,7 +10938,6 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -10640,7 +11016,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10667,7 +11042,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dev": true, "dependencies": { "function-bind": "^1.1.2", "has-proto": "^1.0.1", @@ -11320,7 +11694,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -11892,7 +12265,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.2" }, @@ -11904,7 +12276,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -11916,7 +12287,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -12000,7 +12370,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -12175,7 +12544,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -12206,7 +12574,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -12222,7 +12589,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -12310,7 +12676,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -12530,8 +12895,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "4.1.1", @@ -15219,7 +15583,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -15343,8 +15706,7 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/merge-stream": { "version": "2.0.0", @@ -15365,7 +15727,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -15411,7 +15772,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -15420,7 +15780,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -15842,7 +16201,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -15956,7 +16314,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -16432,7 +16789,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, "dependencies": { "boolbase": "^1.0.0" }, @@ -16484,13 +16840,13 @@ } }, "node_modules/nx": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/nx/-/nx-17.0.3.tgz", - "integrity": "sha512-VShJISKCYt3iVJoMUPZiv67+0tiItxWMnfVmTmPZPio2Fu+wGc9U4ijjPxcmp2RJmLRaxkB9cn5rlrAvkIrNMA==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/nx/-/nx-17.1.2.tgz", + "integrity": "sha512-pf94ri36cAiSzbYcPTJwQzttgAsHSjCLEni0Ilw6aVdjpoV2l6cggYxwddX7pgtCWuokVp/6KhAxVkbzvH65wg==", "dev": true, "hasInstallScript": true, "dependencies": { - "@nrwl/tao": "17.0.3", + "@nrwl/tao": "17.1.2", "@yarnpkg/lockfile": "^1.1.0", "@yarnpkg/parsers": "3.0.0-rc.46", "@zkochan/js-yaml": "0.0.6", @@ -16531,16 +16887,16 @@ "nx-cloud": "bin/nx-cloud.js" }, "optionalDependencies": { - "@nx/nx-darwin-arm64": "17.0.3", - "@nx/nx-darwin-x64": "17.0.3", - "@nx/nx-freebsd-x64": "17.0.3", - "@nx/nx-linux-arm-gnueabihf": "17.0.3", - "@nx/nx-linux-arm64-gnu": "17.0.3", - "@nx/nx-linux-arm64-musl": "17.0.3", - "@nx/nx-linux-x64-gnu": "17.0.3", - "@nx/nx-linux-x64-musl": "17.0.3", - "@nx/nx-win32-arm64-msvc": "17.0.3", - "@nx/nx-win32-x64-msvc": "17.0.3" + "@nx/nx-darwin-arm64": "17.1.2", + "@nx/nx-darwin-x64": "17.1.2", + "@nx/nx-freebsd-x64": "17.1.2", + "@nx/nx-linux-arm-gnueabihf": "17.1.2", + "@nx/nx-linux-arm64-gnu": "17.1.2", + "@nx/nx-linux-arm64-musl": "17.1.2", + "@nx/nx-linux-x64-gnu": "17.1.2", + "@nx/nx-linux-x64-musl": "17.1.2", + "@nx/nx-win32-arm64-msvc": "17.1.2", + "@nx/nx-win32-x64-msvc": "17.1.2" }, "peerDependencies": { "@swc-node/register": "^1.6.7", @@ -16577,9 +16933,9 @@ "dev": true }, "node_modules/nx/node_modules/axios": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", - "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "dev": true, "dependencies": { "follow-redirects": "^1.15.0", @@ -16795,7 +17151,6 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -17441,7 +17796,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -17543,8 +17897,7 @@ "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/path-type": { "version": "4.0.0", @@ -17564,8 +17917,7 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "3.0.1", @@ -17784,7 +18136,6 @@ "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -18050,7 +18401,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, "engines": { "node": ">=6" }, @@ -18140,7 +18490,6 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -18153,7 +18502,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, "engines": { "node": ">= 0.10" } @@ -18327,7 +18675,6 @@ "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -18389,7 +18736,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -19295,7 +19641,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -19366,8 +19711,7 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { "version": "1.69.5", @@ -20472,7 +20816,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dev": true, "dependencies": { "define-data-property": "^1.1.1", "get-intrinsic": "^1.2.1", @@ -20534,8 +20877,7 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/shallow-clone": { "version": "3.0.1", @@ -20604,7 +20946,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -22255,7 +22596,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, "engines": { "node": ">=0.6" } @@ -22409,7 +22749,6 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -22772,7 +23111,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -23027,7 +23365,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, "engines": { "node": ">= 0.4.0" } @@ -23109,7 +23446,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -24346,6 +24682,14 @@ "node": ">=8" } }, + "node_modules/xhr2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz", + "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/xmlbuilder": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-12.0.0.tgz", diff --git a/package.json b/package.json index c76533a172f..4f3630f2ad5 100644 --- a/package.json +++ b/package.json @@ -49,21 +49,25 @@ "test:i18n:dist": "eslint -c projects/igniteui-angular-i18n/.eslintrc.dist.i18n.json dist/igniteui-angular-i18n/**/*.d.ts --no-eslintrc", "postinstall": "gulp copyGitHooks", "cypress:open": "cypress open --config-file=cypress.config.ts", - "cypress:run": "cypress run --config-file=cypress.config.ts" + "cypress:run": "cypress run --config-file=cypress.config.ts", + "serve:ssr:ssr-test": "node dist/ssr-test/server/server.mjs" }, "private": true, "dependencies": { - "@angular/animations": "^17.0.1", - "@angular/common": "^17.0.1", - "@angular/compiler": "^17.0.1", - "@angular/core": "^17.0.1", - "@angular/forms": "^17.0.1", - "@angular/platform-browser": "^17.0.1", - "@angular/platform-browser-dynamic": "^17.0.1", - "@angular/router": "^17.0.1", + "@angular/animations": "^17.0.3", + "@angular/common": "^17.0.3", + "@angular/compiler": "^17.0.3", + "@angular/core": "^17.0.3", + "@angular/forms": "^17.0.3", + "@angular/platform-browser": "^17.0.3", + "@angular/platform-browser-dynamic": "^17.0.3", + "@angular/platform-server": "^17.0.3", + "@angular/router": "^17.0.3", + "@angular/ssr": "^17.0.1", "@igniteui/material-icons-extended": "^3.0.0", "@types/hammerjs": "^2.0.40", "@types/source-map": "0.5.2", + "express": "^4.18.2", "fflate": "^0.7.3", "hammerjs": "^2.0.8", "igniteui-theming": "^3.3.0", @@ -75,18 +79,19 @@ "zone.js": "~0.14.2" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.0.0", - "@angular-devkit/schematics": "^17.0.0", - "@angular-eslint/builder": "^17.0.0", - "@angular-eslint/eslint-plugin": "^17.0.0", - "@angular-eslint/eslint-plugin-template": "^17.0.0", - "@angular-eslint/schematics": "^17.0.0", - "@angular-eslint/template-parser": "^17.0.0", - "@angular/cli": "^17.0.0", - "@angular/compiler-cli": "^17.0.1", - "@angular/language-service": "^17.0.1", + "@angular-devkit/build-angular": "^17.0.1", + "@angular-devkit/schematics": "^17.0.1", + "@angular-eslint/builder": "^17.1.0", + "@angular-eslint/eslint-plugin": "^17.1.0", + "@angular-eslint/eslint-plugin-template": "^17.1.0", + "@angular-eslint/schematics": "^17.1.0", + "@angular-eslint/template-parser": "^17.1.0", + "@angular/cli": "^17.0.1", + "@angular/compiler-cli": "^17.0.3", + "@angular/language-service": "^17.0.3", "@angularclass/hmr": "^3.0.0", "@types/estree": "^1.0.0", + "@types/express": "^4.17.17", "@types/jasmine": "^5.1.1", "@types/jasminewd2": "^2.0.10", "@types/node": "^20.8.9", @@ -133,4 +138,4 @@ "typedoc-plugin-localization": "^3.0.3", "typescript": "5.2.2" } -} +} \ No newline at end of file diff --git a/projects/ssr-test/server.ts b/projects/ssr-test/server.ts new file mode 100644 index 00000000000..7083b14fe9d --- /dev/null +++ b/projects/ssr-test/server.ts @@ -0,0 +1,56 @@ +import { APP_BASE_HREF } from '@angular/common'; +import { CommonEngine } from '@angular/ssr'; +import express from 'express'; +import { fileURLToPath } from 'node:url'; +import { dirname, join, resolve } from 'node:path'; +import bootstrap from './src/main.server'; + +// The Express app is exported so that it can be used by serverless Functions. +export function app(): express.Express { + const server = express(); + const serverDistFolder = dirname(fileURLToPath(import.meta.url)); + const browserDistFolder = resolve(serverDistFolder, '../browser'); + const indexHtml = join(serverDistFolder, 'index.server.html'); + + const commonEngine = new CommonEngine(); + + server.set('view engine', 'html'); + server.set('views', browserDistFolder); + + // Example Express Rest API endpoints + // server.get('/api/**', (req, res) => { }); + // Serve static files from /browser + server.get('*.*', express.static(browserDistFolder, { + maxAge: '1y' + })); + + // All regular routes use the Angular engine + server.get('*', (req, res, next) => { + const { protocol, originalUrl, baseUrl, headers } = req; + + commonEngine + .render({ + bootstrap, + documentFilePath: indexHtml, + url: `${protocol}://${headers.host}${originalUrl}`, + publicPath: browserDistFolder, + providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }], + }) + .then((html) => res.send(html)) + .catch((err) => next(err)); + }); + + return server; +} + +function run(): void { + const port = process.env['PORT'] || 4000; + + // Start up the Node server + const server = app(); + server.listen(port, () => { + console.log(`Node Express server listening on http://localhost:${port}`); + }); +} + +run(); diff --git a/projects/ssr-test/src/app/app.component.html b/projects/ssr-test/src/app/app.component.html new file mode 100644 index 00000000000..89b757a491d --- /dev/null +++ b/projects/ssr-test/src/app/app.component.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/projects/ssr-test/src/app/app.component.scss b/projects/ssr-test/src/app/app.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/projects/ssr-test/src/app/app.component.spec.ts b/projects/ssr-test/src/app/app.component.spec.ts new file mode 100644 index 00000000000..71cbadabe23 --- /dev/null +++ b/projects/ssr-test/src/app/app.component.spec.ts @@ -0,0 +1,29 @@ +import { TestBed } from '@angular/core/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AppComponent], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have the 'ssr-test' title`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('ssr-test'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h1')?.textContent).toContain('Hello, ssr-test'); + }); +}); diff --git a/projects/ssr-test/src/app/app.component.ts b/projects/ssr-test/src/app/app.component.ts new file mode 100644 index 00000000000..65b44458af4 --- /dev/null +++ b/projects/ssr-test/src/app/app.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; +import { IGX_LIST_DIRECTIVES, IgxNavbarComponent } from 'igniteui-angular'; + +@Component({ + selector: 'app-root', + standalone: true, + imports: [RouterOutlet, IgxNavbarComponent, IGX_LIST_DIRECTIVES], + templateUrl: './app.component.html', + styleUrl: './app.component.scss' +}) +export class AppComponent { + title = 'ssr-test'; +} diff --git a/projects/ssr-test/src/app/app.config.server.ts b/projects/ssr-test/src/app/app.config.server.ts new file mode 100644 index 00000000000..b4d57c94235 --- /dev/null +++ b/projects/ssr-test/src/app/app.config.server.ts @@ -0,0 +1,11 @@ +import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; +import { provideServerRendering } from '@angular/platform-server'; +import { appConfig } from './app.config'; + +const serverConfig: ApplicationConfig = { + providers: [ + provideServerRendering() + ] +}; + +export const config = mergeApplicationConfig(appConfig, serverConfig); diff --git a/projects/ssr-test/src/app/app.config.ts b/projects/ssr-test/src/app/app.config.ts new file mode 100644 index 00000000000..e5a3cf10050 --- /dev/null +++ b/projects/ssr-test/src/app/app.config.ts @@ -0,0 +1,9 @@ +import { ApplicationConfig } from '@angular/core'; +import { provideRouter } from '@angular/router'; + +import { routes } from './app.routes'; +import { provideClientHydration } from '@angular/platform-browser'; + +export const appConfig: ApplicationConfig = { + providers: [provideRouter(routes), provideClientHydration()] +}; diff --git a/projects/ssr-test/src/app/app.routes.ts b/projects/ssr-test/src/app/app.routes.ts new file mode 100644 index 00000000000..dc39edb5f23 --- /dev/null +++ b/projects/ssr-test/src/app/app.routes.ts @@ -0,0 +1,3 @@ +import { Routes } from '@angular/router'; + +export const routes: Routes = []; diff --git a/projects/ssr-test/src/assets/.gitkeep b/projects/ssr-test/src/assets/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/projects/ssr-test/src/favicon.ico b/projects/ssr-test/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 zcmd^G33O9Omi+`8$@{|M-I6TH3wzF-p5CV8o}7f~KxR60LK+ApEFB<$bcciv%@SmA zV{n>g85YMFFeU*Uvl=i4v)C*qgnb;$GQ=3XTe9{Y%c`mO%su)noNCCQ*@t1WXn|B(hQ7i~ zrUK8|pUkD6#lNo!bt$6)jR!&C?`P5G(`e((P($RaLeq+o0Vd~f11;qB05kdbAOm?r zXv~GYr_sibQO9NGTCdT;+G(!{4Xs@4fPak8#L8PjgJwcs-Mm#nR_Z0s&u?nDX5^~@ z+A6?}g0|=4e_LoE69pPFO`yCD@BCjgKpzMH0O4Xs{Ahc?K3HC5;l=f zg>}alhBXX&);z$E-wai+9TTRtBX-bWYY@cl$@YN#gMd~tM_5lj6W%8ah4;uZ;jP@Q zVbuel1rPA?2@x9Y+u?e`l{Z4ngfG5q5BLH5QsEu4GVpt{KIp1?U)=3+KQ;%7ec8l* zdV=zZgN5>O3G(3L2fqj3;oBbZZw$Ij@`Juz@?+yy#OPw)>#wsTewVgTK9BGt5AbZ&?K&B3GVF&yu?@(Xj3fR3n+ZP0%+wo)D9_xp>Z$`A4 zfV>}NWjO#3lqumR0`gvnffd9Ka}JJMuHS&|55-*mCD#8e^anA<+sFZVaJe7{=p*oX zE_Uv?1>e~ga=seYzh{9P+n5<+7&9}&(kwqSaz;1aD|YM3HBiy<))4~QJSIryyqp| z8nGc(8>3(_nEI4n)n7j(&d4idW1tVLjZ7QbNLXg;LB ziHsS5pXHEjGJZb59KcvS~wv;uZR-+4qEqow`;JCfB*+b^UL^3!?;-^F%yt=VjU|v z39SSqKcRu_NVvz!zJzL0CceJaS6%!(eMshPv_0U5G`~!a#I$qI5Ic(>IONej@aH=f z)($TAT#1I{iCS4f{D2+ApS=$3E7}5=+y(rA9mM#;Cky%b*Gi0KfFA`ofKTzu`AV-9 znW|y@19rrZ*!N2AvDi<_ZeR3O2R{#dh1#3-d%$k${Rx42h+i&GZo5!C^dSL34*AKp z27mTd>k>?V&X;Nl%GZ(>0s`1UN~Hfyj>KPjtnc|)xM@{H_B9rNr~LuH`Gr5_am&Ep zTjZA8hljNj5H1Ipm-uD9rC}U{-vR!eay5&6x6FkfupdpT*84MVwGpdd(}ib)zZ3Ky z7C$pnjc82(W_y_F{PhYj?o!@3__UUvpX)v69aBSzYj3 zdi}YQkKs^SyXyFG2LTRz9{(w}y~!`{EuAaUr6G1M{*%c+kP1olW9z23dSH!G4_HSK zzae-DF$OGR{ofP*!$a(r^5Go>I3SObVI6FLY)N@o<*gl0&kLo-OT{Tl*7nCz>Iq=? zcigIDHtj|H;6sR?or8Wd_a4996GI*CXGU}o;D9`^FM!AT1pBY~?|4h^61BY#_yIfO zKO?E0 zJ{Pc`9rVEI&$xxXu`<5E)&+m(7zX^v0rqofLs&bnQT(1baQkAr^kEsk)15vlzAZ-l z@OO9RF<+IiJ*O@HE256gCt!bF=NM*vh|WVWmjVawcNoksRTMvR03H{p@cjwKh(CL4 z7_PB(dM=kO)!s4fW!1p0f93YN@?ZSG` z$B!JaAJCtW$B97}HNO9(x-t30&E}Mo1UPi@Av%uHj~?T|!4JLwV;KCx8xO#b9IlUW zI6+{a@Wj|<2Y=U;a@vXbxqZNngH8^}LleE_4*0&O7#3iGxfJ%Id>+sb;7{L=aIic8 z|EW|{{S)J-wr@;3PmlxRXU8!e2gm_%s|ReH!reFcY8%$Hl4M5>;6^UDUUae?kOy#h zk~6Ee_@ZAn48Bab__^bNmQ~+k=02jz)e0d9Z3>G?RGG!65?d1>9}7iG17?P*=GUV-#SbLRw)Hu{zx*azHxWkGNTWl@HeWjA?39Ia|sCi{e;!^`1Oec zb>Z|b65OM*;eC=ZLSy?_fg$&^2xI>qSLA2G*$nA3GEnp3$N-)46`|36m*sc#4%C|h zBN<2U;7k>&G_wL4=Ve5z`ubVD&*Hxi)r@{4RCDw7U_D`lbC(9&pG5C*z#W>8>HU)h z!h3g?2UL&sS!oY5$3?VlA0Me9W5e~V;2jds*fz^updz#AJ%G8w2V}AEE?E^=MK%Xt z__Bx1cr7+DQmuHmzn*|hh%~eEc9@m05@clWfpEFcr+06%0&dZJH&@8^&@*$qR@}o3 z@Tuuh2FsLz^zH+dN&T&?0G3I?MpmYJ;GP$J!EzjeM#YLJ!W$}MVNb0^HfOA>5Fe~UNn%Zk(PT@~9}1dt)1UQ zU*B5K?Dl#G74qmg|2>^>0WtLX#Jz{lO4NT`NYB*(L#D|5IpXr9v&7a@YsGp3vLR7L zHYGHZg7{ie6n~2p$6Yz>=^cEg7tEgk-1YRl%-s7^cbqFb(U7&Dp78+&ut5!Tn(hER z|Gp4Ed@CnOPeAe|N>U(dB;SZ?NU^AzoD^UAH_vamp6Ws}{|mSq`^+VP1g~2B{%N-!mWz<`)G)>V-<`9`L4?3dM%Qh6<@kba+m`JS{Ya@9Fq*m6$$ zA1%Ogc~VRH33|S9l%CNb4zM%k^EIpqY}@h{w(aBcJ9c05oiZx#SK9t->5lSI`=&l~ z+-Ic)a{FbBhXV$Xt!WRd`R#Jk-$+_Z52rS>?Vpt2IK<84|E-SBEoIw>cs=a{BlQ7O z-?{Fy_M&84&9|KM5wt~)*!~i~E=(6m8(uCO)I=)M?)&sRbzH$9Rovzd?ZEY}GqX+~ zFbEbLz`BZ49=2Yh-|<`waK-_4!7`ro@zlC|r&I4fc4oyb+m=|c8)8%tZ-z5FwhzDt zL5kB@u53`d@%nHl0Sp)Dw`(QU&>vujEn?GPEXUW!Wi<+4e%BORl&BIH+SwRcbS}X@ z01Pk|vA%OdJKAs17zSXtO55k!;%m9>1eW9LnyAX4uj7@${O6cfii`49qTNItzny5J zH&Gj`e}o}?xjQ}r?LrI%FjUd@xflT3|7LA|ka%Q3i}a8gVm<`HIWoJGH=$EGClX^C0lysQJ>UO(q&;`T#8txuoQ_{l^kEV9CAdXuU1Ghg8 zN_6hHFuy&1x24q5-(Z7;!poYdt*`UTdrQOIQ!2O7_+AHV2hgXaEz7)>$LEdG z<8vE^Tw$|YwZHZDPM!SNOAWG$?J)MdmEk{U!!$M#fp7*Wo}jJ$Q(=8>R`Ats?e|VU?Zt7Cdh%AdnfyN3MBWw{ z$OnREvPf7%z6`#2##_7id|H%Y{vV^vWXb?5d5?a_y&t3@p9t$ncHj-NBdo&X{wrfJ zamN)VMYROYh_SvjJ=Xd!Ga?PY_$;*L=SxFte!4O6%0HEh%iZ4=gvns7IWIyJHa|hT z2;1+e)`TvbNb3-0z&DD_)Jomsg-7p_Uh`wjGnU1urmv1_oVqRg#=C?e?!7DgtqojU zWoAB($&53;TsXu^@2;8M`#z{=rPy?JqgYM0CDf4v@z=ZD|ItJ&8%_7A#K?S{wjxgd z?xA6JdJojrWpB7fr2p_MSsU4(R7=XGS0+Eg#xR=j>`H@R9{XjwBmqAiOxOL` zt?XK-iTEOWV}f>Pz3H-s*>W z4~8C&Xq25UQ^xH6H9kY_RM1$ch+%YLF72AA7^b{~VNTG}Tj#qZltz5Q=qxR`&oIlW Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/projects/ssr-test/src/index.html b/projects/ssr-test/src/index.html new file mode 100644 index 00000000000..51c80953643 --- /dev/null +++ b/projects/ssr-test/src/index.html @@ -0,0 +1,13 @@ + + + + + SsrTest + + + + + + + + diff --git a/projects/ssr-test/src/main.server.ts b/projects/ssr-test/src/main.server.ts new file mode 100644 index 00000000000..4b9d4d1545c --- /dev/null +++ b/projects/ssr-test/src/main.server.ts @@ -0,0 +1,7 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { config } from './app/app.config.server'; + +const bootstrap = () => bootstrapApplication(AppComponent, config); + +export default bootstrap; diff --git a/projects/ssr-test/src/main.ts b/projects/ssr-test/src/main.ts new file mode 100644 index 00000000000..35b00f34633 --- /dev/null +++ b/projects/ssr-test/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, appConfig) + .catch((err) => console.error(err)); diff --git a/projects/ssr-test/src/styles.scss b/projects/ssr-test/src/styles.scss new file mode 100644 index 00000000000..a3f2bcdd548 --- /dev/null +++ b/projects/ssr-test/src/styles.scss @@ -0,0 +1,27 @@ +/* You can add global styles to this file, and also import other style files */ +@use '../../igniteui-angular/src/lib/core/styles/themes' as *; + +$primary: #fff; +$secondary: #FF0A3A; +$gray: #ddd; +$background: #fff; + +$app-palette: palette( + $primary: $primary, + $secondary: $secondary, + $surface: $background, + $gray: $gray +); + +@include core(); +@include typography(); + +$include: ( + igx-list, + igx-navbar +); + +@include light-theme( + $palette: $app-palette, + $exclude: map-keys(map-remove($components, $include...),) +);/* You can add global styles to this file, and also import other style files */ diff --git a/projects/ssr-test/tsconfig.app.json b/projects/ssr-test/tsconfig.app.json new file mode 100644 index 00000000000..5e370729994 --- /dev/null +++ b/projects/ssr-test/tsconfig.app.json @@ -0,0 +1,30 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/app", + "types": [ + "node" + ], + "paths": { + "igniteui-angular": [ + "dist/igniteui-angular" + ], + "igniteui-angular/*": [ + "dist/igniteui-angular/*" + ], + "igniteui-angular-i18n": [ + "dist/igniteui-angular-i18n" + ] + }, + "allowSyntheticDefaultImports": true + }, + "files": [ + "src/main.ts", + "src/main.server.ts", + "server.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/projects/ssr-test/tsconfig.spec.json b/projects/ssr-test/tsconfig.spec.json new file mode 100644 index 00000000000..a9c0752ffe5 --- /dev/null +++ b/projects/ssr-test/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} From c425ae664465e4ebbdc4d872d68d3ad6da4a3ed1 Mon Sep 17 00:00:00 2001 From: Svetoslav Krastev Date: Mon, 20 Nov 2023 17:58:48 +0200 Subject: [PATCH 12/25] fix(grid): Add missing interface for clipboardOptions. (#13682) --- .../src/lib/grids/common/grid.interface.ts | 22 +++++++++++++++++++ .../src/lib/grids/grid-base.directive.ts | 5 +++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts b/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts index 6af745ae71e..059a55b9c84 100644 --- a/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts +++ b/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts @@ -1387,3 +1387,25 @@ export interface IPinningConfig { columns?: ColumnPinningPosition; rows?: RowPinningPosition; } + +/** + * An interface describing settings for clipboard options + */ +export interface IClipboardOptions { + /** + * Enables/disables the copy behavior + */ + enabled: boolean; + /** + * Include the columns headers in the clipboard output. + */ + copyHeaders: boolean; + /** + * Apply the columns formatters (if any) on the data in the clipboard output. + */ + copyFormatters: boolean; + /** + * The separator used for formatting the copy output. Defaults to `\t`. + */ + separator: string; +} diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 8959729728b..253aedd5ac2 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -140,7 +140,8 @@ import { IGX_GRID_SERVICE_BASE, ISizeInfo, RowType, - IPinningConfig + IPinningConfig, + IClipboardOptions } from './common/grid.interface'; import { DropPosition } from './moving/moving.service'; import { IgxHeadSelectorDirective, IgxRowSelectorDirective } from './selection/row-selectors'; @@ -323,7 +324,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements * Controls the copy behavior of the grid. */ @Input() - public clipboardOptions = { + public clipboardOptions: IClipboardOptions = { /** * Enables/disables the copy behavior */ From 6a0528b7ae6cb27250179f6d1c2b04adafa76f6f Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Tue, 21 Nov 2023 10:26:25 +0200 Subject: [PATCH 13/25] spec(density): update some component specs --- .../src/lib/combo/combo.component.spec.ts | 1415 +++++++++-------- .../igniteui-angular/src/lib/core/density.ts | 27 +- .../date-range-picker.component.spec.ts | 252 +-- 3 files changed, 865 insertions(+), 829 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 757adbfac66..a1de875770c 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -90,750 +90,797 @@ describe('igxCombo', () => { mockSelection.get.and.returnValue(new Set([])); const mockIconService = new IgxIconService(null, null, null, null); it('should correctly implement interface methods - ControlValueAccessor ', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - expect(mockInjector.get).toHaveBeenCalledWith(NgControl, null); - combo.registerOnChange(mockNgControl.registerOnChangeCb); - combo.registerOnTouched(mockNgControl.registerOnTouchedCb); - - // writeValue - expect(combo.displayValue).toEqual(''); - mockSelection.get.and.returnValue(new Set(['test'])); - spyOnProperty(combo, 'isRemote').and.returnValue(false); - combo.writeValue(['test']); - expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled(); - expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['test'], true); - expect(combo.displayValue).toEqual('test'); - expect(combo.value).toEqual(['test']); - - // setDisabledState - combo.setDisabledState(true); - expect(combo.disabled).toBe(true); - combo.setDisabledState(false); - expect(combo.disabled).toBe(false); - - // OnChange callback - mockSelection.add_items.and.returnValue(new Set(['simpleValue'])); - combo.select(['simpleValue']); - expect(mockSelection.add_items).toHaveBeenCalledWith(combo.id, ['simpleValue'], undefined); - expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['simpleValue'], true); - expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith(['simpleValue']); - - // OnTouched callback - spyOnProperty(combo, 'collapsed').and.returnValue(true); - spyOnProperty(combo, 'valid', 'set'); - - combo.onBlur(); - expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + expect(mockInjector.get).toHaveBeenCalledWith(NgControl, null); + combo.registerOnChange(mockNgControl.registerOnChangeCb); + combo.registerOnTouched(mockNgControl.registerOnTouchedCb); + + // writeValue + expect(combo.displayValue).toEqual(''); + mockSelection.get.and.returnValue(new Set(['test'])); + spyOnProperty(combo, 'isRemote').and.returnValue(false); + combo.writeValue(['test']); + expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled(); + expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['test'], true); + expect(combo.displayValue).toEqual('test'); + expect(combo.value).toEqual(['test']); + + // setDisabledState + combo.setDisabledState(true); + expect(combo.disabled).toBe(true); + combo.setDisabledState(false); + expect(combo.disabled).toBe(false); + + // OnChange callback + mockSelection.add_items.and.returnValue(new Set(['simpleValue'])); + combo.select(['simpleValue']); + expect(mockSelection.add_items).toHaveBeenCalledWith(combo.id, ['simpleValue'], undefined); + expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['simpleValue'], true); + expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith(['simpleValue']); + + // OnTouched callback + spyOnProperty(combo, 'collapsed').and.returnValue(true); + spyOnProperty(combo, 'valid', 'set'); + + combo.onBlur(); + expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1); + }); }); it('should properly call dropdown methods on toggle', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.dropdown = dropdown; - dropdown.collapsed = true; - - combo.open(); - dropdown.collapsed = false; - expect(combo.dropdown.open).toHaveBeenCalledTimes(1); - expect(combo.collapsed).toBe(false); - - combo.close(); - dropdown.collapsed = true; - expect(combo.dropdown.close).toHaveBeenCalledTimes(1); - expect(combo.collapsed).toBe(true); - - combo.toggle(); - dropdown.collapsed = false; - expect(combo.dropdown.toggle).toHaveBeenCalledTimes(1); - expect(combo.collapsed).toBe(false); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.dropdown = dropdown; + dropdown.collapsed = true; + + combo.open(); + dropdown.collapsed = false; + expect(combo.dropdown.open).toHaveBeenCalledTimes(1); + expect(combo.collapsed).toBe(false); + + combo.close(); + dropdown.collapsed = true; + expect(combo.dropdown.close).toHaveBeenCalledTimes(1); + expect(combo.collapsed).toBe(true); + + combo.toggle(); + dropdown.collapsed = false; + expect(combo.dropdown.toggle).toHaveBeenCalledTimes(1); + expect(combo.collapsed).toBe(false); + }); }); it(`should not focus search input when property autoFocusSearch=false`, () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdownContainer = { nativeElement: { focus: () => { } } }; - combo['dropdownContainer'] = dropdownContainer; - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - spyOn(combo, 'focusSearchInput'); - - combo.autoFocusSearch = false; - combo.handleOpened(); - expect(combo.focusSearchInput).toHaveBeenCalledTimes(0); - - combo.autoFocusSearch = true; - combo.handleOpened(); - expect(combo.focusSearchInput).toHaveBeenCalledTimes(1); - - combo.autoFocusSearch = false; - combo.handleOpened(); - expect(combo.focusSearchInput).toHaveBeenCalledTimes(1); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdownContainer = { nativeElement: { focus: () => { } } }; + combo['dropdownContainer'] = dropdownContainer; + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + spyOn(combo, 'focusSearchInput'); + + combo.autoFocusSearch = false; + combo.handleOpened(); + expect(combo.focusSearchInput).toHaveBeenCalledTimes(0); + + combo.autoFocusSearch = true; + combo.handleOpened(); + expect(combo.focusSearchInput).toHaveBeenCalledTimes(1); + + combo.autoFocusSearch = false; + combo.handleOpened(); + expect(combo.focusSearchInput).toHaveBeenCalledTimes(1); + }); }); it('should call dropdown toggle with correct overlaySettings', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['toggle']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.dropdown = dropdown; - const defaultSettings = (combo as any)._overlaySettings; - combo.toggle(); - expect(combo.dropdown.toggle).toHaveBeenCalledWith(defaultSettings || {}); - const newSettings = { - positionStrategy: new ConnectedPositioningStrategy(), - scrollStrategy: new AbsoluteScrollStrategy() - }; - combo.overlaySettings = newSettings; - const expectedSettings = Object.assign({}, defaultSettings, newSettings); - combo.toggle(); - expect(combo.dropdown.toggle).toHaveBeenCalledWith(expectedSettings); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['toggle']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.dropdown = dropdown; + const defaultSettings = (combo as any)._overlaySettings; + combo.toggle(); + expect(combo.dropdown.toggle).toHaveBeenCalledWith(defaultSettings || {}); + const newSettings = { + positionStrategy: new ConnectedPositioningStrategy(), + scrollStrategy: new AbsoluteScrollStrategy() + }; + combo.overlaySettings = newSettings; + const expectedSettings = Object.assign({}, defaultSettings, newSettings); + combo.toggle(); + expect(combo.dropdown.toggle).toHaveBeenCalledWith(expectedSettings); + }); }); it('should properly get/set displayKey', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.valueKey = 'field'; - expect(combo.displayKey).toEqual(combo.valueKey); - combo.displayKey = 'region'; - expect(combo.displayKey).toEqual('region'); - expect(combo.displayKey === combo.valueKey).toBeFalsy(); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.valueKey = 'field'; + expect(combo.displayKey).toEqual(combo.valueKey); + combo.displayKey = 'region'; + expect(combo.displayKey).toEqual('region'); + expect(combo.displayKey === combo.valueKey).toBeFalsy(); + }); }); it('should properly call "writeValue" method', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - mockSelection.select_items.calls.reset(); - spyOnProperty(combo, 'isRemote').and.returnValue(false); - combo.writeValue(['EXAMPLE']); - expect(mockSelection.select_items).toHaveBeenCalledTimes(1); - - // Calling "select_items" through the writeValue accessor should clear the previous values; - // Select items is called with the invalid value and it is written in selection, though no item is selected - // Controlling the selection is up to the user - expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['EXAMPLE'], true); - combo.writeValue(combo.data[0]); - // When value key is specified, the item's value key is stored in the selection - expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, [], true); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + mockSelection.select_items.calls.reset(); + spyOnProperty(combo, 'isRemote').and.returnValue(false); + combo.writeValue(['EXAMPLE']); + expect(mockSelection.select_items).toHaveBeenCalledTimes(1); + + // Calling "select_items" through the writeValue accessor should clear the previous values; + // Select items is called with the invalid value and it is written in selection, though no item is selected + // Controlling the selection is up to the user + expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['EXAMPLE'], true); + combo.writeValue(combo.data[0]); + // When value key is specified, the item's value key is stored in the selection + expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, [], true); + }); }); it('should select items through setSelctedItem method', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = complexData; - combo.valueKey = 'country'; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - - const selectedItems = [combo.data[0]]; - const selectedValues = [combo.data[0].country]; - combo.setSelectedItem('UK', true); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedValues); - combo.setSelectedItem('Germany', true); - selectedItems.push(combo.data[2]); - selectedValues.push(combo.data[2].country); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedValues); - selectedItems.pop(); - selectedValues.pop(); - combo.setSelectedItem('Germany', false); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedValues); - selectedItems.pop(); - selectedValues.pop(); - combo.setSelectedItem('UK', false); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedValues); - - combo.valueKey = null; - selectedItems.push(combo.data[5]); - combo.setSelectedItem(combo.data[5], true); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - selectedItems.push(combo.data[1]); - combo.setSelectedItem(combo.data[1], true); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - selectedItems.pop(); - combo.setSelectedItem(combo.data[1], false); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = complexData; + combo.valueKey = 'country'; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + + const selectedItems = [combo.data[0]]; + const selectedValues = [combo.data[0].country]; + combo.setSelectedItem('UK', true); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedValues); + combo.setSelectedItem('Germany', true); + selectedItems.push(combo.data[2]); + selectedValues.push(combo.data[2].country); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedValues); + selectedItems.pop(); + selectedValues.pop(); + combo.setSelectedItem('Germany', false); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedValues); + selectedItems.pop(); + selectedValues.pop(); + combo.setSelectedItem('UK', false); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedValues); + + combo.valueKey = null; + selectedItems.push(combo.data[5]); + combo.setSelectedItem(combo.data[5], true); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + selectedItems.push(combo.data[1]); + combo.setSelectedItem(combo.data[1], true); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + selectedItems.pop(); + combo.setSelectedItem(combo.data[1], false); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + }); }); it('should set selectedItems correctly on selectItems method call', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - - combo.select([], false); - expect(combo.selection).toEqual([]); - expect(combo.value).toEqual([]); - combo.select([], true); - expect(combo.selection).toEqual([]); - expect(combo.value).toEqual([]); - const selectedItems = combo.data.slice(0, 3); - combo.select(combo.data.slice(0, 3), true); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - combo.select([], false); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - selectedItems.push(combo.data[3]); - combo.select([combo.data[3]], false); - expect(combo.selection).toEqual(combo.data.slice(0, 4)); - expect(combo.value).toEqual(combo.data.slice(0, 4)); - combo.select([], true); - expect(combo.selection).toEqual([]); - expect(combo.value).toEqual([]); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + + combo.select([], false); + expect(combo.selection).toEqual([]); + expect(combo.value).toEqual([]); + combo.select([], true); + expect(combo.selection).toEqual([]); + expect(combo.value).toEqual([]); + const selectedItems = combo.data.slice(0, 3); + combo.select(combo.data.slice(0, 3), true); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + combo.select([], false); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + selectedItems.push(combo.data[3]); + combo.select([combo.data[3]], false); + expect(combo.selection).toEqual(combo.data.slice(0, 4)); + expect(combo.value).toEqual(combo.data.slice(0, 4)); + combo.select([], true); + expect(combo.selection).toEqual([]); + expect(combo.value).toEqual([]); + }); }); it('should emit owner on `opening` and `closing`', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - spyOn(combo.opening, 'emit').and.callThrough(); - spyOn(combo.closing, 'emit').and.callThrough(); - const mockObj = {}; - const mockEvent = new Event('mock'); - const inputEvent: IBaseCancelableBrowserEventArgs = { - cancel: false, - owner: mockObj, - event: mockEvent - }; - combo.comboInput = { - nativeElement: { - focus: () => { } - } - } as any; - combo.handleOpening(inputEvent); - const expectedCall: IBaseCancelableBrowserEventArgs = { owner: combo, event: inputEvent.event, cancel: inputEvent.cancel }; - expect(combo.opening.emit).toHaveBeenCalledWith(expectedCall); - combo.handleClosing(inputEvent); - expect(combo.closing.emit).toHaveBeenCalledWith(expectedCall); - let sub = combo.opening.subscribe((e: IBaseCancelableBrowserEventArgs) => { - e.cancel = true; - }); - combo.handleOpening(inputEvent); - expect(inputEvent.cancel).toEqual(true); - sub.unsubscribe(); - inputEvent.cancel = false; - - sub = combo.closing.subscribe((e: IBaseCancelableBrowserEventArgs) => { - e.cancel = true; - }); - combo.handleClosing(inputEvent); - expect(inputEvent.cancel).toEqual(true); - sub.unsubscribe(); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + spyOn(combo.opening, 'emit').and.callThrough(); + spyOn(combo.closing, 'emit').and.callThrough(); + const mockObj = {}; + const mockEvent = new Event('mock'); + const inputEvent: IBaseCancelableBrowserEventArgs = { + cancel: false, + owner: mockObj, + event: mockEvent + }; + combo.comboInput = { + nativeElement: { + focus: () => { } + } + } as any; + combo.handleOpening(inputEvent); + const expectedCall: IBaseCancelableBrowserEventArgs = { owner: combo, event: inputEvent.event, cancel: inputEvent.cancel }; + expect(combo.opening.emit).toHaveBeenCalledWith(expectedCall); + combo.handleClosing(inputEvent); + expect(combo.closing.emit).toHaveBeenCalledWith(expectedCall); + let sub = combo.opening.subscribe((e: IBaseCancelableBrowserEventArgs) => { + e.cancel = true; + }); + combo.handleOpening(inputEvent); + expect(inputEvent.cancel).toEqual(true); + sub.unsubscribe(); + inputEvent.cancel = false; + + sub = combo.closing.subscribe((e: IBaseCancelableBrowserEventArgs) => { + e.cancel = true; + }); + combo.handleClosing(inputEvent); + expect(inputEvent.cancel).toEqual(true); + sub.unsubscribe(); + }); }); it('should fire selectionChanging event on item selection', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - spyOn(combo.selectionChanging, 'emit'); - - let oldValue = []; - let newValue = [combo.data[1], combo.data[5], combo.data[6]]; - - let oldSelection = []; - let newSelection = [combo.data[1], combo.data[5], combo.data[6]]; - - combo.select(newSelection); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(1); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue, - newValue, - oldSelection, - newSelection, - added: newSelection, - removed: [], - event: undefined, - owner: combo, - displayText: `${newSelection.join(', ')}`, - cancel: false - }); - - let newItem = combo.data[3]; - combo.select([newItem]); - oldValue = [...newValue]; - newValue.push(newItem); - oldSelection = [...newSelection]; - newSelection.push(newItem); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(2); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue, - newValue, - oldSelection, - newSelection, - removed: [], - added: [combo.data[3]], - event: undefined, - owner: combo, - displayText: `${newSelection.join(', ')}`, - cancel: false - }); - - oldValue = [...newValue]; - newValue = [combo.data[0]]; - oldSelection = [...newSelection]; - newSelection = [combo.data[0]]; - combo.select(newSelection, true); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(3); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue, - newValue, - oldSelection, - newSelection, - removed: oldSelection, - added: newSelection, - event: undefined, - owner: combo, - displayText: `${newSelection.join(', ')}`, - cancel: false - }); - - oldValue = [...newValue]; - newValue = []; - oldSelection = [...newSelection]; - newSelection = []; - newItem = combo.data[0]; - combo.deselect([newItem]); - expect(combo.selection.length).toEqual(0); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(4); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue, - newValue, - oldSelection, - newSelection, - removed: [combo.data[0]], - added: [], - event: undefined, - owner: combo, - displayText: `${newSelection.join(', ')}`, - cancel: false + + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + spyOn(combo.selectionChanging, 'emit'); + + let oldValue = []; + let newValue = [combo.data[1], combo.data[5], combo.data[6]]; + + let oldSelection = []; + let newSelection = [combo.data[1], combo.data[5], combo.data[6]]; + + combo.select(newSelection); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(1); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue, + newValue, + oldSelection, + newSelection, + added: newSelection, + removed: [], + event: undefined, + owner: combo, + displayText: `${newSelection.join(', ')}`, + cancel: false + }); + + let newItem = combo.data[3]; + combo.select([newItem]); + oldValue = [...newValue]; + newValue.push(newItem); + oldSelection = [...newSelection]; + newSelection.push(newItem); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(2); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue, + newValue, + oldSelection, + newSelection, + removed: [], + added: [combo.data[3]], + event: undefined, + owner: combo, + displayText: `${newSelection.join(', ')}`, + cancel: false + }); + + oldValue = [...newValue]; + newValue = [combo.data[0]]; + oldSelection = [...newSelection]; + newSelection = [combo.data[0]]; + combo.select(newSelection, true); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(3); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue, + newValue, + oldSelection, + newSelection, + removed: oldSelection, + added: newSelection, + event: undefined, + owner: combo, + displayText: `${newSelection.join(', ')}`, + cancel: false + }); + + oldValue = [...newValue]; + newValue = []; + oldSelection = [...newSelection]; + newSelection = []; + newItem = combo.data[0]; + combo.deselect([newItem]); + expect(combo.selection.length).toEqual(0); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(4); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue, + newValue, + oldSelection, + newSelection, + removed: [combo.data[0]], + added: [], + event: undefined, + owner: combo, + displayText: `${newSelection.join(', ')}`, + cancel: false + }); }); }); it('should properly emit added and removed values in change event on single value selection', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = complexData; - combo.valueKey = 'country'; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - const selectionSpy = spyOn(combo.selectionChanging, 'emit'); - const expectedResults: IComboSelectionChangingEventArgs = { - newValue: [combo.data[0][combo.valueKey]], - oldValue: [], - newSelection: [combo.data[0]], - oldSelection: [], - added: [combo.data[0]], - removed: [], - event: undefined, - owner: combo, - displayText: `${combo.data[0][combo.displayKey]}`, - cancel: false - }; - combo.select([combo.data[0][combo.valueKey]]); - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); - Object.assign(expectedResults, { - newValue: [], - oldValue: [combo.data[0][combo.valueKey]], - newSelection: [], - oldSelection: [combo.data[0]], - added: [], - displayText: '', - removed: [combo.data[0]] - }); - combo.deselect([combo.data[0][combo.valueKey]]); - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = complexData; + combo.valueKey = 'country'; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + const selectionSpy = spyOn(combo.selectionChanging, 'emit'); + const expectedResults: IComboSelectionChangingEventArgs = { + newValue: [combo.data[0][combo.valueKey]], + oldValue: [], + newSelection: [combo.data[0]], + oldSelection: [], + added: [combo.data[0]], + removed: [], + event: undefined, + owner: combo, + displayText: `${combo.data[0][combo.displayKey]}`, + cancel: false + }; + combo.select([combo.data[0][combo.valueKey]]); + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + Object.assign(expectedResults, { + newValue: [], + oldValue: [combo.data[0][combo.valueKey]], + newSelection: [], + oldSelection: [combo.data[0]], + added: [], + displayText: '', + removed: [combo.data[0]] + }); + combo.deselect([combo.data[0][combo.valueKey]]); + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + }); }); it('should properly emit added and removed values in change event on multiple values selection', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = complexData; - combo.valueKey = 'country'; - combo.displayKey = 'city'; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - const selectionSpy = spyOn(combo.selectionChanging, 'emit'); - - let oldSelection = []; - let newSelection = [combo.data[0], combo.data[1], combo.data[2]]; - combo.select(newSelection.map(e => e[combo.valueKey])); - const expectedResults: IComboSelectionChangingEventArgs = { - newValue: newSelection.map(e => e[combo.valueKey]), - oldValue: [], - newSelection: newSelection, - oldSelection, - added: newSelection, - removed: [], - event: undefined, - owner: combo, - displayText: `${newSelection.map(entry => entry[combo.displayKey]).join(', ')}`, - cancel: false - }; - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); - - oldSelection = [...newSelection]; - newSelection = [combo.data[1], combo.data[2]]; - combo.deselect([combo.data[0][combo.valueKey]]); - Object.assign(expectedResults, { - newValue: newSelection.map(e => e[combo.valueKey]), - oldValue: oldSelection.map(e => e[combo.valueKey]), - newSelection, - oldSelection, - added: [], - displayText: newSelection.map(e => e[combo.displayKey]).join(', '), - removed: [combo.data[0]] - }); - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); - - oldSelection = [...newSelection]; - newSelection = [combo.data[4], combo.data[5], combo.data[6]]; - combo.select(newSelection.map(e => e[combo.valueKey]), true); - Object.assign(expectedResults, { - newValue: newSelection.map(e => e[combo.valueKey]), - oldValue: oldSelection.map(e => e[combo.valueKey]), - newSelection, - oldSelection, - added: newSelection, - displayText: newSelection.map(e => e[combo.displayKey]).join(', '), - removed: oldSelection - }); - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = complexData; + combo.valueKey = 'country'; + combo.displayKey = 'city'; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + const selectionSpy = spyOn(combo.selectionChanging, 'emit'); + + let oldSelection = []; + let newSelection = [combo.data[0], combo.data[1], combo.data[2]]; + combo.select(newSelection.map(e => e[combo.valueKey])); + const expectedResults: IComboSelectionChangingEventArgs = { + newValue: newSelection.map(e => e[combo.valueKey]), + oldValue: [], + newSelection: newSelection, + oldSelection, + added: newSelection, + removed: [], + event: undefined, + owner: combo, + displayText: `${newSelection.map(entry => entry[combo.displayKey]).join(', ')}`, + cancel: false + }; + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + + oldSelection = [...newSelection]; + newSelection = [combo.data[1], combo.data[2]]; + combo.deselect([combo.data[0][combo.valueKey]]); + Object.assign(expectedResults, { + newValue: newSelection.map(e => e[combo.valueKey]), + oldValue: oldSelection.map(e => e[combo.valueKey]), + newSelection, + oldSelection, + added: [], + displayText: newSelection.map(e => e[combo.displayKey]).join(', '), + removed: [combo.data[0]] + }); + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + + oldSelection = [...newSelection]; + newSelection = [combo.data[4], combo.data[5], combo.data[6]]; + combo.select(newSelection.map(e => e[combo.valueKey]), true); + Object.assign(expectedResults, { + newValue: newSelection.map(e => e[combo.valueKey]), + oldValue: oldSelection.map(e => e[combo.valueKey]), + newSelection, + oldSelection, + added: newSelection, + displayText: newSelection.map(e => e[combo.displayKey]).join(', '), + removed: oldSelection + }); + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + }); }); it('should handle select/deselect ALL items', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - spyOn(combo, 'selectAllItems'); - spyOn(combo, 'deselectAllItems'); - - combo.handleSelectAll({ checked: true }); - expect(combo.selectAllItems).toHaveBeenCalledTimes(1); - expect(combo.deselectAllItems).toHaveBeenCalledTimes(0); - - combo.handleSelectAll({ checked: false }); - expect(combo.selectAllItems).toHaveBeenCalledTimes(1); - expect(combo.deselectAllItems).toHaveBeenCalledTimes(1); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + spyOn(combo, 'selectAllItems'); + spyOn(combo, 'deselectAllItems'); + + combo.handleSelectAll({ checked: true }); + expect(combo.selectAllItems).toHaveBeenCalledTimes(1); + expect(combo.deselectAllItems).toHaveBeenCalledTimes(0); + + combo.handleSelectAll({ checked: false }); + expect(combo.selectAllItems).toHaveBeenCalledTimes(1); + expect(combo.deselectAllItems).toHaveBeenCalledTimes(1); + }); }); it('should emit onSelectonChange event on select/deselect ALL items method call', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - spyOn(combo.selectionChanging, 'emit'); - - combo.selectAllItems(true); - expect(combo.selection).toEqual(data); - expect(combo.value).toEqual(data); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(1); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue: [], - newValue: data, - oldSelection: [], - newSelection: data, - added: data, - removed: [], - owner: combo, - event: undefined, - displayText: `${combo.data.join(', ')}`, - cancel: false - }); - - combo.deselectAllItems(true); - expect(combo.selection).toEqual([]); - expect(combo.value).toEqual([]); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(2); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue: data, - newValue: [], - oldSelection: data, - newSelection: [], - added: [], - removed: data, - owner: combo, - event: undefined, - displayText: '', - cancel: false + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + spyOn(combo.selectionChanging, 'emit'); + + combo.selectAllItems(true); + expect(combo.selection).toEqual(data); + expect(combo.value).toEqual(data); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(1); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue: [], + newValue: data, + oldSelection: [], + newSelection: data, + added: data, + removed: [], + owner: combo, + event: undefined, + displayText: `${combo.data.join(', ')}`, + cancel: false + }); + + combo.deselectAllItems(true); + expect(combo.selection).toEqual([]); + expect(combo.value).toEqual([]); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(2); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue: data, + newValue: [], + oldSelection: data, + newSelection: [], + added: [], + removed: data, + owner: combo, + event: undefined, + displayText: '', + cancel: false + }); }); }); it('should properly handle selection manipulation through selectionChanging emit', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.newValue = []); - // No items are initially selected - expect(combo.selection).toEqual([]); - // Select the first 5 items - combo.select(combo.data.splice(0, 5)); - // selectionChanging fires and overrides the selection to be []; - expect(combo.selection).toEqual([]); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.newValue = []); + // No items are initially selected + expect(combo.selection).toEqual([]); + // Select the first 5 items + combo.select(combo.data.splice(0, 5)); + // selectionChanging fires and overrides the selection to be []; + expect(combo.selection).toEqual([]); + }); }); it('should not throw error when setting data to null', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - let errorMessage = ''; - try { - combo.data = null; - } catch (ex) { - errorMessage = ex.message; - } - expect(errorMessage).toBe(''); - expect(combo.data).not.toBeUndefined(); - expect(combo.data).not.toBeNull(); - expect(combo.data.length).toBe(0); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + let errorMessage = ''; + try { + combo.data = null; + } catch (ex) { + errorMessage = ex.message; + } + expect(errorMessage).toBe(''); + expect(combo.data).not.toBeUndefined(); + expect(combo.data).not.toBeNull(); + expect(combo.data.length).toBe(0); + }); }); it('should not throw error when setting data to undefined', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - let errorMessage = ''; - try { - combo.data = undefined; - } catch (ex) { - errorMessage = ex.message; - } - expect(errorMessage).toBe(''); - expect(combo.data).not.toBeUndefined(); - expect(combo.data).not.toBeNull(); - expect(combo.data.length).toBe(0); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + let errorMessage = ''; + try { + combo.data = undefined; + } catch (ex) { + errorMessage = ex.message; + } + expect(errorMessage).toBe(''); + expect(combo.data).not.toBeUndefined(); + expect(combo.data).not.toBeNull(); + expect(combo.data.length).toBe(0); + }); }); it('should properly handleInputChange', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - combo.comboInput = { - value: '', - } as any; - combo.filteringOptions.filterable = true; - const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); - spyOn(combo.searchInputUpdate, 'emit'); - - combo.handleInputChange(); - expect(matchSpy).toHaveBeenCalledTimes(1); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(0); - - const args = { - searchText: 'Fake', - owner: combo, - cancel: false - }; - combo.handleInputChange('Fake'); - expect(matchSpy).toHaveBeenCalledTimes(2); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(1); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledWith(args); - - args.searchText = ''; - combo.handleInputChange(''); - expect(matchSpy).toHaveBeenCalledTimes(3); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(2); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledWith(args); - - combo.filteringOptions.filterable = false; - combo.handleInputChange(); - expect(matchSpy).toHaveBeenCalledTimes(4); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(2); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + combo.comboInput = { + value: '', + } as any; + combo.filteringOptions.filterable = true; + const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); + spyOn(combo.searchInputUpdate, 'emit'); + + combo.handleInputChange(); + expect(matchSpy).toHaveBeenCalledTimes(1); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(0); + + const args = { + searchText: 'Fake', + owner: combo, + cancel: false + }; + combo.handleInputChange('Fake'); + expect(matchSpy).toHaveBeenCalledTimes(2); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(1); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledWith(args); + + args.searchText = ''; + combo.handleInputChange(''); + expect(matchSpy).toHaveBeenCalledTimes(3); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(2); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledWith(args); + + combo.filteringOptions.filterable = false; + combo.handleInputChange(); + expect(matchSpy).toHaveBeenCalledTimes(4); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(2); + }); }); it('should be able to cancel searchInputUpdate', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.filteringOptions.filterable = true; - combo.searchInputUpdate.subscribe((e) => { - e.cancel = true; - }); - const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); - spyOn(combo.searchInputUpdate, 'emit').and.callThrough(); - - combo.handleInputChange('Item1'); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(1); - expect(matchSpy).toHaveBeenCalledTimes(1); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.filteringOptions.filterable = true; + combo.searchInputUpdate.subscribe((e) => { + e.cancel = true; + }); + const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); + spyOn(combo.searchInputUpdate, 'emit').and.callThrough(); + + combo.handleInputChange('Item1'); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(1); + expect(matchSpy).toHaveBeenCalledTimes(1); + }); }); it('should not open on click if combo is disabled', () => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']); - const spyObj = jasmine.createSpyObj('event', ['stopPropagation', 'preventDefault']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.dropdown = dropdown; - dropdown.collapsed = true; - - combo.disabled = true; - combo.onClick(spyObj); - expect(combo.dropdown.collapsed).toBeTruthy(); + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']); + const spyObj = jasmine.createSpyObj('event', ['stopPropagation', 'preventDefault']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.dropdown = dropdown; + dropdown.collapsed = true; + + combo.disabled = true; + combo.onClick(spyObj); + expect(combo.dropdown.collapsed).toBeTruthy(); + }); }); it('should not clear value when combo is disabled', () => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - const spyObj = jasmine.createSpyObj('event', ['stopPropagation']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - combo.disabled = true; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - - const item = combo.data.slice(0, 1); - combo.select(item, true); - combo.handleClearItems(spyObj); - expect(combo.displayValue).toEqual(item[0]); + + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + const spyObj = jasmine.createSpyObj('event', ['stopPropagation']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + combo.disabled = true; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + + const item = combo.data.slice(0, 1); + combo.select(item, true); + combo.handleClearItems(spyObj); + expect(combo.displayValue).toEqual(item[0]); + }) }); it('should allow canceling and overwriting of item addition', fakeAsync(() => { const selectionService = new IgxSelectionAPIService(); - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - const mockVirtDir = jasmine.createSpyObj('virtDir', ['scrollTo']); - const mockInput = jasmine.createSpyObj('mockInput', [], { - nativeElement: jasmine.createSpyObj('mockElement', ['focus']) - }); - spyOn(combo.addition, 'emit').and.callThrough(); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - const subParams: { cancel: boolean; newValue: string; modify: boolean } = { - cancel: false, - modify: false, - newValue: 'mockValue' - }; - const sub = combo.addition.subscribe((e) => { - if (subParams.cancel) { - e.cancel = true; - } - if (subParams.modify) { - e.addedItem = subParams.newValue; - } - }); - combo.ngOnInit(); - combo.data = ['Item 1', 'Item 2', 'Item 3']; - combo.dropdown = dropdown; - combo.searchInput = mockInput; - (combo as any).virtDir = mockVirtDir; - let mockAddParams: IComboItemAdditionEvent = { - cancel: false, - owner: combo, - addedItem: 'Item 99', - newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'], - oldCollection: ['Item 1', 'Item 2', 'Item 3'] - }; + TestBed.runInInjectionContext(() => { + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + const mockVirtDir = jasmine.createSpyObj('virtDir', ['scrollTo']); + const mockInput = jasmine.createSpyObj('mockInput', [], { + nativeElement: jasmine.createSpyObj('mockElement', ['focus']) + }); + spyOn(combo.addition, 'emit').and.callThrough(); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + const subParams: { cancel: boolean; newValue: string; modify: boolean } = { + cancel: false, + modify: false, + newValue: 'mockValue' + }; + const sub = combo.addition.subscribe((e) => { + if (subParams.cancel) { + e.cancel = true; + } + if (subParams.modify) { + e.addedItem = subParams.newValue; + } + }); + combo.ngOnInit(); + combo.data = ['Item 1', 'Item 2', 'Item 3']; + combo.dropdown = dropdown; + combo.searchInput = mockInput; + (combo as any).virtDir = mockVirtDir; + let mockAddParams: IComboItemAdditionEvent = { + cancel: false, + owner: combo, + addedItem: 'Item 99', + newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'], + oldCollection: ['Item 1', 'Item 2', 'Item 3'] + }; - // handle addition - - combo.searchValue = 'Item 99'; - combo.addItemToCollection(); - tick(); - expect(combo.data.length).toEqual(4); - expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); - expect(combo.addition.emit).toHaveBeenCalledTimes(1); - expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(1); - expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(1); - expect(combo.data[combo.data.length - 1]).toBe('Item 99'); - expect(selectionService.get(combo.id).size).toBe(1); - expect([...selectionService.get(combo.id)][0]).toBe('Item 99'); - - // cancel - subParams.cancel = true; - mockAddParams = { - cancel: true, - owner: combo, - addedItem: 'Item 99', - newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99', 'Item 99'], - oldCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'] - }; - combo.searchValue = 'Item 99'; - combo.addItemToCollection(); - tick(); - expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); - expect(combo.addition.emit).toHaveBeenCalledTimes(2); - expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(1); - expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(1); - expect(combo.data.length).toEqual(4); - expect(combo.data[combo.data.length - 1]).toBe('Item 99'); - expect(selectionService.get(combo.id).size).toBe(1); - expect([...selectionService.get(combo.id)][0]).toBe('Item 99'); - - // overwrite - subParams.modify = true; - subParams.cancel = false; - mockAddParams = { - cancel: false, - owner: combo, - addedItem: 'mockValue', - newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99', 'Item 99'], - oldCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'] - }; + // handle addition - combo.searchValue = 'Item 99'; - combo.addItemToCollection(); - tick(); - expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); - expect(combo.addition.emit).toHaveBeenCalledTimes(3); - expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(2); - expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(2); - expect(combo.data.length).toEqual(5); - expect(combo.data[combo.data.length - 1]).toBe(subParams.newValue); - expect(selectionService.get(combo.id).size).toBe(2); - expect([...selectionService.get(combo.id)][1]).toBe(subParams.newValue); - sub.unsubscribe(); + combo.searchValue = 'Item 99'; + combo.addItemToCollection(); + tick(); + expect(combo.data.length).toEqual(4); + expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); + expect(combo.addition.emit).toHaveBeenCalledTimes(1); + expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(1); + expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(1); + expect(combo.data[combo.data.length - 1]).toBe('Item 99'); + expect(selectionService.get(combo.id).size).toBe(1); + expect([...selectionService.get(combo.id)][0]).toBe('Item 99'); + + // cancel + subParams.cancel = true; + mockAddParams = { + cancel: true, + owner: combo, + addedItem: 'Item 99', + newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99', 'Item 99'], + oldCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'] + }; + + combo.searchValue = 'Item 99'; + combo.addItemToCollection(); + tick(); + expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); + expect(combo.addition.emit).toHaveBeenCalledTimes(2); + expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(1); + expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(1); + expect(combo.data.length).toEqual(4); + expect(combo.data[combo.data.length - 1]).toBe('Item 99'); + expect(selectionService.get(combo.id).size).toBe(1); + expect([...selectionService.get(combo.id)][0]).toBe('Item 99'); + + // overwrite + subParams.modify = true; + subParams.cancel = false; + mockAddParams = { + cancel: false, + owner: combo, + addedItem: 'mockValue', + newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99', 'Item 99'], + oldCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'] + }; + + combo.searchValue = 'Item 99'; + combo.addItemToCollection(); + tick(); + expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); + expect(combo.addition.emit).toHaveBeenCalledTimes(3); + expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(2); + expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(2); + expect(combo.data.length).toEqual(5); + expect(combo.data[combo.data.length - 1]).toBe(subParams.newValue); + expect(selectionService.get(combo.id).size).toBe(2); + expect([...selectionService.get(combo.id)][1]).toBe(subParams.newValue); + sub.unsubscribe(); + }); })); }); diff --git a/projects/igniteui-angular/src/lib/core/density.ts b/projects/igniteui-angular/src/lib/core/density.ts index 83acb436665..dac6acdb4f2 100644 --- a/projects/igniteui-angular/src/lib/core/density.ts +++ b/projects/igniteui-angular/src/lib/core/density.ts @@ -9,31 +9,11 @@ import { Optional, Inject, ElementRef, - inject, - runInInjectionContext, - Injector, } from '@angular/core'; import { IBaseEventArgs, mkenum } from './utils'; +import { inject } from './inject'; import { DOCUMENT } from '@angular/common'; -/** Create a document factory **/ -function _document(): Document { - return document; -} - -/** - * Construct a provider object to be used when creating an Injector context - */ -const documentProviders = [ - { provide: DOCUMENT, useFactory: _document } -]; - -/** - * A custom Injector context used when injecting DOCUMENT using - * the `inject` function. - */ -const documentInjector = Injector.create({ providers: documentProviders }); - /** * Defines the possible values of the components' display density. */ @@ -165,10 +145,7 @@ export class DisplayDensityBase implements DoCheck, OnInit { protected _host: ElementRef ) { Object.assign(this.oldDisplayDensityOptions, displayDensityOptions); - - runInInjectionContext(documentInjector, () => { - this._document = inject(DOCUMENT); - }); + this._document = inject(DOCUMENT); } /** diff --git a/projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts b/projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts index 90682c67fca..612887993e0 100644 --- a/projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts @@ -153,150 +153,162 @@ describe('IgxDateRangePicker', () => { }); /* eslint-enable @typescript-eslint/no-unused-vars */ it('should set range dates correctly through selectRange method', () => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, null, null, null, null); - // dateRange.calendar = calendar; - let startDate = new Date(2020, 3, 7); - const endDate = new Date(2020, 6, 27); - - // select range - dateRange.select(startDate, endDate); - expect(dateRange.value.start).toEqual(startDate); - expect(dateRange.value.end).toEqual(endDate); - - // select startDate only - startDate = new Date(2023, 2, 11); - dateRange.select(startDate); - expect(dateRange.value.start).toEqual(startDate); - expect(dateRange.value.end).toEqual(startDate); + TestBed.runInInjectionContext(() => { + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, null, null, null, null); + // dateRange.calendar = calendar; + let startDate = new Date(2020, 3, 7); + const endDate = new Date(2020, 6, 27); + + // select range + dateRange.select(startDate, endDate); + expect(dateRange.value.start).toEqual(startDate); + expect(dateRange.value.end).toEqual(endDate); + + // select startDate only + startDate = new Date(2023, 2, 11); + dateRange.select(startDate); + expect(dateRange.value.start).toEqual(startDate); + expect(dateRange.value.end).toEqual(startDate); + }); }); it('should emit valueChange on selection', () => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, null, null, null, null); - // dateRange.calendar = calendar; - spyOn(dateRange.valueChange, 'emit'); - let startDate = new Date(2017, 4, 5); - const endDate = new Date(2017, 11, 22); - - // select range - dateRange.select(startDate, endDate); - expect(dateRange.value.start).toEqual(startDate); - expect(dateRange.value.end).toEqual(endDate); - expect(dateRange.valueChange.emit).toHaveBeenCalledTimes(1); - expect(dateRange.valueChange.emit).toHaveBeenCalledWith({ start: startDate, end: endDate }); - - // select startDate only - startDate = new Date(2024, 12, 15); - dateRange.select(startDate); - expect(dateRange.value.start).toEqual(startDate); - expect(dateRange.value.end).toEqual(startDate); - expect(dateRange.valueChange.emit).toHaveBeenCalledTimes(2); - expect(dateRange.valueChange.emit).toHaveBeenCalledWith({ start: startDate, end: startDate }); + TestBed.runInInjectionContext(() => { + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, null, null, null, null); + // dateRange.calendar = calendar; + spyOn(dateRange.valueChange, 'emit'); + let startDate = new Date(2017, 4, 5); + const endDate = new Date(2017, 11, 22); + + // select range + dateRange.select(startDate, endDate); + expect(dateRange.value.start).toEqual(startDate); + expect(dateRange.value.end).toEqual(endDate); + expect(dateRange.valueChange.emit).toHaveBeenCalledTimes(1); + expect(dateRange.valueChange.emit).toHaveBeenCalledWith({ start: startDate, end: endDate }); + + // select startDate only + startDate = new Date(2024, 12, 15); + dateRange.select(startDate); + expect(dateRange.value.start).toEqual(startDate); + expect(dateRange.value.end).toEqual(startDate); + expect(dateRange.valueChange.emit).toHaveBeenCalledTimes(2); + expect(dateRange.valueChange.emit).toHaveBeenCalledWith({ start: startDate, end: startDate }); + }); }); it('should correctly implement interface methods - ControlValueAccessor', () => { const range = { start: new Date(2020, 1, 18), end: new Date(2020, 1, 28) }; const rangeUpdate = { start: new Date(2020, 2, 22), end: new Date(2020, 2, 25) }; - // init - const dateRangePicker = new IgxDateRangePickerComponent(null, 'en', platform, null, null, null, null); - dateRangePicker.registerOnChange(mockNgControl.registerOnChangeCb); - dateRangePicker.registerOnTouched(mockNgControl.registerOnTouchedCb); - spyOn(dateRangePicker as any, 'handleSelection').and.callThrough(); - - // writeValue - expect(dateRangePicker.value).toBeUndefined(); - expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled(); - dateRangePicker.writeValue(range); - expect(dateRangePicker.value).toBe(range); - - // set value & handleSelection call _onChangeCallback - dateRangePicker.value = rangeUpdate; - expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith(rangeUpdate); - - (dateRangePicker as any).handleSelection([range.start]); - expect((dateRangePicker as any).handleSelection).toHaveBeenCalledWith([range.start]); - expect((dateRangePicker as any).handleSelection).toHaveBeenCalledTimes(1); - expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith({ start: range.start, end: range.start }); - - // awaiting implementation - OnTouched callback - // Docs: changes the value, turning the control dirty; or blurs the form control element, setting the control to touched. - // when handleSelection fires should be touched&dirty // when input is blurred(two inputs), should be touched. - (dateRangePicker as any).handleSelection([range.start]); - (dateRangePicker as any).updateValidityOnBlur(); - expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1); - - dateRangePicker.setDisabledState(true); - expect(dateRangePicker.disabled).toBe(true); - dateRangePicker.setDisabledState(false); - expect(dateRangePicker.disabled).toBe(false); + TestBed.runInInjectionContext(() => { + // init + const dateRangePicker = new IgxDateRangePickerComponent(null, 'en', platform, null, null, null, null); + dateRangePicker.registerOnChange(mockNgControl.registerOnChangeCb); + dateRangePicker.registerOnTouched(mockNgControl.registerOnTouchedCb); + spyOn(dateRangePicker as any, 'handleSelection').and.callThrough(); + + // writeValue + expect(dateRangePicker.value).toBeUndefined(); + expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled(); + dateRangePicker.writeValue(range); + expect(dateRangePicker.value).toBe(range); + + // set value & handleSelection call _onChangeCallback + dateRangePicker.value = rangeUpdate; + expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith(rangeUpdate); + + (dateRangePicker as any).handleSelection([range.start]); + expect((dateRangePicker as any).handleSelection).toHaveBeenCalledWith([range.start]); + expect((dateRangePicker as any).handleSelection).toHaveBeenCalledTimes(1); + expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith({ start: range.start, end: range.start }); + + // awaiting implementation - OnTouched callback + // Docs: changes the value, turning the control dirty; or blurs the form control element, setting the control to touched. + // when handleSelection fires should be touched&dirty // when input is blurred(two inputs), should be touched. + (dateRangePicker as any).handleSelection([range.start]); + (dateRangePicker as any).updateValidityOnBlur(); + expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1); + + dateRangePicker.setDisabledState(true); + expect(dateRangePicker.disabled).toBe(true); + dateRangePicker.setDisabledState(false); + expect(dateRangePicker.disabled).toBe(false); + }); }); it('should validate correctly minValue and maxValue', () => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, mockInjector, null, null, null); - dateRange.ngOnInit(); + TestBed.runInInjectionContext(() => { + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, mockInjector, null, null, null); + dateRange.ngOnInit(); - // dateRange.calendar = calendar; - dateRange.registerOnChange(mockNgControl.registerOnChangeCb); - dateRange.registerOnValidatorChange(mockNgControl.registerOnValidatorChangeCb); + // dateRange.calendar = calendar; + dateRange.registerOnChange(mockNgControl.registerOnChangeCb); + dateRange.registerOnValidatorChange(mockNgControl.registerOnValidatorChangeCb); - dateRange.minValue = new Date(2020, 4, 7); - expect(mockNgControl.registerOnValidatorChangeCb).toHaveBeenCalledTimes(1); - dateRange.maxValue = new Date(2020, 8, 7); - expect(mockNgControl.registerOnValidatorChangeCb).toHaveBeenCalledTimes(2); + dateRange.minValue = new Date(2020, 4, 7); + expect(mockNgControl.registerOnValidatorChangeCb).toHaveBeenCalledTimes(1); + dateRange.maxValue = new Date(2020, 8, 7); + expect(mockNgControl.registerOnValidatorChangeCb).toHaveBeenCalledTimes(2); - const range = { start: new Date(2020, 4, 18), end: new Date(2020, 6, 28) }; - dateRange.writeValue(range); - const mockFormControl = new UntypedFormControl(dateRange.value); - expect(dateRange.validate(mockFormControl)).toBeNull(); + const range = { start: new Date(2020, 4, 18), end: new Date(2020, 6, 28) }; + dateRange.writeValue(range); + const mockFormControl = new UntypedFormControl(dateRange.value); + expect(dateRange.validate(mockFormControl)).toBeNull(); - range.start.setMonth(2); - expect(dateRange.validate(mockFormControl)).toEqual({ minValue: true }); + range.start.setMonth(2); + expect(dateRange.validate(mockFormControl)).toEqual({ minValue: true }); - range.end.setMonth(10); - expect(dateRange.validate(mockFormControl)).toEqual({ minValue: true, maxValue: true }); + range.end.setMonth(10); + expect(dateRange.validate(mockFormControl)).toEqual({ minValue: true, maxValue: true }); + }); }); it('should disable calendar dates when min and/or max values as dates are provided', () => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, mockInjector, null, overlay); - dateRange.ngOnInit(); - - spyOnProperty((dateRange as any), 'calendar').and.returnValue(mockCalendar); - dateRange.minValue = new Date(2000, 10, 1); - dateRange.maxValue = new Date(2000, 10, 20); - - dateRange.open({ - closeOnOutsideClick: true, - modal: false, - target: dateRange.element.nativeElement, - positionStrategy: new AutoPositionStrategy({ - openAnimation: null, - closeAnimation: null - }) + TestBed.runInInjectionContext(() => { + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, mockInjector, null, overlay); + dateRange.ngOnInit(); + + spyOnProperty((dateRange as any), 'calendar').and.returnValue(mockCalendar); + dateRange.minValue = new Date(2000, 10, 1); + dateRange.maxValue = new Date(2000, 10, 20); + + dateRange.open({ + closeOnOutsideClick: true, + modal: false, + target: dateRange.element.nativeElement, + positionStrategy: new AutoPositionStrategy({ + openAnimation: null, + closeAnimation: null + }) + }); + (dateRange as any).updateCalendar(); + expect(mockCalendar.disabledDates.length).toEqual(2); + expect(mockCalendar.disabledDates[0].type).toEqual(DateRangeType.Before); + expect(mockCalendar.disabledDates[0].dateRange[0]).toEqual(dateRange.minValue); + expect(mockCalendar.disabledDates[1].type).toEqual(DateRangeType.After); + expect(mockCalendar.disabledDates[1].dateRange[0]).toEqual(dateRange.maxValue); + expect(mockCalendar.daysView.focusActiveDate).toHaveBeenCalledTimes(1); }); - (dateRange as any).updateCalendar(); - expect(mockCalendar.disabledDates.length).toEqual(2); - expect(mockCalendar.disabledDates[0].type).toEqual(DateRangeType.Before); - expect(mockCalendar.disabledDates[0].dateRange[0]).toEqual(dateRange.minValue); - expect(mockCalendar.disabledDates[1].type).toEqual(DateRangeType.After); - expect(mockCalendar.disabledDates[1].dateRange[0]).toEqual(dateRange.maxValue); - expect(mockCalendar.daysView.focusActiveDate).toHaveBeenCalledTimes(1); }); it('should disable calendar dates when min and/or max values as strings are provided', fakeAsync(() => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en', platform, mockInjector, null, null, null); - dateRange.ngOnInit(); - - spyOnProperty((dateRange as any), 'calendar').and.returnValue(mockCalendar); - dateRange.minValue = '2000/10/1'; - dateRange.maxValue = '2000/10/30'; - - spyOn((dateRange as any).calendar, 'deselectDate').and.returnValue(null); - (dateRange as any).updateCalendar(); - expect((dateRange as any).calendar.disabledDates.length).toEqual(2); - expect((dateRange as any).calendar.disabledDates[0].type).toEqual(DateRangeType.Before); - expect((dateRange as any).calendar.disabledDates[0].dateRange[0]).toEqual(new Date(dateRange.minValue)); - expect((dateRange as any).calendar.disabledDates[1].type).toEqual(DateRangeType.After); - expect((dateRange as any).calendar.disabledDates[1].dateRange[0]).toEqual(new Date(dateRange.maxValue)); + TestBed.runInInjectionContext(() => { + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en', platform, mockInjector, null, null, null); + dateRange.ngOnInit(); + + spyOnProperty((dateRange as any), 'calendar').and.returnValue(mockCalendar); + dateRange.minValue = '2000/10/1'; + dateRange.maxValue = '2000/10/30'; + + spyOn((dateRange as any).calendar, 'deselectDate').and.returnValue(null); + (dateRange as any).updateCalendar(); + expect((dateRange as any).calendar.disabledDates.length).toEqual(2); + expect((dateRange as any).calendar.disabledDates[0].type).toEqual(DateRangeType.Before); + expect((dateRange as any).calendar.disabledDates[0].dateRange[0]).toEqual(new Date(dateRange.minValue)); + expect((dateRange as any).calendar.disabledDates[1].type).toEqual(DateRangeType.After); + expect((dateRange as any).calendar.disabledDates[1].dateRange[0]).toEqual(new Date(dateRange.maxValue)); + }); })); }); From 218439674383a3ae89827e287479b4b61189a1b1 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 16 Nov 2023 13:20:18 +0200 Subject: [PATCH 14/25] fix(density): use globalThis to resolve SSR issues --- projects/igniteui-angular/src/lib/core/density.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/density.ts b/projects/igniteui-angular/src/lib/core/density.ts index 08adf227c49..c7f0e38352a 100644 --- a/projects/igniteui-angular/src/lib/core/density.ts +++ b/projects/igniteui-angular/src/lib/core/density.ts @@ -118,7 +118,7 @@ export class DisplayDensityBase implements DoCheck, OnInit { } public get size() { - return document.defaultView + return globalThis.document.defaultView .getComputedStyle(this._host.nativeElement) .getPropertyValue('--ig-size') .trim(); From ffd308fe9182bbdad633456691a84491cf4ecdc2 Mon Sep 17 00:00:00 2001 From: Marin Popov Date: Tue, 21 Nov 2023 12:45:32 +0200 Subject: [PATCH 15/25] fix(chip): fix avatar inside igx-suffix and igx-prefix directive (#13696) Co-authored-by: Simeon Simeonoff --- .../styles/components/chip/_chip-theme.scss | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss index e625c74212e..9965aad8b9a 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss @@ -376,7 +376,6 @@ align-items: center; justify-content: center; text-align: center; - flex: 1 1 auto; height: var-get($theme, 'size'); padding-inline: sizable( map.get($chip-padding, 'compact'), @@ -411,9 +410,9 @@ igx-avatar, igx-circular-bar { - max-width: 100%; max-height: 100%; width: sizable(rem(14px), rem(18px), rem(24px)); + max-width: sizable(rem(14px), rem(18px), rem(24px)); height: sizable(rem(14px), rem(18px), rem(24px)); } @@ -655,21 +654,41 @@ } %igx-chip__start { - igx-avatar, - igx-circular-bar { + > igx-avatar, + > igx-circular-bar { &:first-child { margin-inline-start: calc(#{sizable(rem(0), rem(4px), rem(8px))} * -1); } } + + [igxPrefix], + igx-prefix { + &:first-of-type { + igx-avatar, + igx-circular-bar { + margin-inline-start: calc(#{sizable(rem(0), rem(4px), rem(8px))} * -1); + } + } + } } %igx-chip__end { - igx-avatar, - igx-circular-bar { + > igx-avatar, + > igx-circular-bar { &:last-child { margin-inline-end: calc(#{sizable(rem(0), rem(4px), rem(8px))} * -1); } } + + [igxPrefix], + igx-prefix { + &:first-of-type { + igx-avatar, + igx-circular-bar { + margin-inline-end: calc(#{sizable(rem(0), rem(4px), rem(8px))} * -1); + } + } + } } %igx-chip__start, @@ -694,8 +713,7 @@ %igx-chip__prefix, %igx-chip__suffix { - @include ellipsis(); - display: inline-block; + display: inline-flex; vertical-align: middle; max-width: $chip-max-width; From 607c642fc60d985f4670e5b5fbde145c57b5ff60 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Tue, 21 Nov 2023 12:54:30 +0200 Subject: [PATCH 16/25] refactor(density): further optimizations --- .../igniteui-angular/src/lib/core/density.ts | 19 ++++++++----------- .../igniteui-angular/src/lib/core/utils.ts | 4 ++-- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/density.ts b/projects/igniteui-angular/src/lib/core/density.ts index c7f0e38352a..30d9c694321 100644 --- a/projects/igniteui-angular/src/lib/core/density.ts +++ b/projects/igniteui-angular/src/lib/core/density.ts @@ -81,14 +81,6 @@ export class DisplayDensityBase implements DoCheck, OnInit { */ @Input() public get displayDensity(): DisplayDensity { - if (!this.size) { - return ( - this._displayDensity ?? - this.displayDensityOptions?.displayDensity ?? - DisplayDensity.comfortable - ); - } - switch (this.size) { case '1': return DisplayDensity.compact; @@ -96,7 +88,11 @@ export class DisplayDensityBase implements DoCheck, OnInit { return DisplayDensity.cosy; case '3': default: - return DisplayDensity.comfortable; + return ( + this._displayDensity ?? + this.displayDensityOptions?.displayDensity ?? + DisplayDensity.comfortable + ); } } @@ -118,7 +114,7 @@ export class DisplayDensityBase implements DoCheck, OnInit { } public get size() { - return globalThis.document.defaultView + return globalThis.document?.defaultView .getComputedStyle(this._host.nativeElement) .getPropertyValue('--ig-size') .trim(); @@ -131,7 +127,8 @@ export class DisplayDensityBase implements DoCheck, OnInit { protected oldDisplayDensityOptions: IDisplayDensityOptions = { displayDensity: DisplayDensity.comfortable, - }; + } + protected _displayDensity: DisplayDensity; constructor( diff --git a/projects/igniteui-angular/src/lib/core/utils.ts b/projects/igniteui-angular/src/lib/core/utils.ts index 20d6975e38b..a034866ff64 100644 --- a/projects/igniteui-angular/src/lib/core/utils.ts +++ b/projects/igniteui-angular/src/lib/core/utils.ts @@ -573,11 +573,11 @@ export const formatCurrency = new CurrencyPipe(undefined).transform; /** Converts pixel values to their rem counterparts for a base value */ export const rem = (value: number | string) => { - const base = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--ig-base-font-size')) + const base = parseFloat(getComputedStyle(globalThis.document?.documentElement).getPropertyValue('--ig-base-font-size')) return Number(value) / base; } /** Get the size of the component as derived from the CSS size variable */ export function getComponentSize(el: Element) { - return window.getComputedStyle(el).getPropertyValue('--component-size'); + return globalThis.window?.getComputedStyle(el).getPropertyValue('--component-size'); } From 4fe76bdb0fe7a03d0c974d45abc64005d9778d1e Mon Sep 17 00:00:00 2001 From: Konstantin Dinev Date: Tue, 21 Nov 2023 15:00:21 +0200 Subject: [PATCH 17/25] chore(*): resolving incorrect merge --- projects/igniteui-angular/src/lib/core/density.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/density.ts b/projects/igniteui-angular/src/lib/core/density.ts index e7449deab5c..c19487da12b 100644 --- a/projects/igniteui-angular/src/lib/core/density.ts +++ b/projects/igniteui-angular/src/lib/core/density.ts @@ -11,8 +11,6 @@ import { ElementRef, } from '@angular/core'; import { IBaseEventArgs, mkenum } from './utils'; -import { inject } from './inject'; -import { DOCUMENT } from '@angular/common'; /** * Defines the possible values of the components' display density. @@ -66,7 +64,6 @@ export const DisplayDensityToken = new InjectionToken( }) // eslint-disable-next-line @angular-eslint/directive-class-suffix export class DisplayDensityBase implements DoCheck, OnInit { - private _document: Document; @Output() public densityChanged = new EventEmitter(); @@ -142,7 +139,6 @@ export class DisplayDensityBase implements DoCheck, OnInit { protected _host: ElementRef ) { Object.assign(this.oldDisplayDensityOptions, displayDensityOptions); - this._document = inject(DOCUMENT); } /** From 215c0d0562a2a0c915a5afc3b5f4454b7df59372 Mon Sep 17 00:00:00 2001 From: Konstantin Dinev Date: Tue, 21 Nov 2023 15:33:12 +0200 Subject: [PATCH 18/25] chore(*): removing ssr-test and making demos-dev ssr --- angular.json | 124 +------ .../src/lib/tabs/tabs/tabs.component.spec.ts | 1 - projects/ssr-test/src/app/app.component.html | 7 - projects/ssr-test/src/app/app.component.scss | 0 .../ssr-test/src/app/app.component.spec.ts | 29 -- projects/ssr-test/src/app/app.component.ts | 14 - projects/ssr-test/src/app/app.config.ts | 9 - projects/ssr-test/src/app/app.routes.ts | 3 - projects/ssr-test/src/assets/.gitkeep | 0 projects/ssr-test/src/favicon.ico | Bin 15086 -> 0 bytes projects/ssr-test/src/index.html | 13 - projects/ssr-test/src/main.ts | 6 - projects/ssr-test/src/styles.scss | 27 -- projects/ssr-test/tsconfig.app.json | 30 -- projects/ssr-test/tsconfig.spec.json | 14 - src/app/app.component.ts | 22 +- .../src => src}/app/app.config.server.ts | 0 src/app/app.config.ts | 24 ++ src/app/app.module.ts | 344 ------------------ src/app/{app.routing.ts => app.routes.ts} | 6 +- {projects/ssr-test/src => src}/main.server.ts | 0 src/main.ts | 27 +- {projects/ssr-test => src}/server.ts | 2 +- src/tsconfig.app.json | 23 +- 24 files changed, 75 insertions(+), 650 deletions(-) delete mode 100644 projects/ssr-test/src/app/app.component.html delete mode 100644 projects/ssr-test/src/app/app.component.scss delete mode 100644 projects/ssr-test/src/app/app.component.spec.ts delete mode 100644 projects/ssr-test/src/app/app.component.ts delete mode 100644 projects/ssr-test/src/app/app.config.ts delete mode 100644 projects/ssr-test/src/app/app.routes.ts delete mode 100644 projects/ssr-test/src/assets/.gitkeep delete mode 100644 projects/ssr-test/src/favicon.ico delete mode 100644 projects/ssr-test/src/index.html delete mode 100644 projects/ssr-test/src/main.ts delete mode 100644 projects/ssr-test/src/styles.scss delete mode 100644 projects/ssr-test/tsconfig.app.json delete mode 100644 projects/ssr-test/tsconfig.spec.json rename {projects/ssr-test/src => src}/app/app.config.server.ts (100%) create mode 100644 src/app/app.config.ts delete mode 100644 src/app/app.module.ts rename src/app/{app.routing.ts => app.routes.ts} (99%) rename {projects/ssr-test/src => src}/main.server.ts (100%) rename {projects/ssr-test => src}/server.ts (97%) diff --git a/angular.json b/angular.json index e10e6ffa784..04e8f333210 100644 --- a/angular.json +++ b/angular.json @@ -15,12 +15,19 @@ }, "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/igniteui-dev-demos", "index": "src/index.html", - "main": "src/main.ts", - "polyfills": "src/polyfills.ts", + "browser": "src/main.ts", + "server": "src/main.server.ts", + "ssr": { + "entry": "src/server.ts" + }, + "polyfills": [ + "zone.js", + "hammerjs" + ], "tsConfig": "src/tsconfig.app.json", "assets": [ "src/favicon.ico", @@ -31,9 +38,7 @@ "src/styles/styles.scss" ], "scripts": [], - "vendorChunk": true, "extractLicenses": false, - "buildOptimizer": false, "sourceMap": true, "optimization": false, "namedChunks": true, @@ -62,10 +67,7 @@ "outputHashing": "all", "sourceMap": false, "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "aot": true + "extractLicenses": true }, "hmr": { "budgets": [ @@ -335,110 +337,6 @@ } } } - }, - "ssr-test": { - "projectType": "application", - "schematics": { - "@schematics/angular:component": { - "style": "scss" - } - }, - "root": "projects/ssr-test", - "sourceRoot": "projects/ssr-test/src", - "prefix": "app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:application", - "options": { - "outputPath": "dist/ssr-test", - "index": "projects/ssr-test/src/index.html", - "browser": "projects/ssr-test/src/main.ts", - "polyfills": [ - "zone.js" - ], - "tsConfig": "projects/ssr-test/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "projects/ssr-test/src/favicon.ico", - "projects/ssr-test/src/assets" - ], - "styles": [ - "projects/ssr-test/src/styles.scss" - ], - "scripts": [], - "server": "projects/ssr-test/src/main.server.ts", - "prerender": true, - "ssr": { - "entry": "projects/ssr-test/server.ts" - }, - "stylePreprocessorOptions": { - "includePaths": [ - "node_modules" - ] - } - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "ssr-test:build:production" - }, - "development": { - "buildTarget": "ssr-test:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "ssr-test:build" - } - }, - "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "polyfills": [ - "zone.js", - "zone.js/testing" - ], - "tsConfig": "projects/ssr-test/tsconfig.spec.json", - "inlineStyleLanguage": "scss", - "assets": [ - "projects/ssr-test/src/favicon.ico", - "projects/ssr-test/src/assets" - ], - "styles": [ - "projects/ssr-test/src/styles.scss" - ], - "scripts": [] - } - } - } } }, "cli": { diff --git a/projects/igniteui-angular/src/lib/tabs/tabs/tabs.component.spec.ts b/projects/igniteui-angular/src/lib/tabs/tabs/tabs.component.spec.ts index 97dbc69f6ea..70bc11fc87c 100644 --- a/projects/igniteui-angular/src/lib/tabs/tabs/tabs.component.spec.ts +++ b/projects/igniteui-angular/src/lib/tabs/tabs/tabs.component.spec.ts @@ -45,7 +45,6 @@ describe('IgxTabs', () => { ]; TestBed.configureTestingModule({ - declarations: [], imports: [ NoopAnimationsModule, RouterTestingModule.withRoutes(testRoutes), diff --git a/projects/ssr-test/src/app/app.component.html b/projects/ssr-test/src/app/app.component.html deleted file mode 100644 index 89b757a491d..00000000000 --- a/projects/ssr-test/src/app/app.component.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/projects/ssr-test/src/app/app.component.scss b/projects/ssr-test/src/app/app.component.scss deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/projects/ssr-test/src/app/app.component.spec.ts b/projects/ssr-test/src/app/app.component.spec.ts deleted file mode 100644 index 71cbadabe23..00000000000 --- a/projects/ssr-test/src/app/app.component.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [AppComponent], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have the 'ssr-test' title`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('ssr-test'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain('Hello, ssr-test'); - }); -}); diff --git a/projects/ssr-test/src/app/app.component.ts b/projects/ssr-test/src/app/app.component.ts deleted file mode 100644 index 65b44458af4..00000000000 --- a/projects/ssr-test/src/app/app.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; -import { IGX_LIST_DIRECTIVES, IgxNavbarComponent } from 'igniteui-angular'; - -@Component({ - selector: 'app-root', - standalone: true, - imports: [RouterOutlet, IgxNavbarComponent, IGX_LIST_DIRECTIVES], - templateUrl: './app.component.html', - styleUrl: './app.component.scss' -}) -export class AppComponent { - title = 'ssr-test'; -} diff --git a/projects/ssr-test/src/app/app.config.ts b/projects/ssr-test/src/app/app.config.ts deleted file mode 100644 index e5a3cf10050..00000000000 --- a/projects/ssr-test/src/app/app.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ApplicationConfig } from '@angular/core'; -import { provideRouter } from '@angular/router'; - -import { routes } from './app.routes'; -import { provideClientHydration } from '@angular/platform-browser'; - -export const appConfig: ApplicationConfig = { - providers: [provideRouter(routes), provideClientHydration()] -}; diff --git a/projects/ssr-test/src/app/app.routes.ts b/projects/ssr-test/src/app/app.routes.ts deleted file mode 100644 index dc39edb5f23..00000000000 --- a/projects/ssr-test/src/app/app.routes.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Routes } from '@angular/router'; - -export const routes: Routes = []; diff --git a/projects/ssr-test/src/assets/.gitkeep b/projects/ssr-test/src/assets/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/projects/ssr-test/src/favicon.ico b/projects/ssr-test/src/favicon.ico deleted file mode 100644 index 57614f9c967596fad0a3989bec2b1deff33034f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmd^G33O9Omi+`8$@{|M-I6TH3wzF-p5CV8o}7f~KxR60LK+ApEFB<$bcciv%@SmA zV{n>g85YMFFeU*Uvl=i4v)C*qgnb;$GQ=3XTe9{Y%c`mO%su)noNCCQ*@t1WXn|B(hQ7i~ zrUK8|pUkD6#lNo!bt$6)jR!&C?`P5G(`e((P($RaLeq+o0Vd~f11;qB05kdbAOm?r zXv~GYr_sibQO9NGTCdT;+G(!{4Xs@4fPak8#L8PjgJwcs-Mm#nR_Z0s&u?nDX5^~@ z+A6?}g0|=4e_LoE69pPFO`yCD@BCjgKpzMH0O4Xs{Ahc?K3HC5;l=f zg>}alhBXX&);z$E-wai+9TTRtBX-bWYY@cl$@YN#gMd~tM_5lj6W%8ah4;uZ;jP@Q zVbuel1rPA?2@x9Y+u?e`l{Z4ngfG5q5BLH5QsEu4GVpt{KIp1?U)=3+KQ;%7ec8l* zdV=zZgN5>O3G(3L2fqj3;oBbZZw$Ij@`Juz@?+yy#OPw)>#wsTewVgTK9BGt5AbZ&?K&B3GVF&yu?@(Xj3fR3n+ZP0%+wo)D9_xp>Z$`A4 zfV>}NWjO#3lqumR0`gvnffd9Ka}JJMuHS&|55-*mCD#8e^anA<+sFZVaJe7{=p*oX zE_Uv?1>e~ga=seYzh{9P+n5<+7&9}&(kwqSaz;1aD|YM3HBiy<))4~QJSIryyqp| z8nGc(8>3(_nEI4n)n7j(&d4idW1tVLjZ7QbNLXg;LB ziHsS5pXHEjGJZb59KcvS~wv;uZR-+4qEqow`;JCfB*+b^UL^3!?;-^F%yt=VjU|v z39SSqKcRu_NVvz!zJzL0CceJaS6%!(eMshPv_0U5G`~!a#I$qI5Ic(>IONej@aH=f z)($TAT#1I{iCS4f{D2+ApS=$3E7}5=+y(rA9mM#;Cky%b*Gi0KfFA`ofKTzu`AV-9 znW|y@19rrZ*!N2AvDi<_ZeR3O2R{#dh1#3-d%$k${Rx42h+i&GZo5!C^dSL34*AKp z27mTd>k>?V&X;Nl%GZ(>0s`1UN~Hfyj>KPjtnc|)xM@{H_B9rNr~LuH`Gr5_am&Ep zTjZA8hljNj5H1Ipm-uD9rC}U{-vR!eay5&6x6FkfupdpT*84MVwGpdd(}ib)zZ3Ky z7C$pnjc82(W_y_F{PhYj?o!@3__UUvpX)v69aBSzYj3 zdi}YQkKs^SyXyFG2LTRz9{(w}y~!`{EuAaUr6G1M{*%c+kP1olW9z23dSH!G4_HSK zzae-DF$OGR{ofP*!$a(r^5Go>I3SObVI6FLY)N@o<*gl0&kLo-OT{Tl*7nCz>Iq=? zcigIDHtj|H;6sR?or8Wd_a4996GI*CXGU}o;D9`^FM!AT1pBY~?|4h^61BY#_yIfO zKO?E0 zJ{Pc`9rVEI&$xxXu`<5E)&+m(7zX^v0rqofLs&bnQT(1baQkAr^kEsk)15vlzAZ-l z@OO9RF<+IiJ*O@HE256gCt!bF=NM*vh|WVWmjVawcNoksRTMvR03H{p@cjwKh(CL4 z7_PB(dM=kO)!s4fW!1p0f93YN@?ZSG` z$B!JaAJCtW$B97}HNO9(x-t30&E}Mo1UPi@Av%uHj~?T|!4JLwV;KCx8xO#b9IlUW zI6+{a@Wj|<2Y=U;a@vXbxqZNngH8^}LleE_4*0&O7#3iGxfJ%Id>+sb;7{L=aIic8 z|EW|{{S)J-wr@;3PmlxRXU8!e2gm_%s|ReH!reFcY8%$Hl4M5>;6^UDUUae?kOy#h zk~6Ee_@ZAn48Bab__^bNmQ~+k=02jz)e0d9Z3>G?RGG!65?d1>9}7iG17?P*=GUV-#SbLRw)Hu{zx*azHxWkGNTWl@HeWjA?39Ia|sCi{e;!^`1Oec zb>Z|b65OM*;eC=ZLSy?_fg$&^2xI>qSLA2G*$nA3GEnp3$N-)46`|36m*sc#4%C|h zBN<2U;7k>&G_wL4=Ve5z`ubVD&*Hxi)r@{4RCDw7U_D`lbC(9&pG5C*z#W>8>HU)h z!h3g?2UL&sS!oY5$3?VlA0Me9W5e~V;2jds*fz^updz#AJ%G8w2V}AEE?E^=MK%Xt z__Bx1cr7+DQmuHmzn*|hh%~eEc9@m05@clWfpEFcr+06%0&dZJH&@8^&@*$qR@}o3 z@Tuuh2FsLz^zH+dN&T&?0G3I?MpmYJ;GP$J!EzjeM#YLJ!W$}MVNb0^HfOA>5Fe~UNn%Zk(PT@~9}1dt)1UQ zU*B5K?Dl#G74qmg|2>^>0WtLX#Jz{lO4NT`NYB*(L#D|5IpXr9v&7a@YsGp3vLR7L zHYGHZg7{ie6n~2p$6Yz>=^cEg7tEgk-1YRl%-s7^cbqFb(U7&Dp78+&ut5!Tn(hER z|Gp4Ed@CnOPeAe|N>U(dB;SZ?NU^AzoD^UAH_vamp6Ws}{|mSq`^+VP1g~2B{%N-!mWz<`)G)>V-<`9`L4?3dM%Qh6<@kba+m`JS{Ya@9Fq*m6$$ zA1%Ogc~VRH33|S9l%CNb4zM%k^EIpqY}@h{w(aBcJ9c05oiZx#SK9t->5lSI`=&l~ z+-Ic)a{FbBhXV$Xt!WRd`R#Jk-$+_Z52rS>?Vpt2IK<84|E-SBEoIw>cs=a{BlQ7O z-?{Fy_M&84&9|KM5wt~)*!~i~E=(6m8(uCO)I=)M?)&sRbzH$9Rovzd?ZEY}GqX+~ zFbEbLz`BZ49=2Yh-|<`waK-_4!7`ro@zlC|r&I4fc4oyb+m=|c8)8%tZ-z5FwhzDt zL5kB@u53`d@%nHl0Sp)Dw`(QU&>vujEn?GPEXUW!Wi<+4e%BORl&BIH+SwRcbS}X@ z01Pk|vA%OdJKAs17zSXtO55k!;%m9>1eW9LnyAX4uj7@${O6cfii`49qTNItzny5J zH&Gj`e}o}?xjQ}r?LrI%FjUd@xflT3|7LA|ka%Q3i}a8gVm<`HIWoJGH=$EGClX^C0lysQJ>UO(q&;`T#8txuoQ_{l^kEV9CAdXuU1Ghg8 zN_6hHFuy&1x24q5-(Z7;!poYdt*`UTdrQOIQ!2O7_+AHV2hgXaEz7)>$LEdG z<8vE^Tw$|YwZHZDPM!SNOAWG$?J)MdmEk{U!!$M#fp7*Wo}jJ$Q(=8>R`Ats?e|VU?Zt7Cdh%AdnfyN3MBWw{ z$OnREvPf7%z6`#2##_7id|H%Y{vV^vWXb?5d5?a_y&t3@p9t$ncHj-NBdo&X{wrfJ zamN)VMYROYh_SvjJ=Xd!Ga?PY_$;*L=SxFte!4O6%0HEh%iZ4=gvns7IWIyJHa|hT z2;1+e)`TvbNb3-0z&DD_)Jomsg-7p_Uh`wjGnU1urmv1_oVqRg#=C?e?!7DgtqojU zWoAB($&53;TsXu^@2;8M`#z{=rPy?JqgYM0CDf4v@z=ZD|ItJ&8%_7A#K?S{wjxgd z?xA6JdJojrWpB7fr2p_MSsU4(R7=XGS0+Eg#xR=j>`H@R9{XjwBmqAiOxOL` zt?XK-iTEOWV}f>Pz3H-s*>W z4~8C&Xq25UQ^xH6H9kY_RM1$ch+%YLF72AA7^b{~VNTG}Tj#qZltz5Q=qxR`&oIlW Nr__JTFzvMr^FKp4S3v*( diff --git a/projects/ssr-test/src/index.html b/projects/ssr-test/src/index.html deleted file mode 100644 index 51c80953643..00000000000 --- a/projects/ssr-test/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - SsrTest - - - - - - - - diff --git a/projects/ssr-test/src/main.ts b/projects/ssr-test/src/main.ts deleted file mode 100644 index 35b00f34633..00000000000 --- a/projects/ssr-test/src/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig) - .catch((err) => console.error(err)); diff --git a/projects/ssr-test/src/styles.scss b/projects/ssr-test/src/styles.scss deleted file mode 100644 index a3f2bcdd548..00000000000 --- a/projects/ssr-test/src/styles.scss +++ /dev/null @@ -1,27 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ -@use '../../igniteui-angular/src/lib/core/styles/themes' as *; - -$primary: #fff; -$secondary: #FF0A3A; -$gray: #ddd; -$background: #fff; - -$app-palette: palette( - $primary: $primary, - $secondary: $secondary, - $surface: $background, - $gray: $gray -); - -@include core(); -@include typography(); - -$include: ( - igx-list, - igx-navbar -); - -@include light-theme( - $palette: $app-palette, - $exclude: map-keys(map-remove($components, $include...),) -);/* You can add global styles to this file, and also import other style files */ diff --git a/projects/ssr-test/tsconfig.app.json b/projects/ssr-test/tsconfig.app.json deleted file mode 100644 index 5e370729994..00000000000 --- a/projects/ssr-test/tsconfig.app.json +++ /dev/null @@ -1,30 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/app", - "types": [ - "node" - ], - "paths": { - "igniteui-angular": [ - "dist/igniteui-angular" - ], - "igniteui-angular/*": [ - "dist/igniteui-angular/*" - ], - "igniteui-angular-i18n": [ - "dist/igniteui-angular-i18n" - ] - }, - "allowSyntheticDefaultImports": true - }, - "files": [ - "src/main.ts", - "src/main.server.ts", - "server.ts" - ], - "include": [ - "src/**/*.d.ts" - ] -} diff --git a/projects/ssr-test/tsconfig.spec.json b/projects/ssr-test/tsconfig.spec.json deleted file mode 100644 index a9c0752ffe5..00000000000 --- a/projects/ssr-test/tsconfig.spec.json +++ /dev/null @@ -1,14 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": [ - "jasmine" - ] - }, - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f65507e5083..1163364b5ff 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,12 +1,30 @@ import { Component, OnInit, ViewChild, HostBinding } from '@angular/core'; -import { Router, NavigationStart, NavigationEnd } from '@angular/router'; +import { Router, NavigationStart, NavigationEnd, RouterLinkActive, RouterLink, RouterOutlet } from '@angular/router'; import { filter } from 'rxjs/operators'; import { IgxNavigationDrawerComponent, IgxIconService } from 'igniteui-angular'; +import { PageHeaderComponent } from './pageHeading/pageHeading.component'; +import { IgxIconComponent } from '../../projects/igniteui-angular/src/lib/icon/icon.component'; +import { NgFor, NgIf } from '@angular/common'; +import { IgxNavDrawerTemplateDirective, IgxNavDrawerItemDirective, IgxNavDrawerMiniTemplateDirective } from '../../projects/igniteui-angular/src/lib/navigation-drawer/navigation-drawer.directives'; @Component({ selector: 'app-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'] + styleUrls: ['./app.component.scss'], + standalone: true, + imports: [ + IgxNavigationDrawerComponent, + IgxNavDrawerTemplateDirective, + IgxNavDrawerItemDirective, + NgFor, + RouterLinkActive, + RouterLink, + IgxIconComponent, + NgIf, + IgxNavDrawerMiniTemplateDirective, + PageHeaderComponent, + RouterOutlet + ] }) export class AppComponent implements OnInit { @HostBinding('attr.id') diff --git a/projects/ssr-test/src/app/app.config.server.ts b/src/app/app.config.server.ts similarity index 100% rename from projects/ssr-test/src/app/app.config.server.ts rename to src/app/app.config.server.ts diff --git a/src/app/app.config.ts b/src/app/app.config.ts new file mode 100644 index 00000000000..3464d4323dc --- /dev/null +++ b/src/app/app.config.ts @@ -0,0 +1,24 @@ +import { HTTP_INTERCEPTORS, provideHttpClient, withFetch, withInterceptorsFromDi } from '@angular/common/http'; +import { ApplicationConfig, importProvidersFrom } from '@angular/core'; +import { DisplayDensity, DisplayDensityToken } from 'igniteui-angular'; +import { TestInterceptorClass } from './interceptor.service'; +import { provideAnimations } from '@angular/platform-browser/animations'; +import { HammerModule, provideClientHydration } from '@angular/platform-browser'; +import { provideRouter } from '@angular/router'; +import { appRoutes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + importProvidersFrom(HammerModule), + { provide: DisplayDensityToken, useFactory: () => ({ displayDensity: DisplayDensity.comfortable }) }, + { + provide: HTTP_INTERCEPTORS, + useClass: TestInterceptorClass, + multi: true + }, + provideAnimations(), + provideHttpClient(withInterceptorsFromDi(), withFetch()), + provideClientHydration(), + provideRouter(appRoutes) + ] +}; diff --git a/src/app/app.module.ts b/src/app/app.module.ts deleted file mode 100644 index 96f18fa451a..00000000000 --- a/src/app/app.module.ts +++ /dev/null @@ -1,344 +0,0 @@ -import { TreeGridAddRowSampleComponent } from './tree-grid-add-row/tree-grid-add-row.sample'; -import { BrowserModule, HammerModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { NgModule } from '@angular/core'; -import { IgxOverlayService, IgxIconService, DisplayDensityToken, DisplayDensity, IgxNavigationDrawerComponent, IgxNavDrawerItemDirective, IgxIconComponent, IgxNavDrawerMiniTemplateDirective, IgxNavDrawerTemplateDirective } from 'igniteui-angular'; - -import { routing } from './app.routing'; -import { ActionStripSampleComponent } from './action-strip/action-strip.sample'; -import { AppComponent } from './app.component'; -import { AvatarSampleComponent } from './avatar/avatar.sample'; -import { PageHeaderComponent } from './pageHeading/pageHeading.component'; -import { BadgeSampleComponent } from './badge/badge.sample'; -import { ButtonSampleComponent } from './button/button.sample'; -import { CalendarSampleComponent } from './calendar/calendar.sample'; -import { CardSampleComponent } from './card/card.sample'; -import { CarouselSampleComponent } from './carousel/carousel.sample'; -import { ChipsSampleComponent } from './chips/chips.sample'; -import { DatePickerSampleComponent } from './date-picker/date-picker.sample'; -import { DialogSampleComponent } from './dialog/dialog.sample'; -import { DragDropSampleComponent } from './drag-drop/drag-drop.sample'; -import { ShadowGridSampleComponent } from './drag-drop/shadow-dom-grid/shadow-grid-sample'; -import { MaskSampleComponent, DisplayFormatPipe, InputFormatPipe } from './mask/mask.sample'; -import { IconSampleComponent } from './icon/icon.sample'; -import { InputSampleComponent } from './input/input.sample'; -import { InputGroupSampleComponent } from './input-group/input-group.sample'; -import { LayoutSampleComponent } from './layout/layout.sample'; -import { ListSampleComponent } from './list/list.sample'; -import { ListPanningSampleComponent } from './list-panning/list-panning.sample'; -import { ListPerformanceSampleComponent } from './list-performance/list-performance.sample'; -import { NavbarSampleComponent } from './navbar/navbar.sample'; -import { NavdrawerSampleComponent } from './navdrawer/navdrawer.sample'; -import { ProgressbarSampleComponent } from './progressbar/progressbar.sample'; -import { RippleSampleComponent } from './ripple/ripple.sample'; -import { SliderSampleComponent } from './slider/slider.sample'; -import { SplitterSampleComponent } from './splitter/splitter.sample'; -import { SnackbarSampleComponent } from './snackbar/snackbar.sample'; -import { ColorsSampleComponent } from './styleguide/colors/color.sample'; -import { ShadowsSampleComponent } from './styleguide/shadows/shadows.sample'; -import { TypographySampleComponent } from './styleguide/typography/typography.sample'; -import { BottomNavSampleComponent, CustomContentComponent } from './bottomnav/bottomnav.sample'; -import { BottomNavRoutingSampleComponent } from './bottomnav-routing/bottomnav-routing.sample'; -import { - BottomNavRoutingView1Component, - BottomNavRoutingView2Component, - BottomNavRoutingView3Component -} from './bottomnav-routing/bottomnav-routing-views.sample'; -import { TabsSampleComponent } from './tabs/tabs.sample'; -import { TabsRoutingSampleComponent } from './tabs-routing/tabs-routing.sample'; -import { - TabsRoutingView1Component, - TabsRoutingView2Component, - TabsRoutingView3Component -} from './tabs-routing/tabs-routing-views.sample'; -import { TimePickerSampleComponent } from './time-picker/time-picker.sample'; -import { ToastSampleComponent } from './toast/toast.sample'; -import { RemoteService } from './shared/remote.service'; -import { VirtualForSampleComponent } from './virtual-for-directive/virtual-for.sample'; -import { LocalService } from './shared/local.service'; -import { GridCellEditingComponent } from './grid-cellEditing/grid-cellEditing.component'; -import { GridSampleComponent } from './grid/grid.sample'; -import { GridColumnMovingSampleComponent } from './grid-column-moving/grid-column-moving.sample'; -import { GridColumnPinningSampleComponent } from './grid-column-pinning/grid-column-pinning.sample'; -import { GridColumnResizingSampleComponent } from './grid-column-resizing/grid-column-resizing.sample'; -import { GridSummaryComponent } from './grid-summaries/grid-summaries.sample'; -import { GridPerformanceSampleComponent } from './grid-performance/grid-performance.sample'; -import { GridRemotePagingSampleComponent } from './grid-remote-paging/grid-remote-paging.sample'; -import { GridSelectionComponent } from './grid-selection/grid-selection.sample'; -import { GridRowDraggableComponent } from './grid-row-draggable/grid-row-draggable.sample'; -import { GridRowReorderComponent } from './grid-row-reorder/grid-row-reorder.sample'; -import { GridToolbarSampleComponent } from './grid-toolbar/grid-toolbar.sample'; -import { GridToolbarCustomSampleComponent } from './grid-toolbar/grid-toolbar-custom.sample'; -import { GridVirtualizationSampleComponent } from './grid-remote-virtualization/grid-remote-virtualization.sample'; -import { ButtonGroupSampleComponent } from './buttonGroup/buttonGroup.sample'; -import { GridColumnGroupsSampleComponent } from './grid-column-groups/grid-column-groups.sample'; -import { GridCellStylingSampleComponent } from './gird-cell-styling/grid-cell-styling.sample'; -import { GridGroupBySampleComponent } from './grid-groupby/grid-groupby.sample'; -import { DropDownSampleComponent } from './drop-down/drop-down.sample'; -import { DisplayDensityDropDownComponent } from './drop-down/display-density/display-density.sample'; -import { DropDownVirtualComponent } from './drop-down/drop-down-virtual/drop-down-virtual.component'; -import { ComboSampleComponent } from './combo/combo.sample'; -import { OverlaySampleComponent } from './overlay/overlay.sample'; -import { OverlayAnimationSampleComponent } from './overlay/overlay-animation.sample'; -import { OverlayPresetsSampleComponent } from './overlay/overlay-presets.sample'; -import { RadioSampleComponent } from './radio/radio.sample'; -import { TooltipSampleComponent } from './tooltip/tooltip.sample'; -import { ExpansionPanelSampleComponent } from './expansion-panel/expansion-panel-sample'; -import { GridRowEditSampleComponent } from './grid-row-edit/grid-row-edit-sample.component'; -import { TreeGridSampleComponent } from './tree-grid/tree-grid.sample'; -import { TreeGridFlatDataSampleComponent } from './tree-grid-flat-data/tree-grid-flat-data.sample'; -import { HierarchicalGridSampleComponent } from './hierarchical-grid/hierarchical-grid.sample'; -import { HierarchicalGridRemoteSampleComponent } from './hierarchical-grid-remote/hierarchical-grid-remote.sample'; -import { HierarchicalGridUpdatingSampleComponent } from './hierarchical-grid-updating/hierarchical-grid-updating.sample'; -import { GridColumnPercentageWidthsSampleComponent } from './grid-percentage-columns/grid-percantge-widths.sample'; -import { BannerSampleComponent } from './banner/banner.sample'; -import { CalendarViewsSampleComponent } from './calendar-views/calendar-views.sample'; -import { SelectSampleComponent } from './select/select.sample'; -import { GridSearchBoxComponent } from './grid-search-box/grid-search-box.component'; -import { GridSearchComponent } from './grid-search/grid-search.sample'; -import { AutocompleteSampleComponent, AutocompletePipeContains, AutocompleteGroupPipeContains } from './autocomplete/autocomplete.sample'; -import { GridMRLSampleComponent } from './grid-multi-row-layout/grid-mrl.sample'; -import { TreeGridLoadOnDemandSampleComponent } from './tree-grid-load-on-demand/tree-grid-load-on-demand.sample'; -import { GridFilterTemplateSampleComponent } from './grid-filter-template/grid-filter-template.sample'; -import { GridMRLConfigSampleComponent } from './grid-multi-row-layout-config/grid-mrl-config.sample'; -import { GridMRLCustomNavigationSampleComponent } from './grid-mrl-custom-navigation/grid-mrl-custom-navigation'; -import { GridClipboardSampleComponent } from './grid-clipboard/grid-clipboard.sample'; -import { GridAutoSizeSampleComponent } from './grid-auto-size/grid-auto-size.sample'; -import { GridFlexSampleComponent } from './grid-flex-layout/grid-flex.sample'; -import { GridEsfLoadOnDemandComponent } from './grid-esf-load-on-demand/grid-esf-load-on-demand.component'; -import { GridFilteringComponent } from './grid-filtering/grid-filtering.sample'; -import { GridExternalFilteringComponent } from './grid-external-filtering/grid-external-filtering.sample'; -import { AboutComponent } from './grid-state/about.component'; -import { GridSaveStateComponent } from './grid-state/grid-state.component'; -import { GridMasterDetailSampleComponent } from './grid-master-detail/grid-master-detail.sample'; -import { DateTimeEditorSampleComponent } from './date-time-editor/date-time-editor.sample'; -import { GridColumnSelectionSampleComponent, GridColumnSelectionFilterPipe } from './grid-column-selection/grid-column-selection.sample'; -import { ReactiveFormSampleComponent } from './reactive-from/reactive-form-sample.component'; -import { GridRowPinningSampleComponent } from './grid-row-pinning/grid-row-pinning.sample'; -import { DateRangeSampleComponent } from './date-range/date-range.sample'; -import { - HierarchicalGridRemoteVirtualizationComponent -} from './hierarchical-grid-remote-virtualization/hierarchical-grid-remote-virtualization'; -import { HierarchicalRemoteService } from './hierarchical-grid-remote-virtualization/hierarchical-remote.service'; -import { GridVirtualizationScrollSampleComponent } from './grid-remote-virtualization-with-scroll/grid-remote-virtualization-scroll.sample'; -import { GridNestedPropsSampleComponent } from './grid-nested-props/grid-nested-props.sample'; -import { GridColumnActionsSampleComponent } from './grid-column-actions/grid-column-actions.sample'; -import { IgxColumnGroupingDirective } from './grid-column-actions/custom-action-directive'; -import { GridAddRowSampleComponent } from './grid-add-row/grid-add-row.sample'; -import { HierarchicalGridAddRowSampleComponent } from './hierarchical-grid-add-row/hierarchical-grid-add-row.sample'; -import { AnimationsSampleComponent } from './styleguide/animations/animations.sample'; -import { GridFormattingComponent } from './grid-formatting/grid-formatting.component'; -import { GridFinJSComponent } from './grid-finjs/grid-finjs.component'; -import { MainComponent } from './grid-finjs/main.component'; -import { ControllerComponent } from './grid-finjs/controllers.component'; -import { CommonModule } from '@angular/common'; -import { GridEventsComponent } from './grid-events/grid-events.component'; - -import { GridRowAPISampleComponent } from './grid-row-api/grid-row-api.sample'; -import { GridUpdatesComponent } from './grid-updates-test/grid-updates.component'; -import { TestInterceptorClass } from './interceptor.service'; -import { TreeSampleComponent } from './tree/tree.sample'; -import { GridColumnTypesSampleComponent } from './grid-column-types/grid-column-types.sample'; -import { AccordionSampleComponent } from './accordion/accordion.sample'; -import { GridLocalizationSampleComponent } from './grid-localization/grid-localization.sample'; -import { TreeGridGroupBySampleComponent } from './tree-grid-groupby/tree-grid-groupby.sample'; -import { PaginationSampleComponent } from './pagination/pagination.component'; -import { GridCellAPISampleComponent } from './grid-cell-api/grid-cell-api.sample'; -import { PivotGridSampleComponent } from './pivot-grid/pivot-grid.sample'; -import { PivotGridHierarchySampleComponent } from './pivot-grid-hierarchy/pivot-grid-hierarchy.sample'; -import { PivotGridNoopSampleComponent } from './pivot-grid-noop/pivot-grid-noop.sample'; -import { IgxStepperSampleComponent } from './stepper/stepper.sample'; -import { RatingSampleComponent } from './rating/rating.sample'; -import { RangeSliderComponent } from './slider/range-slider/range-slider.component'; -import { QueryBuilderComponent } from './query-builder/query-builder.sample'; -import { PivotGridStateSampleComponent } from './pivot-grid-state/pivot-grid-state.sample'; -import { ForbiddenValidatorDirective, GridValidationSampleComponent } from './grid-validation/grid-validation.sample.component'; -import { GridExportComponent } from './grid-export/grid-export.sample'; -import { DividerComponent } from './divider/divider.component'; - -const components = [ - AccordionSampleComponent, - ActionStripSampleComponent, - AutocompletePipeContains, - AutocompleteGroupPipeContains, - AutocompleteSampleComponent, - AvatarSampleComponent, - BadgeSampleComponent, - BannerSampleComponent, - ButtonSampleComponent, - CalendarSampleComponent, - CardSampleComponent, - CarouselSampleComponent, - ExpansionPanelSampleComponent, - ChipsSampleComponent, - DialogSampleComponent, - DatePickerSampleComponent, - DropDownSampleComponent, - DisplayDensityDropDownComponent, - DropDownVirtualComponent, - DragDropSampleComponent, - ShadowGridSampleComponent, - ComboSampleComponent, - IconSampleComponent, - InputSampleComponent, - InputGroupSampleComponent, - LayoutSampleComponent, - ListSampleComponent, - ListPanningSampleComponent, - ListPerformanceSampleComponent, - MaskSampleComponent, - DateTimeEditorSampleComponent, - NavbarSampleComponent, - NavdrawerSampleComponent, - OverlaySampleComponent, - OverlayAnimationSampleComponent, - OverlayPresetsSampleComponent, - PageHeaderComponent, - PaginationSampleComponent, - ProgressbarSampleComponent, - RippleSampleComponent, - SelectSampleComponent, - SliderSampleComponent, - RangeSliderComponent, - SplitterSampleComponent, - SnackbarSampleComponent, - BottomNavSampleComponent, - BottomNavRoutingSampleComponent, - BottomNavRoutingView1Component, - BottomNavRoutingView2Component, - BottomNavRoutingView3Component, - TabsSampleComponent, - TabsRoutingSampleComponent, - TabsRoutingView1Component, - TabsRoutingView2Component, - TabsRoutingView3Component, - TimePickerSampleComponent, - ToastSampleComponent, - VirtualForSampleComponent, - ButtonGroupSampleComponent, - GridCellEditingComponent, - ForbiddenValidatorDirective, - GridSampleComponent, - GridAddRowSampleComponent, - HierarchicalGridAddRowSampleComponent, - TreeGridAddRowSampleComponent, - GridColumnMovingSampleComponent, - GridColumnSelectionSampleComponent, - GridColumnSelectionFilterPipe, - GridColumnPinningSampleComponent, - GridColumnActionsSampleComponent, - GridRowPinningSampleComponent, - GridRowAPISampleComponent, - GridCellAPISampleComponent, - GridColumnResizingSampleComponent, - GridGroupBySampleComponent, - GridMasterDetailSampleComponent, - GridSummaryComponent, - GridPerformanceSampleComponent, - GridSelectionComponent, - GridRowDraggableComponent, - GridRowReorderComponent, - GridToolbarSampleComponent, - GridToolbarCustomSampleComponent, - GridVirtualizationSampleComponent, - GridColumnGroupsSampleComponent, - GridMRLSampleComponent, - GridMRLConfigSampleComponent, - GridMRLCustomNavigationSampleComponent, - GridCellStylingSampleComponent, - GridRowEditSampleComponent, - GridValidationSampleComponent, - TreeGridSampleComponent, - TreeGridFlatDataSampleComponent, - TreeGridLoadOnDemandSampleComponent, - TreeGridGroupBySampleComponent, - CustomContentComponent, - ColorsSampleComponent, - AnimationsSampleComponent, - ShadowsSampleComponent, - TypographySampleComponent, - TreeSampleComponent, - RadioSampleComponent, - TooltipSampleComponent, - HierarchicalGridSampleComponent, - HierarchicalGridRemoteSampleComponent, - HierarchicalGridRemoteVirtualizationComponent, - HierarchicalGridUpdatingSampleComponent, - DisplayFormatPipe, - InputFormatPipe, - GridColumnPercentageWidthsSampleComponent, - CalendarViewsSampleComponent, - GridSearchBoxComponent, - GridSearchComponent, - GridFilterTemplateSampleComponent, - GridClipboardSampleComponent, - GridAutoSizeSampleComponent, - GridFlexSampleComponent, - GridEsfLoadOnDemandComponent, - GridFormattingComponent, - GridEventsComponent, - GridFilteringComponent, - GridFinJSComponent, - GridUpdatesComponent, - MainComponent, - ControllerComponent, - GridExternalFilteringComponent, - GridSaveStateComponent, - AboutComponent, - ReactiveFormSampleComponent, - DateRangeSampleComponent, - GridRemotePagingSampleComponent, - GridVirtualizationScrollSampleComponent, - GridNestedPropsSampleComponent, - IgxColumnGroupingDirective, - GridColumnTypesSampleComponent, - GridLocalizationSampleComponent, - PivotGridSampleComponent, - PivotGridHierarchySampleComponent, - PivotGridStateSampleComponent, - PivotGridNoopSampleComponent, - IgxStepperSampleComponent, - QueryBuilderComponent, - RatingSampleComponent, - GridExportComponent, - DividerComponent, -]; - -@NgModule({ - declarations: [AppComponent], - imports: [ - BrowserModule, - BrowserAnimationsModule, - HammerModule, - FormsModule, - CommonModule, - ReactiveFormsModule, - HttpClientModule, - PageHeaderComponent, - IgxNavigationDrawerComponent, - IgxNavDrawerItemDirective, - IgxNavDrawerMiniTemplateDirective, - IgxNavDrawerTemplateDirective, - IgxIconComponent, - routing, - HammerModule, - ...components - ], - providers: [ - LocalService, - RemoteService, - HierarchicalRemoteService, - IgxIconService, - IgxOverlayService, - { provide: DisplayDensityToken, useFactory: () => ({ displayDensity: DisplayDensity.comfortable }) }, - { - provide: HTTP_INTERCEPTORS, - useClass: TestInterceptorClass, - multi: true - } - ], - bootstrap: [AppComponent] -}) -export class AppModule { } diff --git a/src/app/app.routing.ts b/src/app/app.routes.ts similarity index 99% rename from src/app/app.routing.ts rename to src/app/app.routes.ts index 916160ea595..6cf70620089 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routes.ts @@ -1,5 +1,5 @@ import { TreeGridAddRowSampleComponent } from './tree-grid-add-row/tree-grid-add-row.sample'; -import { RouterModule, Routes } from '@angular/router'; +import { Routes } from '@angular/router'; import { AvatarSampleComponent } from './avatar/avatar.sample'; import { BadgeSampleComponent } from './badge/badge.sample'; import { ButtonSampleComponent } from './button/button.sample'; @@ -138,7 +138,7 @@ import { GridValidationSampleComponent } from './grid-validation/grid-validation import { GridExportComponent } from './grid-export/grid-export.sample'; import { DividerComponent } from './divider/divider.component'; -const appRoutes: Routes = [ +export const appRoutes: Routes = [ { path: '', pathMatch: 'full', @@ -661,5 +661,3 @@ const appRoutes: Routes = [ component: StepperSampleComponent } ]; - -export const routing = RouterModule.forRoot(appRoutes, {}); diff --git a/projects/ssr-test/src/main.server.ts b/src/main.server.ts similarity index 100% rename from projects/ssr-test/src/main.server.ts rename to src/main.server.ts diff --git a/src/main.ts b/src/main.ts index ba12930b3ee..a544bbda38b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,12 @@ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; - -import { AppModule } from './app/app.module'; -import { environment } from './environments/environment'; - -import { hmrBootstrap } from './hmr'; import { registerLocaleData } from '@angular/common'; import localeFr from '@angular/common/locales/fr'; import localeDe from '@angular/common/locales/de'; import localeJa from '@angular/common/locales/ja'; import localeBb from '@angular/common/locales/bg'; import localeZh from '@angular/common/locales/zh'; +import { AppComponent } from './app/app.component'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; registerLocaleData(localeFr); registerLocaleData(localeDe); @@ -18,19 +14,4 @@ registerLocaleData(localeJa); registerLocaleData(localeBb); registerLocaleData(localeZh); -if (environment.production) { - enableProdMode(); -} - -const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); - -if (environment.hmr) { - if (module['hot']) { - hmrBootstrap(module, bootstrap); - } else { - console.error('HMR is not enabled for webpack-dev-server!'); - console.log('Are you using the --hmr flag for ng serve?'); - } -} else { - bootstrap().catch(err => console.log(err)); -} +bootstrapApplication(AppComponent, appConfig).catch(err => console.log(err)); diff --git a/projects/ssr-test/server.ts b/src/server.ts similarity index 97% rename from projects/ssr-test/server.ts rename to src/server.ts index 7083b14fe9d..9ac625a6446 100644 --- a/projects/ssr-test/server.ts +++ b/src/server.ts @@ -3,7 +3,7 @@ import { CommonEngine } from '@angular/ssr'; import express from 'express'; import { fileURLToPath } from 'node:url'; import { dirname, join, resolve } from 'node:path'; -import bootstrap from './src/main.server'; +import bootstrap from './main.server'; // The Express app is exported so that it can be used by serverless Functions. export function app(): express.Express { diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json index 232ae545a52..4bbf997c933 100644 --- a/src/tsconfig.app.json +++ b/src/tsconfig.app.json @@ -3,15 +3,18 @@ "compilerOptions": { "outDir": "../out-tsc/app", "types": [ - "node" - ] + "node", + "hammerjs" + ], + "allowSyntheticDefaultImports": true }, - "files": [ - "main.ts", - "polyfills.ts", - "../projects/igniteui-angular-i18n/src/i18n/expand-type.ts" - ], - "include": [ - "**/*.d.ts" - ] + "files": [ + "main.ts", + "main.server.ts", + "server.ts", + "../projects/igniteui-angular-i18n/src/i18n/expand-type.ts" + ], + "include": [ + "**/*.d.ts" + ] } From 6dcac651ebd5cfd6c2034e7af81179d35a8b38fa Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Tue, 21 Nov 2023 15:53:02 +0200 Subject: [PATCH 19/25] spec(combo, date-range-picker): revert spec files --- .../src/lib/combo/combo.component.spec.ts | 1415 ++++++++--------- .../date-range-picker.component.spec.ts | 252 ++- 2 files changed, 804 insertions(+), 863 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index a1de875770c..757adbfac66 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -90,797 +90,750 @@ describe('igxCombo', () => { mockSelection.get.and.returnValue(new Set([])); const mockIconService = new IgxIconService(null, null, null, null); it('should correctly implement interface methods - ControlValueAccessor ', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - expect(mockInjector.get).toHaveBeenCalledWith(NgControl, null); - combo.registerOnChange(mockNgControl.registerOnChangeCb); - combo.registerOnTouched(mockNgControl.registerOnTouchedCb); - - // writeValue - expect(combo.displayValue).toEqual(''); - mockSelection.get.and.returnValue(new Set(['test'])); - spyOnProperty(combo, 'isRemote').and.returnValue(false); - combo.writeValue(['test']); - expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled(); - expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['test'], true); - expect(combo.displayValue).toEqual('test'); - expect(combo.value).toEqual(['test']); - - // setDisabledState - combo.setDisabledState(true); - expect(combo.disabled).toBe(true); - combo.setDisabledState(false); - expect(combo.disabled).toBe(false); - - // OnChange callback - mockSelection.add_items.and.returnValue(new Set(['simpleValue'])); - combo.select(['simpleValue']); - expect(mockSelection.add_items).toHaveBeenCalledWith(combo.id, ['simpleValue'], undefined); - expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['simpleValue'], true); - expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith(['simpleValue']); - - // OnTouched callback - spyOnProperty(combo, 'collapsed').and.returnValue(true); - spyOnProperty(combo, 'valid', 'set'); - - combo.onBlur(); - expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + expect(mockInjector.get).toHaveBeenCalledWith(NgControl, null); + combo.registerOnChange(mockNgControl.registerOnChangeCb); + combo.registerOnTouched(mockNgControl.registerOnTouchedCb); + + // writeValue + expect(combo.displayValue).toEqual(''); + mockSelection.get.and.returnValue(new Set(['test'])); + spyOnProperty(combo, 'isRemote').and.returnValue(false); + combo.writeValue(['test']); + expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled(); + expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['test'], true); + expect(combo.displayValue).toEqual('test'); + expect(combo.value).toEqual(['test']); + + // setDisabledState + combo.setDisabledState(true); + expect(combo.disabled).toBe(true); + combo.setDisabledState(false); + expect(combo.disabled).toBe(false); + + // OnChange callback + mockSelection.add_items.and.returnValue(new Set(['simpleValue'])); + combo.select(['simpleValue']); + expect(mockSelection.add_items).toHaveBeenCalledWith(combo.id, ['simpleValue'], undefined); + expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['simpleValue'], true); + expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith(['simpleValue']); + + // OnTouched callback + spyOnProperty(combo, 'collapsed').and.returnValue(true); + spyOnProperty(combo, 'valid', 'set'); + + combo.onBlur(); + expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1); }); it('should properly call dropdown methods on toggle', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.dropdown = dropdown; - dropdown.collapsed = true; - - combo.open(); - dropdown.collapsed = false; - expect(combo.dropdown.open).toHaveBeenCalledTimes(1); - expect(combo.collapsed).toBe(false); - - combo.close(); - dropdown.collapsed = true; - expect(combo.dropdown.close).toHaveBeenCalledTimes(1); - expect(combo.collapsed).toBe(true); - - combo.toggle(); - dropdown.collapsed = false; - expect(combo.dropdown.toggle).toHaveBeenCalledTimes(1); - expect(combo.collapsed).toBe(false); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.dropdown = dropdown; + dropdown.collapsed = true; + + combo.open(); + dropdown.collapsed = false; + expect(combo.dropdown.open).toHaveBeenCalledTimes(1); + expect(combo.collapsed).toBe(false); + + combo.close(); + dropdown.collapsed = true; + expect(combo.dropdown.close).toHaveBeenCalledTimes(1); + expect(combo.collapsed).toBe(true); + + combo.toggle(); + dropdown.collapsed = false; + expect(combo.dropdown.toggle).toHaveBeenCalledTimes(1); + expect(combo.collapsed).toBe(false); }); it(`should not focus search input when property autoFocusSearch=false`, () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdownContainer = { nativeElement: { focus: () => { } } }; - combo['dropdownContainer'] = dropdownContainer; - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - spyOn(combo, 'focusSearchInput'); - - combo.autoFocusSearch = false; - combo.handleOpened(); - expect(combo.focusSearchInput).toHaveBeenCalledTimes(0); - - combo.autoFocusSearch = true; - combo.handleOpened(); - expect(combo.focusSearchInput).toHaveBeenCalledTimes(1); - - combo.autoFocusSearch = false; - combo.handleOpened(); - expect(combo.focusSearchInput).toHaveBeenCalledTimes(1); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdownContainer = { nativeElement: { focus: () => { } } }; + combo['dropdownContainer'] = dropdownContainer; + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + spyOn(combo, 'focusSearchInput'); + + combo.autoFocusSearch = false; + combo.handleOpened(); + expect(combo.focusSearchInput).toHaveBeenCalledTimes(0); + + combo.autoFocusSearch = true; + combo.handleOpened(); + expect(combo.focusSearchInput).toHaveBeenCalledTimes(1); + + combo.autoFocusSearch = false; + combo.handleOpened(); + expect(combo.focusSearchInput).toHaveBeenCalledTimes(1); }); it('should call dropdown toggle with correct overlaySettings', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['toggle']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.dropdown = dropdown; - const defaultSettings = (combo as any)._overlaySettings; - combo.toggle(); - expect(combo.dropdown.toggle).toHaveBeenCalledWith(defaultSettings || {}); - const newSettings = { - positionStrategy: new ConnectedPositioningStrategy(), - scrollStrategy: new AbsoluteScrollStrategy() - }; - combo.overlaySettings = newSettings; - const expectedSettings = Object.assign({}, defaultSettings, newSettings); - combo.toggle(); - expect(combo.dropdown.toggle).toHaveBeenCalledWith(expectedSettings); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['toggle']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.dropdown = dropdown; + const defaultSettings = (combo as any)._overlaySettings; + combo.toggle(); + expect(combo.dropdown.toggle).toHaveBeenCalledWith(defaultSettings || {}); + const newSettings = { + positionStrategy: new ConnectedPositioningStrategy(), + scrollStrategy: new AbsoluteScrollStrategy() + }; + combo.overlaySettings = newSettings; + const expectedSettings = Object.assign({}, defaultSettings, newSettings); + combo.toggle(); + expect(combo.dropdown.toggle).toHaveBeenCalledWith(expectedSettings); }); it('should properly get/set displayKey', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.valueKey = 'field'; - expect(combo.displayKey).toEqual(combo.valueKey); - combo.displayKey = 'region'; - expect(combo.displayKey).toEqual('region'); - expect(combo.displayKey === combo.valueKey).toBeFalsy(); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.valueKey = 'field'; + expect(combo.displayKey).toEqual(combo.valueKey); + combo.displayKey = 'region'; + expect(combo.displayKey).toEqual('region'); + expect(combo.displayKey === combo.valueKey).toBeFalsy(); }); it('should properly call "writeValue" method', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - mockSelection.select_items.calls.reset(); - spyOnProperty(combo, 'isRemote').and.returnValue(false); - combo.writeValue(['EXAMPLE']); - expect(mockSelection.select_items).toHaveBeenCalledTimes(1); - - // Calling "select_items" through the writeValue accessor should clear the previous values; - // Select items is called with the invalid value and it is written in selection, though no item is selected - // Controlling the selection is up to the user - expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['EXAMPLE'], true); - combo.writeValue(combo.data[0]); - // When value key is specified, the item's value key is stored in the selection - expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, [], true); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + mockSelection.select_items.calls.reset(); + spyOnProperty(combo, 'isRemote').and.returnValue(false); + combo.writeValue(['EXAMPLE']); + expect(mockSelection.select_items).toHaveBeenCalledTimes(1); + + // Calling "select_items" through the writeValue accessor should clear the previous values; + // Select items is called with the invalid value and it is written in selection, though no item is selected + // Controlling the selection is up to the user + expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['EXAMPLE'], true); + combo.writeValue(combo.data[0]); + // When value key is specified, the item's value key is stored in the selection + expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, [], true); }); it('should select items through setSelctedItem method', () => { const selectionService = new IgxSelectionAPIService(); - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = complexData; - combo.valueKey = 'country'; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - - const selectedItems = [combo.data[0]]; - const selectedValues = [combo.data[0].country]; - combo.setSelectedItem('UK', true); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedValues); - combo.setSelectedItem('Germany', true); - selectedItems.push(combo.data[2]); - selectedValues.push(combo.data[2].country); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedValues); - selectedItems.pop(); - selectedValues.pop(); - combo.setSelectedItem('Germany', false); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedValues); - selectedItems.pop(); - selectedValues.pop(); - combo.setSelectedItem('UK', false); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedValues); - - combo.valueKey = null; - selectedItems.push(combo.data[5]); - combo.setSelectedItem(combo.data[5], true); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - selectedItems.push(combo.data[1]); - combo.setSelectedItem(combo.data[1], true); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - selectedItems.pop(); - combo.setSelectedItem(combo.data[1], false); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - }); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = complexData; + combo.valueKey = 'country'; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + + const selectedItems = [combo.data[0]]; + const selectedValues = [combo.data[0].country]; + combo.setSelectedItem('UK', true); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedValues); + combo.setSelectedItem('Germany', true); + selectedItems.push(combo.data[2]); + selectedValues.push(combo.data[2].country); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedValues); + selectedItems.pop(); + selectedValues.pop(); + combo.setSelectedItem('Germany', false); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedValues); + selectedItems.pop(); + selectedValues.pop(); + combo.setSelectedItem('UK', false); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedValues); + + combo.valueKey = null; + selectedItems.push(combo.data[5]); + combo.setSelectedItem(combo.data[5], true); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + selectedItems.push(combo.data[1]); + combo.setSelectedItem(combo.data[1], true); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + selectedItems.pop(); + combo.setSelectedItem(combo.data[1], false); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); }); it('should set selectedItems correctly on selectItems method call', () => { const selectionService = new IgxSelectionAPIService(); - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - - combo.select([], false); - expect(combo.selection).toEqual([]); - expect(combo.value).toEqual([]); - combo.select([], true); - expect(combo.selection).toEqual([]); - expect(combo.value).toEqual([]); - const selectedItems = combo.data.slice(0, 3); - combo.select(combo.data.slice(0, 3), true); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - combo.select([], false); - expect(combo.selection).toEqual(selectedItems); - expect(combo.value).toEqual(selectedItems); - selectedItems.push(combo.data[3]); - combo.select([combo.data[3]], false); - expect(combo.selection).toEqual(combo.data.slice(0, 4)); - expect(combo.value).toEqual(combo.data.slice(0, 4)); - combo.select([], true); - expect(combo.selection).toEqual([]); - expect(combo.value).toEqual([]); - }); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + + combo.select([], false); + expect(combo.selection).toEqual([]); + expect(combo.value).toEqual([]); + combo.select([], true); + expect(combo.selection).toEqual([]); + expect(combo.value).toEqual([]); + const selectedItems = combo.data.slice(0, 3); + combo.select(combo.data.slice(0, 3), true); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + combo.select([], false); + expect(combo.selection).toEqual(selectedItems); + expect(combo.value).toEqual(selectedItems); + selectedItems.push(combo.data[3]); + combo.select([combo.data[3]], false); + expect(combo.selection).toEqual(combo.data.slice(0, 4)); + expect(combo.value).toEqual(combo.data.slice(0, 4)); + combo.select([], true); + expect(combo.selection).toEqual([]); + expect(combo.value).toEqual([]); }); it('should emit owner on `opening` and `closing`', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - spyOn(combo.opening, 'emit').and.callThrough(); - spyOn(combo.closing, 'emit').and.callThrough(); - const mockObj = {}; - const mockEvent = new Event('mock'); - const inputEvent: IBaseCancelableBrowserEventArgs = { - cancel: false, - owner: mockObj, - event: mockEvent - }; - combo.comboInput = { - nativeElement: { - focus: () => { } - } - } as any; - combo.handleOpening(inputEvent); - const expectedCall: IBaseCancelableBrowserEventArgs = { owner: combo, event: inputEvent.event, cancel: inputEvent.cancel }; - expect(combo.opening.emit).toHaveBeenCalledWith(expectedCall); - combo.handleClosing(inputEvent); - expect(combo.closing.emit).toHaveBeenCalledWith(expectedCall); - let sub = combo.opening.subscribe((e: IBaseCancelableBrowserEventArgs) => { - e.cancel = true; - }); - combo.handleOpening(inputEvent); - expect(inputEvent.cancel).toEqual(true); - sub.unsubscribe(); - inputEvent.cancel = false; - - sub = combo.closing.subscribe((e: IBaseCancelableBrowserEventArgs) => { - e.cancel = true; - }); - combo.handleClosing(inputEvent); - expect(inputEvent.cancel).toEqual(true); - sub.unsubscribe(); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + spyOn(combo.opening, 'emit').and.callThrough(); + spyOn(combo.closing, 'emit').and.callThrough(); + const mockObj = {}; + const mockEvent = new Event('mock'); + const inputEvent: IBaseCancelableBrowserEventArgs = { + cancel: false, + owner: mockObj, + event: mockEvent + }; + combo.comboInput = { + nativeElement: { + focus: () => { } + } + } as any; + combo.handleOpening(inputEvent); + const expectedCall: IBaseCancelableBrowserEventArgs = { owner: combo, event: inputEvent.event, cancel: inputEvent.cancel }; + expect(combo.opening.emit).toHaveBeenCalledWith(expectedCall); + combo.handleClosing(inputEvent); + expect(combo.closing.emit).toHaveBeenCalledWith(expectedCall); + let sub = combo.opening.subscribe((e: IBaseCancelableBrowserEventArgs) => { + e.cancel = true; + }); + combo.handleOpening(inputEvent); + expect(inputEvent.cancel).toEqual(true); + sub.unsubscribe(); + inputEvent.cancel = false; + + sub = combo.closing.subscribe((e: IBaseCancelableBrowserEventArgs) => { + e.cancel = true; + }); + combo.handleClosing(inputEvent); + expect(inputEvent.cancel).toEqual(true); + sub.unsubscribe(); }); it('should fire selectionChanging event on item selection', () => { const selectionService = new IgxSelectionAPIService(); - - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - spyOn(combo.selectionChanging, 'emit'); - - let oldValue = []; - let newValue = [combo.data[1], combo.data[5], combo.data[6]]; - - let oldSelection = []; - let newSelection = [combo.data[1], combo.data[5], combo.data[6]]; - - combo.select(newSelection); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(1); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue, - newValue, - oldSelection, - newSelection, - added: newSelection, - removed: [], - event: undefined, - owner: combo, - displayText: `${newSelection.join(', ')}`, - cancel: false - }); - - let newItem = combo.data[3]; - combo.select([newItem]); - oldValue = [...newValue]; - newValue.push(newItem); - oldSelection = [...newSelection]; - newSelection.push(newItem); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(2); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue, - newValue, - oldSelection, - newSelection, - removed: [], - added: [combo.data[3]], - event: undefined, - owner: combo, - displayText: `${newSelection.join(', ')}`, - cancel: false - }); - - oldValue = [...newValue]; - newValue = [combo.data[0]]; - oldSelection = [...newSelection]; - newSelection = [combo.data[0]]; - combo.select(newSelection, true); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(3); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue, - newValue, - oldSelection, - newSelection, - removed: oldSelection, - added: newSelection, - event: undefined, - owner: combo, - displayText: `${newSelection.join(', ')}`, - cancel: false - }); - - oldValue = [...newValue]; - newValue = []; - oldSelection = [...newSelection]; - newSelection = []; - newItem = combo.data[0]; - combo.deselect([newItem]); - expect(combo.selection.length).toEqual(0); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(4); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue, - newValue, - oldSelection, - newSelection, - removed: [combo.data[0]], - added: [], - event: undefined, - owner: combo, - displayText: `${newSelection.join(', ')}`, - cancel: false - }); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + spyOn(combo.selectionChanging, 'emit'); + + let oldValue = []; + let newValue = [combo.data[1], combo.data[5], combo.data[6]]; + + let oldSelection = []; + let newSelection = [combo.data[1], combo.data[5], combo.data[6]]; + + combo.select(newSelection); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(1); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue, + newValue, + oldSelection, + newSelection, + added: newSelection, + removed: [], + event: undefined, + owner: combo, + displayText: `${newSelection.join(', ')}`, + cancel: false + }); + + let newItem = combo.data[3]; + combo.select([newItem]); + oldValue = [...newValue]; + newValue.push(newItem); + oldSelection = [...newSelection]; + newSelection.push(newItem); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(2); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue, + newValue, + oldSelection, + newSelection, + removed: [], + added: [combo.data[3]], + event: undefined, + owner: combo, + displayText: `${newSelection.join(', ')}`, + cancel: false + }); + + oldValue = [...newValue]; + newValue = [combo.data[0]]; + oldSelection = [...newSelection]; + newSelection = [combo.data[0]]; + combo.select(newSelection, true); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(3); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue, + newValue, + oldSelection, + newSelection, + removed: oldSelection, + added: newSelection, + event: undefined, + owner: combo, + displayText: `${newSelection.join(', ')}`, + cancel: false + }); + + oldValue = [...newValue]; + newValue = []; + oldSelection = [...newSelection]; + newSelection = []; + newItem = combo.data[0]; + combo.deselect([newItem]); + expect(combo.selection.length).toEqual(0); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(4); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue, + newValue, + oldSelection, + newSelection, + removed: [combo.data[0]], + added: [], + event: undefined, + owner: combo, + displayText: `${newSelection.join(', ')}`, + cancel: false }); }); it('should properly emit added and removed values in change event on single value selection', () => { const selectionService = new IgxSelectionAPIService(); - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = complexData; - combo.valueKey = 'country'; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - const selectionSpy = spyOn(combo.selectionChanging, 'emit'); - const expectedResults: IComboSelectionChangingEventArgs = { - newValue: [combo.data[0][combo.valueKey]], - oldValue: [], - newSelection: [combo.data[0]], - oldSelection: [], - added: [combo.data[0]], - removed: [], - event: undefined, - owner: combo, - displayText: `${combo.data[0][combo.displayKey]}`, - cancel: false - }; - combo.select([combo.data[0][combo.valueKey]]); - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); - Object.assign(expectedResults, { - newValue: [], - oldValue: [combo.data[0][combo.valueKey]], - newSelection: [], - oldSelection: [combo.data[0]], - added: [], - displayText: '', - removed: [combo.data[0]] - }); - combo.deselect([combo.data[0][combo.valueKey]]); - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); - }); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = complexData; + combo.valueKey = 'country'; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + const selectionSpy = spyOn(combo.selectionChanging, 'emit'); + const expectedResults: IComboSelectionChangingEventArgs = { + newValue: [combo.data[0][combo.valueKey]], + oldValue: [], + newSelection: [combo.data[0]], + oldSelection: [], + added: [combo.data[0]], + removed: [], + event: undefined, + owner: combo, + displayText: `${combo.data[0][combo.displayKey]}`, + cancel: false + }; + combo.select([combo.data[0][combo.valueKey]]); + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + Object.assign(expectedResults, { + newValue: [], + oldValue: [combo.data[0][combo.valueKey]], + newSelection: [], + oldSelection: [combo.data[0]], + added: [], + displayText: '', + removed: [combo.data[0]] + }); + combo.deselect([combo.data[0][combo.valueKey]]); + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); }); it('should properly emit added and removed values in change event on multiple values selection', () => { const selectionService = new IgxSelectionAPIService(); - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = complexData; - combo.valueKey = 'country'; - combo.displayKey = 'city'; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - const selectionSpy = spyOn(combo.selectionChanging, 'emit'); - - let oldSelection = []; - let newSelection = [combo.data[0], combo.data[1], combo.data[2]]; - combo.select(newSelection.map(e => e[combo.valueKey])); - const expectedResults: IComboSelectionChangingEventArgs = { - newValue: newSelection.map(e => e[combo.valueKey]), - oldValue: [], - newSelection: newSelection, - oldSelection, - added: newSelection, - removed: [], - event: undefined, - owner: combo, - displayText: `${newSelection.map(entry => entry[combo.displayKey]).join(', ')}`, - cancel: false - }; - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); - - oldSelection = [...newSelection]; - newSelection = [combo.data[1], combo.data[2]]; - combo.deselect([combo.data[0][combo.valueKey]]); - Object.assign(expectedResults, { - newValue: newSelection.map(e => e[combo.valueKey]), - oldValue: oldSelection.map(e => e[combo.valueKey]), - newSelection, - oldSelection, - added: [], - displayText: newSelection.map(e => e[combo.displayKey]).join(', '), - removed: [combo.data[0]] - }); - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); - - oldSelection = [...newSelection]; - newSelection = [combo.data[4], combo.data[5], combo.data[6]]; - combo.select(newSelection.map(e => e[combo.valueKey]), true); - Object.assign(expectedResults, { - newValue: newSelection.map(e => e[combo.valueKey]), - oldValue: oldSelection.map(e => e[combo.valueKey]), - newSelection, - oldSelection, - added: newSelection, - displayText: newSelection.map(e => e[combo.displayKey]).join(', '), - removed: oldSelection - }); - expect(selectionSpy).toHaveBeenCalledWith(expectedResults); - }); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = complexData; + combo.valueKey = 'country'; + combo.displayKey = 'city'; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + const selectionSpy = spyOn(combo.selectionChanging, 'emit'); + + let oldSelection = []; + let newSelection = [combo.data[0], combo.data[1], combo.data[2]]; + combo.select(newSelection.map(e => e[combo.valueKey])); + const expectedResults: IComboSelectionChangingEventArgs = { + newValue: newSelection.map(e => e[combo.valueKey]), + oldValue: [], + newSelection: newSelection, + oldSelection, + added: newSelection, + removed: [], + event: undefined, + owner: combo, + displayText: `${newSelection.map(entry => entry[combo.displayKey]).join(', ')}`, + cancel: false + }; + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + + oldSelection = [...newSelection]; + newSelection = [combo.data[1], combo.data[2]]; + combo.deselect([combo.data[0][combo.valueKey]]); + Object.assign(expectedResults, { + newValue: newSelection.map(e => e[combo.valueKey]), + oldValue: oldSelection.map(e => e[combo.valueKey]), + newSelection, + oldSelection, + added: [], + displayText: newSelection.map(e => e[combo.displayKey]).join(', '), + removed: [combo.data[0]] + }); + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); + + oldSelection = [...newSelection]; + newSelection = [combo.data[4], combo.data[5], combo.data[6]]; + combo.select(newSelection.map(e => e[combo.valueKey]), true); + Object.assign(expectedResults, { + newValue: newSelection.map(e => e[combo.valueKey]), + oldValue: oldSelection.map(e => e[combo.valueKey]), + newSelection, + oldSelection, + added: newSelection, + displayText: newSelection.map(e => e[combo.displayKey]).join(', '), + removed: oldSelection + }); + expect(selectionSpy).toHaveBeenCalledWith(expectedResults); }); it('should handle select/deselect ALL items', () => { const selectionService = new IgxSelectionAPIService(); - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - spyOn(combo, 'selectAllItems'); - spyOn(combo, 'deselectAllItems'); - - combo.handleSelectAll({ checked: true }); - expect(combo.selectAllItems).toHaveBeenCalledTimes(1); - expect(combo.deselectAllItems).toHaveBeenCalledTimes(0); - - combo.handleSelectAll({ checked: false }); - expect(combo.selectAllItems).toHaveBeenCalledTimes(1); - expect(combo.deselectAllItems).toHaveBeenCalledTimes(1); - }); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + spyOn(combo, 'selectAllItems'); + spyOn(combo, 'deselectAllItems'); + + combo.handleSelectAll({ checked: true }); + expect(combo.selectAllItems).toHaveBeenCalledTimes(1); + expect(combo.deselectAllItems).toHaveBeenCalledTimes(0); + + combo.handleSelectAll({ checked: false }); + expect(combo.selectAllItems).toHaveBeenCalledTimes(1); + expect(combo.deselectAllItems).toHaveBeenCalledTimes(1); }); it('should emit onSelectonChange event on select/deselect ALL items method call', () => { const selectionService = new IgxSelectionAPIService(); - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - spyOn(combo.selectionChanging, 'emit'); - - combo.selectAllItems(true); - expect(combo.selection).toEqual(data); - expect(combo.value).toEqual(data); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(1); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue: [], - newValue: data, - oldSelection: [], - newSelection: data, - added: data, - removed: [], - owner: combo, - event: undefined, - displayText: `${combo.data.join(', ')}`, - cancel: false - }); - - combo.deselectAllItems(true); - expect(combo.selection).toEqual([]); - expect(combo.value).toEqual([]); - expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(2); - expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ - oldValue: data, - newValue: [], - oldSelection: data, - newSelection: [], - added: [], - removed: data, - owner: combo, - event: undefined, - displayText: '', - cancel: false - }); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + spyOn(combo.selectionChanging, 'emit'); + + combo.selectAllItems(true); + expect(combo.selection).toEqual(data); + expect(combo.value).toEqual(data); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(1); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue: [], + newValue: data, + oldSelection: [], + newSelection: data, + added: data, + removed: [], + owner: combo, + event: undefined, + displayText: `${combo.data.join(', ')}`, + cancel: false + }); + + combo.deselectAllItems(true); + expect(combo.selection).toEqual([]); + expect(combo.value).toEqual([]); + expect(combo.selectionChanging.emit).toHaveBeenCalledTimes(2); + expect(combo.selectionChanging.emit).toHaveBeenCalledWith({ + oldValue: data, + newValue: [], + oldSelection: data, + newSelection: [], + added: [], + removed: data, + owner: combo, + event: undefined, + displayText: '', + cancel: false }); }); it('should properly handle selection manipulation through selectionChanging emit', () => { const selectionService = new IgxSelectionAPIService(); - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.newValue = []); - // No items are initially selected - expect(combo.selection).toEqual([]); - // Select the first 5 items - combo.select(combo.data.splice(0, 5)); - // selectionChanging fires and overrides the selection to be []; - expect(combo.selection).toEqual([]); - }); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.newValue = []); + // No items are initially selected + expect(combo.selection).toEqual([]); + // Select the first 5 items + combo.select(combo.data.splice(0, 5)); + // selectionChanging fires and overrides the selection to be []; + expect(combo.selection).toEqual([]); }); it('should not throw error when setting data to null', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - let errorMessage = ''; - try { - combo.data = null; - } catch (ex) { - errorMessage = ex.message; - } - expect(errorMessage).toBe(''); - expect(combo.data).not.toBeUndefined(); - expect(combo.data).not.toBeNull(); - expect(combo.data.length).toBe(0); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + let errorMessage = ''; + try { + combo.data = null; + } catch (ex) { + errorMessage = ex.message; + } + expect(errorMessage).toBe(''); + expect(combo.data).not.toBeUndefined(); + expect(combo.data).not.toBeNull(); + expect(combo.data.length).toBe(0); }); it('should not throw error when setting data to undefined', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - let errorMessage = ''; - try { - combo.data = undefined; - } catch (ex) { - errorMessage = ex.message; - } - expect(errorMessage).toBe(''); - expect(combo.data).not.toBeUndefined(); - expect(combo.data).not.toBeNull(); - expect(combo.data.length).toBe(0); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + let errorMessage = ''; + try { + combo.data = undefined; + } catch (ex) { + errorMessage = ex.message; + } + expect(errorMessage).toBe(''); + expect(combo.data).not.toBeUndefined(); + expect(combo.data).not.toBeNull(); + expect(combo.data.length).toBe(0); }); it('should properly handleInputChange', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - combo.comboInput = { - value: '', - } as any; - combo.filteringOptions.filterable = true; - const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); - spyOn(combo.searchInputUpdate, 'emit'); - - combo.handleInputChange(); - expect(matchSpy).toHaveBeenCalledTimes(1); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(0); - - const args = { - searchText: 'Fake', - owner: combo, - cancel: false - }; - combo.handleInputChange('Fake'); - expect(matchSpy).toHaveBeenCalledTimes(2); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(1); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledWith(args); - - args.searchText = ''; - combo.handleInputChange(''); - expect(matchSpy).toHaveBeenCalledTimes(3); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(2); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledWith(args); - - combo.filteringOptions.filterable = false; - combo.handleInputChange(); - expect(matchSpy).toHaveBeenCalledTimes(4); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(2); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + combo.comboInput = { + value: '', + } as any; + combo.filteringOptions.filterable = true; + const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); + spyOn(combo.searchInputUpdate, 'emit'); + + combo.handleInputChange(); + expect(matchSpy).toHaveBeenCalledTimes(1); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(0); + + const args = { + searchText: 'Fake', + owner: combo, + cancel: false + }; + combo.handleInputChange('Fake'); + expect(matchSpy).toHaveBeenCalledTimes(2); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(1); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledWith(args); + + args.searchText = ''; + combo.handleInputChange(''); + expect(matchSpy).toHaveBeenCalledTimes(3); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(2); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledWith(args); + + combo.filteringOptions.filterable = false; + combo.handleInputChange(); + expect(matchSpy).toHaveBeenCalledTimes(4); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(2); }); it('should be able to cancel searchInputUpdate', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.filteringOptions.filterable = true; - combo.searchInputUpdate.subscribe((e) => { - e.cancel = true; - }); - const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); - spyOn(combo.searchInputUpdate, 'emit').and.callThrough(); - - combo.handleInputChange('Item1'); - expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(1); - expect(matchSpy).toHaveBeenCalledTimes(1); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.filteringOptions.filterable = true; + combo.searchInputUpdate.subscribe((e) => { + e.cancel = true; + }); + const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); + spyOn(combo.searchInputUpdate, 'emit').and.callThrough(); + + combo.handleInputChange('Item1'); + expect(combo.searchInputUpdate.emit).toHaveBeenCalledTimes(1); + expect(matchSpy).toHaveBeenCalledTimes(1); }); it('should not open on click if combo is disabled', () => { - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']); - const spyObj = jasmine.createSpyObj('event', ['stopPropagation', 'preventDefault']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.dropdown = dropdown; - dropdown.collapsed = true; - - combo.disabled = true; - combo.onClick(spyObj); - expect(combo.dropdown.collapsed).toBeTruthy(); - }); + combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']); + const spyObj = jasmine.createSpyObj('event', ['stopPropagation', 'preventDefault']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.dropdown = dropdown; + dropdown.collapsed = true; + + combo.disabled = true; + combo.onClick(spyObj); + expect(combo.dropdown.collapsed).toBeTruthy(); }); it('should not clear value when combo is disabled', () => { const selectionService = new IgxSelectionAPIService(); - - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - const spyObj = jasmine.createSpyObj('event', ['stopPropagation']); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - combo.ngOnInit(); - combo.data = data; - combo.dropdown = dropdown; - combo.disabled = true; - spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); - - const item = combo.data.slice(0, 1); - combo.select(item, true); - combo.handleClearItems(spyObj); - expect(combo.displayValue).toEqual(item[0]); - }) + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + const spyObj = jasmine.createSpyObj('event', ['stopPropagation']); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + combo.ngOnInit(); + combo.data = data; + combo.dropdown = dropdown; + combo.disabled = true; + spyOnProperty(combo, 'totalItemCount').and.returnValue(combo.data.length); + + const item = combo.data.slice(0, 1); + combo.select(item, true); + combo.handleClearItems(spyObj); + expect(combo.displayValue).toEqual(item[0]); }); it('should allow canceling and overwriting of item addition', fakeAsync(() => { const selectionService = new IgxSelectionAPIService(); + combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, + mockIconService, null, null, mockInjector); + const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); + const mockVirtDir = jasmine.createSpyObj('virtDir', ['scrollTo']); + const mockInput = jasmine.createSpyObj('mockInput', [], { + nativeElement: jasmine.createSpyObj('mockElement', ['focus']) + }); + spyOn(combo.addition, 'emit').and.callThrough(); + spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); + const subParams: { cancel: boolean; newValue: string; modify: boolean } = { + cancel: false, + modify: false, + newValue: 'mockValue' + }; + const sub = combo.addition.subscribe((e) => { + if (subParams.cancel) { + e.cancel = true; + } + if (subParams.modify) { + e.addedItem = subParams.newValue; + } + }); - TestBed.runInInjectionContext(() => { - combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, - mockIconService, null, null, mockInjector); - const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']); - const mockVirtDir = jasmine.createSpyObj('virtDir', ['scrollTo']); - const mockInput = jasmine.createSpyObj('mockInput', [], { - nativeElement: jasmine.createSpyObj('mockElement', ['focus']) - }); - spyOn(combo.addition, 'emit').and.callThrough(); - spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null); - const subParams: { cancel: boolean; newValue: string; modify: boolean } = { - cancel: false, - modify: false, - newValue: 'mockValue' - }; - const sub = combo.addition.subscribe((e) => { - if (subParams.cancel) { - e.cancel = true; - } - if (subParams.modify) { - e.addedItem = subParams.newValue; - } - }); - - combo.ngOnInit(); - combo.data = ['Item 1', 'Item 2', 'Item 3']; - combo.dropdown = dropdown; - combo.searchInput = mockInput; - (combo as any).virtDir = mockVirtDir; - let mockAddParams: IComboItemAdditionEvent = { - cancel: false, - owner: combo, - addedItem: 'Item 99', - newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'], - oldCollection: ['Item 1', 'Item 2', 'Item 3'] - }; - + combo.ngOnInit(); + combo.data = ['Item 1', 'Item 2', 'Item 3']; + combo.dropdown = dropdown; + combo.searchInput = mockInput; + (combo as any).virtDir = mockVirtDir; + let mockAddParams: IComboItemAdditionEvent = { + cancel: false, + owner: combo, + addedItem: 'Item 99', + newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'], + oldCollection: ['Item 1', 'Item 2', 'Item 3'] + }; - // handle addition - combo.searchValue = 'Item 99'; - combo.addItemToCollection(); - tick(); - expect(combo.data.length).toEqual(4); - expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); - expect(combo.addition.emit).toHaveBeenCalledTimes(1); - expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(1); - expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(1); - expect(combo.data[combo.data.length - 1]).toBe('Item 99'); - expect(selectionService.get(combo.id).size).toBe(1); - expect([...selectionService.get(combo.id)][0]).toBe('Item 99'); - - // cancel - subParams.cancel = true; - mockAddParams = { - cancel: true, - owner: combo, - addedItem: 'Item 99', - newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99', 'Item 99'], - oldCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'] - }; + // handle addition + + combo.searchValue = 'Item 99'; + combo.addItemToCollection(); + tick(); + expect(combo.data.length).toEqual(4); + expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); + expect(combo.addition.emit).toHaveBeenCalledTimes(1); + expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(1); + expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(1); + expect(combo.data[combo.data.length - 1]).toBe('Item 99'); + expect(selectionService.get(combo.id).size).toBe(1); + expect([...selectionService.get(combo.id)][0]).toBe('Item 99'); + + // cancel + subParams.cancel = true; + mockAddParams = { + cancel: true, + owner: combo, + addedItem: 'Item 99', + newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99', 'Item 99'], + oldCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'] + }; - combo.searchValue = 'Item 99'; - combo.addItemToCollection(); - tick(); - expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); - expect(combo.addition.emit).toHaveBeenCalledTimes(2); - expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(1); - expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(1); - expect(combo.data.length).toEqual(4); - expect(combo.data[combo.data.length - 1]).toBe('Item 99'); - expect(selectionService.get(combo.id).size).toBe(1); - expect([...selectionService.get(combo.id)][0]).toBe('Item 99'); - - // overwrite - subParams.modify = true; - subParams.cancel = false; - mockAddParams = { - cancel: false, - owner: combo, - addedItem: 'mockValue', - newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99', 'Item 99'], - oldCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'] - }; + combo.searchValue = 'Item 99'; + combo.addItemToCollection(); + tick(); + expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); + expect(combo.addition.emit).toHaveBeenCalledTimes(2); + expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(1); + expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(1); + expect(combo.data.length).toEqual(4); + expect(combo.data[combo.data.length - 1]).toBe('Item 99'); + expect(selectionService.get(combo.id).size).toBe(1); + expect([...selectionService.get(combo.id)][0]).toBe('Item 99'); + + // overwrite + subParams.modify = true; + subParams.cancel = false; + mockAddParams = { + cancel: false, + owner: combo, + addedItem: 'mockValue', + newCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99', 'Item 99'], + oldCollection: ['Item 1', 'Item 2', 'Item 3', 'Item 99'] + }; - combo.searchValue = 'Item 99'; - combo.addItemToCollection(); - tick(); - expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); - expect(combo.addition.emit).toHaveBeenCalledTimes(3); - expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(2); - expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(2); - expect(combo.data.length).toEqual(5); - expect(combo.data[combo.data.length - 1]).toBe(subParams.newValue); - expect(selectionService.get(combo.id).size).toBe(2); - expect([...selectionService.get(combo.id)][1]).toBe(subParams.newValue); - sub.unsubscribe(); - }); + combo.searchValue = 'Item 99'; + combo.addItemToCollection(); + tick(); + expect(combo.addition.emit).toHaveBeenCalledWith(mockAddParams); + expect(combo.addition.emit).toHaveBeenCalledTimes(3); + expect(mockVirtDir.scrollTo).toHaveBeenCalledTimes(2); + expect(combo.searchInput.nativeElement.focus).toHaveBeenCalledTimes(2); + expect(combo.data.length).toEqual(5); + expect(combo.data[combo.data.length - 1]).toBe(subParams.newValue); + expect(selectionService.get(combo.id).size).toBe(2); + expect([...selectionService.get(combo.id)][1]).toBe(subParams.newValue); + sub.unsubscribe(); })); }); diff --git a/projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts b/projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts index 612887993e0..90682c67fca 100644 --- a/projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts @@ -153,162 +153,150 @@ describe('IgxDateRangePicker', () => { }); /* eslint-enable @typescript-eslint/no-unused-vars */ it('should set range dates correctly through selectRange method', () => { - TestBed.runInInjectionContext(() => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, null, null, null, null); - // dateRange.calendar = calendar; - let startDate = new Date(2020, 3, 7); - const endDate = new Date(2020, 6, 27); - - // select range - dateRange.select(startDate, endDate); - expect(dateRange.value.start).toEqual(startDate); - expect(dateRange.value.end).toEqual(endDate); - - // select startDate only - startDate = new Date(2023, 2, 11); - dateRange.select(startDate); - expect(dateRange.value.start).toEqual(startDate); - expect(dateRange.value.end).toEqual(startDate); - }); + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, null, null, null, null); + // dateRange.calendar = calendar; + let startDate = new Date(2020, 3, 7); + const endDate = new Date(2020, 6, 27); + + // select range + dateRange.select(startDate, endDate); + expect(dateRange.value.start).toEqual(startDate); + expect(dateRange.value.end).toEqual(endDate); + + // select startDate only + startDate = new Date(2023, 2, 11); + dateRange.select(startDate); + expect(dateRange.value.start).toEqual(startDate); + expect(dateRange.value.end).toEqual(startDate); }); it('should emit valueChange on selection', () => { - TestBed.runInInjectionContext(() => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, null, null, null, null); - // dateRange.calendar = calendar; - spyOn(dateRange.valueChange, 'emit'); - let startDate = new Date(2017, 4, 5); - const endDate = new Date(2017, 11, 22); - - // select range - dateRange.select(startDate, endDate); - expect(dateRange.value.start).toEqual(startDate); - expect(dateRange.value.end).toEqual(endDate); - expect(dateRange.valueChange.emit).toHaveBeenCalledTimes(1); - expect(dateRange.valueChange.emit).toHaveBeenCalledWith({ start: startDate, end: endDate }); - - // select startDate only - startDate = new Date(2024, 12, 15); - dateRange.select(startDate); - expect(dateRange.value.start).toEqual(startDate); - expect(dateRange.value.end).toEqual(startDate); - expect(dateRange.valueChange.emit).toHaveBeenCalledTimes(2); - expect(dateRange.valueChange.emit).toHaveBeenCalledWith({ start: startDate, end: startDate }); - }); + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, null, null, null, null); + // dateRange.calendar = calendar; + spyOn(dateRange.valueChange, 'emit'); + let startDate = new Date(2017, 4, 5); + const endDate = new Date(2017, 11, 22); + + // select range + dateRange.select(startDate, endDate); + expect(dateRange.value.start).toEqual(startDate); + expect(dateRange.value.end).toEqual(endDate); + expect(dateRange.valueChange.emit).toHaveBeenCalledTimes(1); + expect(dateRange.valueChange.emit).toHaveBeenCalledWith({ start: startDate, end: endDate }); + + // select startDate only + startDate = new Date(2024, 12, 15); + dateRange.select(startDate); + expect(dateRange.value.start).toEqual(startDate); + expect(dateRange.value.end).toEqual(startDate); + expect(dateRange.valueChange.emit).toHaveBeenCalledTimes(2); + expect(dateRange.valueChange.emit).toHaveBeenCalledWith({ start: startDate, end: startDate }); }); it('should correctly implement interface methods - ControlValueAccessor', () => { const range = { start: new Date(2020, 1, 18), end: new Date(2020, 1, 28) }; const rangeUpdate = { start: new Date(2020, 2, 22), end: new Date(2020, 2, 25) }; - TestBed.runInInjectionContext(() => { - // init - const dateRangePicker = new IgxDateRangePickerComponent(null, 'en', platform, null, null, null, null); - dateRangePicker.registerOnChange(mockNgControl.registerOnChangeCb); - dateRangePicker.registerOnTouched(mockNgControl.registerOnTouchedCb); - spyOn(dateRangePicker as any, 'handleSelection').and.callThrough(); - - // writeValue - expect(dateRangePicker.value).toBeUndefined(); - expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled(); - dateRangePicker.writeValue(range); - expect(dateRangePicker.value).toBe(range); - - // set value & handleSelection call _onChangeCallback - dateRangePicker.value = rangeUpdate; - expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith(rangeUpdate); - - (dateRangePicker as any).handleSelection([range.start]); - expect((dateRangePicker as any).handleSelection).toHaveBeenCalledWith([range.start]); - expect((dateRangePicker as any).handleSelection).toHaveBeenCalledTimes(1); - expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith({ start: range.start, end: range.start }); - - // awaiting implementation - OnTouched callback - // Docs: changes the value, turning the control dirty; or blurs the form control element, setting the control to touched. - // when handleSelection fires should be touched&dirty // when input is blurred(two inputs), should be touched. - (dateRangePicker as any).handleSelection([range.start]); - (dateRangePicker as any).updateValidityOnBlur(); - expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1); - - dateRangePicker.setDisabledState(true); - expect(dateRangePicker.disabled).toBe(true); - dateRangePicker.setDisabledState(false); - expect(dateRangePicker.disabled).toBe(false); - }); + // init + const dateRangePicker = new IgxDateRangePickerComponent(null, 'en', platform, null, null, null, null); + dateRangePicker.registerOnChange(mockNgControl.registerOnChangeCb); + dateRangePicker.registerOnTouched(mockNgControl.registerOnTouchedCb); + spyOn(dateRangePicker as any, 'handleSelection').and.callThrough(); + + // writeValue + expect(dateRangePicker.value).toBeUndefined(); + expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled(); + dateRangePicker.writeValue(range); + expect(dateRangePicker.value).toBe(range); + + // set value & handleSelection call _onChangeCallback + dateRangePicker.value = rangeUpdate; + expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith(rangeUpdate); + + (dateRangePicker as any).handleSelection([range.start]); + expect((dateRangePicker as any).handleSelection).toHaveBeenCalledWith([range.start]); + expect((dateRangePicker as any).handleSelection).toHaveBeenCalledTimes(1); + expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith({ start: range.start, end: range.start }); + + // awaiting implementation - OnTouched callback + // Docs: changes the value, turning the control dirty; or blurs the form control element, setting the control to touched. + // when handleSelection fires should be touched&dirty // when input is blurred(two inputs), should be touched. + (dateRangePicker as any).handleSelection([range.start]); + (dateRangePicker as any).updateValidityOnBlur(); + expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1); + + dateRangePicker.setDisabledState(true); + expect(dateRangePicker.disabled).toBe(true); + dateRangePicker.setDisabledState(false); + expect(dateRangePicker.disabled).toBe(false); }); it('should validate correctly minValue and maxValue', () => { - TestBed.runInInjectionContext(() => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, mockInjector, null, null, null); - dateRange.ngOnInit(); + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, mockInjector, null, null, null); + dateRange.ngOnInit(); - // dateRange.calendar = calendar; - dateRange.registerOnChange(mockNgControl.registerOnChangeCb); - dateRange.registerOnValidatorChange(mockNgControl.registerOnValidatorChangeCb); + // dateRange.calendar = calendar; + dateRange.registerOnChange(mockNgControl.registerOnChangeCb); + dateRange.registerOnValidatorChange(mockNgControl.registerOnValidatorChangeCb); - dateRange.minValue = new Date(2020, 4, 7); - expect(mockNgControl.registerOnValidatorChangeCb).toHaveBeenCalledTimes(1); - dateRange.maxValue = new Date(2020, 8, 7); - expect(mockNgControl.registerOnValidatorChangeCb).toHaveBeenCalledTimes(2); + dateRange.minValue = new Date(2020, 4, 7); + expect(mockNgControl.registerOnValidatorChangeCb).toHaveBeenCalledTimes(1); + dateRange.maxValue = new Date(2020, 8, 7); + expect(mockNgControl.registerOnValidatorChangeCb).toHaveBeenCalledTimes(2); - const range = { start: new Date(2020, 4, 18), end: new Date(2020, 6, 28) }; - dateRange.writeValue(range); - const mockFormControl = new UntypedFormControl(dateRange.value); - expect(dateRange.validate(mockFormControl)).toBeNull(); + const range = { start: new Date(2020, 4, 18), end: new Date(2020, 6, 28) }; + dateRange.writeValue(range); + const mockFormControl = new UntypedFormControl(dateRange.value); + expect(dateRange.validate(mockFormControl)).toBeNull(); - range.start.setMonth(2); - expect(dateRange.validate(mockFormControl)).toEqual({ minValue: true }); + range.start.setMonth(2); + expect(dateRange.validate(mockFormControl)).toEqual({ minValue: true }); - range.end.setMonth(10); - expect(dateRange.validate(mockFormControl)).toEqual({ minValue: true, maxValue: true }); - }); + range.end.setMonth(10); + expect(dateRange.validate(mockFormControl)).toEqual({ minValue: true, maxValue: true }); }); it('should disable calendar dates when min and/or max values as dates are provided', () => { - TestBed.runInInjectionContext(() => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, mockInjector, null, overlay); - dateRange.ngOnInit(); - - spyOnProperty((dateRange as any), 'calendar').and.returnValue(mockCalendar); - dateRange.minValue = new Date(2000, 10, 1); - dateRange.maxValue = new Date(2000, 10, 20); - - dateRange.open({ - closeOnOutsideClick: true, - modal: false, - target: dateRange.element.nativeElement, - positionStrategy: new AutoPositionStrategy({ - openAnimation: null, - closeAnimation: null - }) - }); - (dateRange as any).updateCalendar(); - expect(mockCalendar.disabledDates.length).toEqual(2); - expect(mockCalendar.disabledDates[0].type).toEqual(DateRangeType.Before); - expect(mockCalendar.disabledDates[0].dateRange[0]).toEqual(dateRange.minValue); - expect(mockCalendar.disabledDates[1].type).toEqual(DateRangeType.After); - expect(mockCalendar.disabledDates[1].dateRange[0]).toEqual(dateRange.maxValue); - expect(mockCalendar.daysView.focusActiveDate).toHaveBeenCalledTimes(1); + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en-US', platform, mockInjector, null, overlay); + dateRange.ngOnInit(); + + spyOnProperty((dateRange as any), 'calendar').and.returnValue(mockCalendar); + dateRange.minValue = new Date(2000, 10, 1); + dateRange.maxValue = new Date(2000, 10, 20); + + dateRange.open({ + closeOnOutsideClick: true, + modal: false, + target: dateRange.element.nativeElement, + positionStrategy: new AutoPositionStrategy({ + openAnimation: null, + closeAnimation: null + }) }); + (dateRange as any).updateCalendar(); + expect(mockCalendar.disabledDates.length).toEqual(2); + expect(mockCalendar.disabledDates[0].type).toEqual(DateRangeType.Before); + expect(mockCalendar.disabledDates[0].dateRange[0]).toEqual(dateRange.minValue); + expect(mockCalendar.disabledDates[1].type).toEqual(DateRangeType.After); + expect(mockCalendar.disabledDates[1].dateRange[0]).toEqual(dateRange.maxValue); + expect(mockCalendar.daysView.focusActiveDate).toHaveBeenCalledTimes(1); }); it('should disable calendar dates when min and/or max values as strings are provided', fakeAsync(() => { - TestBed.runInInjectionContext(() => { - const dateRange = new IgxDateRangePickerComponent(elementRef, 'en', platform, mockInjector, null, null, null); - dateRange.ngOnInit(); - - spyOnProperty((dateRange as any), 'calendar').and.returnValue(mockCalendar); - dateRange.minValue = '2000/10/1'; - dateRange.maxValue = '2000/10/30'; - - spyOn((dateRange as any).calendar, 'deselectDate').and.returnValue(null); - (dateRange as any).updateCalendar(); - expect((dateRange as any).calendar.disabledDates.length).toEqual(2); - expect((dateRange as any).calendar.disabledDates[0].type).toEqual(DateRangeType.Before); - expect((dateRange as any).calendar.disabledDates[0].dateRange[0]).toEqual(new Date(dateRange.minValue)); - expect((dateRange as any).calendar.disabledDates[1].type).toEqual(DateRangeType.After); - expect((dateRange as any).calendar.disabledDates[1].dateRange[0]).toEqual(new Date(dateRange.maxValue)); - }); + const dateRange = new IgxDateRangePickerComponent(elementRef, 'en', platform, mockInjector, null, null, null); + dateRange.ngOnInit(); + + spyOnProperty((dateRange as any), 'calendar').and.returnValue(mockCalendar); + dateRange.minValue = '2000/10/1'; + dateRange.maxValue = '2000/10/30'; + + spyOn((dateRange as any).calendar, 'deselectDate').and.returnValue(null); + (dateRange as any).updateCalendar(); + expect((dateRange as any).calendar.disabledDates.length).toEqual(2); + expect((dateRange as any).calendar.disabledDates[0].type).toEqual(DateRangeType.Before); + expect((dateRange as any).calendar.disabledDates[0].dateRange[0]).toEqual(new Date(dateRange.minValue)); + expect((dateRange as any).calendar.disabledDates[1].type).toEqual(DateRangeType.After); + expect((dateRange as any).calendar.disabledDates[1].dateRange[0]).toEqual(new Date(dateRange.maxValue)); })); }); From 04bae2d86622253400716b8431dc437b4bca55b1 Mon Sep 17 00:00:00 2001 From: Silvia Ivanova <59446295+SisIvanova@users.noreply.github.com> Date: Wed, 22 Nov 2023 17:41:01 +0200 Subject: [PATCH 20/25] refactor(*): use default size from component schemas (#13593) --- package-lock.json | 8 ++++---- package.json | 4 ++-- projects/igniteui-angular/package.json | 2 +- .../lib/core/styles/components/avatar/_avatar-theme.scss | 2 +- .../lib/core/styles/components/button/_button-theme.scss | 6 +++++- .../src/lib/core/styles/components/chip/_chip-theme.scss | 2 +- .../styles/components/drop-down/_drop-down-theme.scss | 2 +- .../src/lib/core/styles/components/icon/_icon-theme.scss | 2 +- .../core/styles/components/input/_input-group-theme.scss | 2 +- .../src/lib/core/styles/components/list/_list-theme.scss | 2 +- .../src/lib/core/styles/components/tree/_tree-theme.scss | 2 +- 11 files changed, 19 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 99f77c7ef60..465e182c3a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "express": "^4.18.2", "fflate": "^0.7.3", "hammerjs": "^2.0.8", - "igniteui-theming": "^3.3.0", + "igniteui-theming": "^3.3.3", "igniteui-trial-watermark": "^3.0.2", "lodash-es": "^4.17.21", "rxjs": "^6.6.7", @@ -12737,9 +12737,9 @@ } }, "node_modules/igniteui-theming": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/igniteui-theming/-/igniteui-theming-3.3.1.tgz", - "integrity": "sha512-kFQQ2nE9/SorRx1RvGE9kWq6q8tNpzF1GoRd2A+ZRZW67X6H38dXy5MT1ctOqsUlsHFiw3taxlBv9EYjF+VwHw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/igniteui-theming/-/igniteui-theming-3.3.3.tgz", + "integrity": "sha512-f15sUvOvgzDuQjEdVy2onX4DVjYwa3g3MdtSspudf8WurlvLb54TK+bC/sEOfhfrTnaRMC/laGmRWfjD13ebkw==", "peerDependencies": { "sass": "^1.58.1" } diff --git a/package.json b/package.json index 4f3630f2ad5..e2123878ff3 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "express": "^4.18.2", "fflate": "^0.7.3", "hammerjs": "^2.0.8", - "igniteui-theming": "^3.3.0", + "igniteui-theming": "^3.3.3", "igniteui-trial-watermark": "^3.0.2", "lodash-es": "^4.17.21", "rxjs": "^6.6.7", @@ -138,4 +138,4 @@ "typedoc-plugin-localization": "^3.0.3", "typescript": "5.2.2" } -} \ No newline at end of file +} diff --git a/projects/igniteui-angular/package.json b/projects/igniteui-angular/package.json index 782f807626c..d0acb747f5e 100644 --- a/projects/igniteui-angular/package.json +++ b/projects/igniteui-angular/package.json @@ -76,7 +76,7 @@ "igniteui-trial-watermark": "^3.0.2", "lodash-es": "^4.17.21", "uuid": "^9.0.0", - "igniteui-theming": "^3.3.0", + "igniteui-theming": "^3.3.3", "@igniteui/material-icons-extended": "^3.0.0" }, "peerDependencies": { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss index e21c4f783e0..9e24c849893 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss @@ -82,7 +82,7 @@ %igx-avatar-display { @include sizable(); - --component-size: var(--ig-size, var(--ig-size-small)); + --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); position: relative; display: inline-flex; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss index 09975e09396..a7d396c1bee 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss @@ -456,7 +456,6 @@ %igx-button-display { @include sizable(); - --component-size: var(--ig-size, var(--ig-size-large)); position: relative; display: inline-flex; @@ -526,6 +525,7 @@ } %igx-button--flat { + --component-size: var(--ig-size, #{var-get($flat-theme, 'default-size')}); background: var-get($flat-theme, 'background'); color: var-get($flat-theme, 'foreground'); border-radius: var-get($flat-theme, 'border-radius'); @@ -566,6 +566,7 @@ } %igx-button--outlined { + --component-size: var(--ig-size, #{var-get($outlined-theme, 'default-size')}); background: var-get($outlined-theme, 'background'); color: var-get($outlined-theme, 'foreground'); border-color: var-get($outlined-theme, 'border-color'); @@ -668,6 +669,7 @@ } %igx-button--raised { + --component-size: var(--ig-size, #{var-get($raised-theme, 'default-size')}); color: var-get($raised-theme, 'foreground'); background: var-get($raised-theme, 'background'); box-shadow: $raised-shadow; @@ -774,6 +776,7 @@ } %igx-button--fab { + --component-size: var(--ig-size, #{var-get($fab-theme, 'default-size')}); padding-block: pad-block( map.get($button-floating-padding-block, 'compact'), map.get($button-floating-padding-block, 'cosy'), @@ -880,6 +883,7 @@ } %igx-button--icon { + --component-size: var(--ig-size, #{var-get($icon-theme, 'default-size')}); width: var-get($icon-theme, 'size'); height: var-get($icon-theme, 'size'); min-width: unset; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss index 9965aad8b9a..7a317bc16f8 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss @@ -299,7 +299,7 @@ %igx-chip { @include sizable(); - --component-size: var(--ig-size, var(--ig-size-large)); + --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); --chip-size: var(--component-size); position: relative; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss index ece9ffca52a..cd80f8ecb6f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss @@ -194,7 +194,7 @@ %igx-drop-down__list { @include sizable(); - --component-size: var(--ig-size, var(--ig-size-large)); + --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); --dropdown-size: var(--component-size); overflow: hidden; border-radius: var-get($theme, 'border-radius'); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/icon/_icon-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/icon/_icon-theme.scss index dde18e0b732..30e1134f2d6 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/icon/_icon-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/icon/_icon-theme.scss @@ -55,7 +55,7 @@ // this approach effectively enables us to eliminate any potential style conflicts without the need of !important %igx-icon-display { @include sizable(); - --component-size: var(--ig-size, var(--ig-size-large)); + --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); display: inline-flex; font-size: $size; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss index ac731b11050..8faf9bfdd08 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss @@ -399,7 +399,7 @@ %form-group-display { @include sizable(); - --component-size: var(--ig-size, var(--ig-size-large)); + --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); --input-size: var(--component-size); position: relative; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/list/_list-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/list/_list-theme.scss index 8d6c56b2839..aafc2d28c6f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/list/_list-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/list/_list-theme.scss @@ -281,7 +281,7 @@ %igx-list { @include sizable(); - --component-size: var(--ig-size, var(--ig-size-large)); + --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); --list-size: var(--component-size); position: relative; display: flex; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss index 665c95dead7..8558ab3a5fb 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss @@ -141,7 +141,7 @@ %tree-node { @include sizable(); - --component-size: var(--ig-size, var(--ig-size-large)); + --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); --tree-size: var(--component-size); flex-direction: column; } From 04b620000c8f0a11a9dbfc714a347b02d3d09ed6 Mon Sep 17 00:00:00 2001 From: Martin Dragnev <37667452+mddragnev@users.noreply.github.com> Date: Wed, 22 Nov 2023 18:58:22 +0200 Subject: [PATCH 21/25] =?UTF-8?q?Do=20not=20change=20focus=20when=20ESF=20?= =?UTF-8?q?keyboard=20navigation=20active=20element=20is=20fi=E2=80=A6=20(?= =?UTF-8?q?#13686)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel-style-search.component.ts | 8 ++++---- .../lib/grids/grid/grid-filtering-ui.spec.ts | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-search.component.ts b/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-search.component.ts index a0b6193fe85..fc5d4c3a1d9 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-search.component.ts +++ b/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-search.component.ts @@ -764,8 +764,8 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { private onArrowUpKeyDown() { if (this.focusedItem && this.focusedItem.index === 0 && this.virtDir.state.startIndex === 0) { - this.searchInput.focus(); - this.onFocusOut(); + // on ArrowUp the focus stays on the same element if it is the first focused + return; } else { this.navigateItem(this.focusedItem ? this.focusedItem.index - 1 : 0); } @@ -775,8 +775,8 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { private onArrowDownKeyDown() { const lastIndex = this.virtDir.igxForOf.length - 1; if (this.focusedItem && this.focusedItem.index === lastIndex) { - this.cancelButton.nativeElement.focus(); - this.onFocusOut(); + // on ArrowDown the focus stays on the same element if it is the last focused + return; } else { this.navigateItem(this.focusedItem ? this.focusedItem.index + 1 : 0); } diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts index c4ecc741681..5cdc4d13883 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts @@ -5487,6 +5487,25 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { }); })); + it('Should not lose focus with arrowUp/arrowDown when navigating inside search list', fakeAsync(() => { + GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'Downloads'); + const searchComponent = GridFunctions.getExcelStyleSearchComponent(fix); + const list = searchComponent.querySelector('igx-list'); + list.dispatchEvent(new Event('focus')); + tick(DEBOUNCETIME); + fix.detectChanges(); + const listItems = list.querySelectorAll('igx-list-item'); + + // we expect only the first list item to be active when the list is focused + expect(listItems[0].classList.contains("igx-list__item-base--active")).toBeTrue(); + expect(listItems[1].classList.contains("igx-list__item-base--active")).toBeFalse(); + + // on arrow up the focus should stay on the first element and not on the search input + UIInteractions.triggerKeyDownEvtUponElem('arrowup', list, true); + fix.detectChanges(); + expect(listItems[0].classList.contains("igx-list__item-base--active")).toBeTrue(); + })); + it('Should add list items to current filtered items when "Add to current filter selection" is selected.', fakeAsync(() => { const totalListItems = []; From 588fecdaab7e0ee1bbc005b17a7b04267354a77e Mon Sep 17 00:00:00 2001 From: Marin Popov Date: Fri, 24 Nov 2023 10:38:50 +0200 Subject: [PATCH 22/25] fix(tree): Consume new hover-selected-color form schema, expose missing hover-colors to the user. (#13700) --- .../lib/core/styles/components/tree/_tree-theme.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss index 8558ab3a5fb..83c7d602f18 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss @@ -23,6 +23,8 @@ /// @param {Color} foreground-disabled [null] - The color used for the content of the disabled tree node. /// @param {Color} drop-area-color [null] - The background color used for the tree node drop aria. /// @param {Color} border-color [null] - The outline shadow color used for tree node in focus state. +/// @param {Color} hover-color [null] - The background color used for the tree node on hover. +/// @param {Color} hover-selected-color [null] - The background color used for the selected tree node on hover. /// @requires $light-material-schema /// /// @example scss Change the tree background @@ -43,6 +45,8 @@ $foreground-disabled: null, $drop-area-color: null, $border-color: null, + $hover-color: null, + $hover-selected-color: null, $size: null, ) { $name: 'igx-tree'; @@ -89,6 +93,8 @@ foreground-disabled: $foreground-disabled, drop-area-color: $drop-area-color, border-color: $border-color, + hover-color: $hover-color, + hover-selected-color: $hover-selected-color, _meta: map.merge(if($meta, $meta, ()), ( variant: map.get($schema, '_meta', 'theme') )), @@ -219,6 +225,12 @@ %node-wrapper--selected { background: var-get($theme, 'background-selected'); color: var-get($theme, 'foreground-selected'); + + &:hover { + &::after { + background: var-get($theme, 'hover-selected-color'); + } + } } %node-wrapper--active { From 74fb685a2e8ae1fb908eb7d88e76f8a1984d8232 Mon Sep 17 00:00:00 2001 From: gedinakova Date: Tue, 28 Nov 2023 09:44:02 +0200 Subject: [PATCH 23/25] chore(*): Updating 'fflate' to v0.8.1. --- projects/igniteui-angular/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/package.json b/projects/igniteui-angular/package.json index d0acb747f5e..0be3396bdd8 100644 --- a/projects/igniteui-angular/package.json +++ b/projects/igniteui-angular/package.json @@ -71,7 +71,7 @@ "dependencies": { "@types/hammerjs": "^2.0.40", "hammerjs": "^2.0.8", - "fflate": "^0.7.3", + "fflate": "^0.8.1", "tslib": "^2.3.0", "igniteui-trial-watermark": "^3.0.2", "lodash-es": "^4.17.21", From 3a1cb0c2445d0da44c2fcc51ff036aab8d3d8d84 Mon Sep 17 00:00:00 2001 From: gedinakova Date: Tue, 28 Nov 2023 10:34:41 +0200 Subject: [PATCH 24/25] Revert "chore(*): Updating 'fflate' to v0.8.1." This reverts commit 74fb685a2e8ae1fb908eb7d88e76f8a1984d8232. --- projects/igniteui-angular/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/package.json b/projects/igniteui-angular/package.json index 0be3396bdd8..d0acb747f5e 100644 --- a/projects/igniteui-angular/package.json +++ b/projects/igniteui-angular/package.json @@ -71,7 +71,7 @@ "dependencies": { "@types/hammerjs": "^2.0.40", "hammerjs": "^2.0.8", - "fflate": "^0.8.1", + "fflate": "^0.7.3", "tslib": "^2.3.0", "igniteui-trial-watermark": "^3.0.2", "lodash-es": "^4.17.21", From 7a815ceee2bae0331430deef453998db17484886 Mon Sep 17 00:00:00 2001 From: Konstantin Dinev Date: Tue, 28 Nov 2023 13:27:28 +0200 Subject: [PATCH 25/25] fix(checkbox): making the checked arg mandatory --- .../igniteui-angular/src/lib/checkbox/checkbox.component.ts | 2 +- projects/igniteui-angular/src/lib/radio/radio.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/checkbox/checkbox.component.ts b/projects/igniteui-angular/src/lib/checkbox/checkbox.component.ts index d9711c80600..2cd3e8156ab 100644 --- a/projects/igniteui-angular/src/lib/checkbox/checkbox.component.ts +++ b/projects/igniteui-angular/src/lib/checkbox/checkbox.component.ts @@ -28,7 +28,7 @@ export const LabelPosition = mkenum({ export type LabelPosition = typeof LabelPosition[keyof typeof LabelPosition]; export interface IChangeCheckboxEventArgs extends IBaseEventArgs { - checked?: boolean; + checked: boolean; value?: any; } diff --git a/projects/igniteui-angular/src/lib/radio/radio.component.ts b/projects/igniteui-angular/src/lib/radio/radio.component.ts index 64b7ab7844f..b39aff3c7c3 100644 --- a/projects/igniteui-angular/src/lib/radio/radio.component.ts +++ b/projects/igniteui-angular/src/lib/radio/radio.component.ts @@ -150,7 +150,7 @@ export class IgxRadioComponent extends IgxCheckboxComponent implements AfterView public select() { if (!this.checked) { this.checked = true; - this.change.emit({ value: this.value, owner: this }); + this.change.emit({ value: this.value, owner: this, checked: this.checked }); this._onChangeCallback(this.value); } }